首页 > 解决方案 > 单击图片元素时切换 img src 和 source srcset

问题描述

一个纯粹的 JS 问题。

页面加载时,会加载小缩略图(webp 或 jpg)。当单击图像(图片元素)时 - 会发生两件事:图片元素将类更改为大(并且 css 调整它的大小)并且小文件的 srcset 字符串被编辑以指向更大的文件('-large.webp'是字符串的结尾)。再次单击图像后,应再次编辑 srcset 字符串以指向小文件('.webp' 应该是字符串的结尾)。然而,这最后一件事并没有发生,而是 srcset 字符串得到另一个“-large.webp”,现在指向一个不存在的文件。

一个页面有很多图像,我只需要在点击时加载大文件。延迟加载没有帮助,因为滚动不是我想要触发它们的事件。

我想我在 if else 循环中的逻辑是错误的......但它可能是别的东西?

任何帮助表示赞赏。

function toggleImages() {
    var images = document.querySelectorAll('figure picture');
    for(var i =0; i< images.length; i++){
        
        images[i].onclick = function() {

            // resize the container 
            this.classList.toggle('thumb');
            this.classList.toggle('large');

            // img and source DOM elements
            var imgtag = this.querySelector('img');
            var sourcetag = this.querySelector('source');
            
            // get urls of small image files
            var thumbsourceJpg = imgtag.getAttribute('src');
            var thumbsourceWebp = sourcetag.getAttribute('srcset');

            // strip the last 4 chars (extension and dot)
            var noJpg = thumbsourceJpg.slice(0,-4);
            var noWebp = thumbsourceWebp.slice(0,-5);
            
            // change ending of urls to point to larger image            
            var largesourceJpg = noJpg + '-large.jpg';
            var largesourceWebp = noWebp + '-large.webp';

            // if srcset points to small file
            if (sourcetag.srcset == thumbsourceWebp) {
                // make it point to a large one
                sourcetag.srcset = largesourceWebp;
                } else {
                    // otherwise point to the small file
                    sourcetag.srcset = thumbsourceWebp;
                }
            
            // do the same for jpgs (this doesnt work at all)
            if (imgtag.src == thumbsourceJpg) {
                imgtag.src = largesourceJpg;
                } else {
                    imgtag.src = thumbsourceJpg;
                }

            }
        
        }
    }
    
window.onload = function() {
toggleImages();

}
figure picture {background: gray;}

figure picture.large{
        width: 608px;
        -moz-transition: all .5s ease;
        -webkit-transition: all .5s ease;
        -o-transition: all .5s ease;
        transition: all .5s ease;  
    }
    
figure picture.thumb {
    width: 180px;
    cursor:pointer;
}
<!DOCTYPE html>
<html>
<body>
<figure>
  <picture class="thumb">
    <source type="image/webp" srcset="https://fokusgrupa.net/files/file1.webp">
    <img src="https://fokusgrupa.net/files/file1.jpg" alt="description">
  </picture>

  <picture class="thumb">
    <source type="image/webp" srcset="https://fokusgrupa.net/files/file2.webp">
    <img src="https://fokusgrupa.net/files/file2.jpg" alt="description">
  </picture>
</figure>
</body>

标签: javascripthtmlimagesrcset

解决方案


src由于您需要根据单击时的or属性值来切换文件名是否包含“-large” srcset,因此您需要在添加或删除该子字符串之前检查这些字符串。您可以使用URL 构造函数和一些基本的字符串操作来处理插入或删除子字符串。

const toggleURL = (srcset) => {
  const url = new URL(srcset);
  const path = url.pathname.split('/');
  let filename = path[path.length - 1];
  let index = filename.lastIndexOf('-large');
  if (index !== -1) {
    filename = filename.slice(0, index) + filename.slice(index + 6);
  } else {
    index = filename.lastIndexOf('.');
    filename = filename.slice(0, index) + '-large' + filename.slice(index);
  }
  
  path[path.length - 1] = filename;
  url.pathname = path.join('/');
  return url.href;
};

window.onload = () => {
  const pictures = document.querySelectorAll('figure picture');
  for (const picture of pictures) {
    picture.addEventListener('click', (event) => {
      const pic = event.currentTarget;
      const img = pic.querySelector('img');
      const source = pic.querySelector('source');
      img.src = toggleURL(img.src);
      source.srcset = toggleURL(source.srcset);
      pic.classList.toggle('thumb');
      pic.classList.toggle('large');
    });
  }
};
figure picture {
  background: gray;
  cursor: pointer;
}

figure picture.large {
  width: 608px;
  -moz-transition: all .5s ease;
  -webkit-transition: all .5s ease;
  -o-transition: all .5s ease;
  transition: all .5s ease;
}

figure picture.thumb {
  width: 180px;
}
<figure>
  <picture class="thumb">
    <source type="image/webp" srcset="https://fokusgrupa.net/files/file1.webp">
    <img src="https://fokusgrupa.net/files/file1.jpg" alt="description">
  </picture>
  <picture class="thumb">
    <source type="image/webp" srcset="https://fokusgrupa.net/files/file2.webp">
    <img src="https://fokusgrupa.net/files/file2.jpg" alt="description">
  </picture>
</figure>


推荐阅读