v-lazy 和 viewer.js 组合使用时,预览图失效问题解决方案

解决方案

  1. 新增自定义属性 data-origin-url
<div class="img-wrp">
  <img
    v-lazy="img.url"
    :data-origin-url="img.url"
  />
div>
  1. viewer.js 修改 options.url 属性

其中 url 支持传入 string | function

const options = merge({
  url(image) {
    if (!image) return '';
    const url = image.getAttribute('large') || image.getAttribute('src');
    return url;
  }
}, configs.options || {});
gallery.current = new Viewer(dom, options);

综上,完美解决两者冲突的问题,亲测可用

问题分析

viewer.js 执行原理是在当前容器中,查找所有的 img 标签,并获取其 src 属性进行维护。

1. viewer.js

viewer.js 初始化时,获取 image.src 属性,如果为空,则对该dom不绑定任何事件

// viewer.js 源码
const images = [];

forEach(isImg ? [element] : element.querySelectorAll('img'), (image) => {
  if (isFunction(options.filter)) {
    if (options.filter.call(this, image)) {
      images.push(image);
    }
  } else if (this.getImageURL(image)) {
    images.push(image);
  }
});

// 获取 image src
getImageURL(image) {
  let { url } = this.options; // 默认 src

  if (isString(url)) {
    url = image.getAttribute(url);
  } else if (isFunction(url)) {
    url = url.call(this, image);
  } else {
    url = '';
  }

  return url;
}

2. v-lazy

而 v-lazy 插件会在 img 标签上先挂载一个 data-src 自定义属性,等 img 加载完成之后,再进行替换

raw HTML
<div v-lazy-container="{ selector: 'img' }">
  <img data-src="//domain.com/img1.jpg">
  <img data-src="//domain.com/img2.jpg">
  <img data-src="//domain.com/img3.jpg">  
div>

loaded(data-src替换为src)
<div v-lazy-container="{ selector: 'img' }">
  <img src="//domain.com/img1.jpg">
  <img src="//domain.com/img2.jpg">
  <img src="//domain.com/img3.jpg">  
div>

如果两个组件分开使用,功能都是正常运行的。一旦组合使用,这两者的逻辑就会有冲突(viewer.js 初始化时获取 img.src,v-lazy 只有在img loaded 时,才会挂载 src 属性)

你可能感兴趣的:(前端,javascript,viewer.js)