IntersectionObserver多个条目

时间:2018-12-20 03:46:34

标签: javascript vue.js

有人可以向我解释为什么观察者设置为观察单个元素会返回多个IntersectionObserverEntry吗?我在Vue项目中已经注意到了这一点,但这并不一致,而且似乎仅在最新版本的Chrome中出现。

我希望我可以提供一个提提这个问题的小提琴,但是我似乎无法复制它一定是与我的项目有关的东西。只是想知道是否有人可以向我指出为什么会发生这种情况。

这是我的jsfiddle(即使它不显示此行为)

<div id="app"> 
  <img :alt="x" v-for="x in 20" v-lazy="'https://picsum.photos/400/600/?random'"/>
</div>

function isObject (value) {
  return value && typeof value === 'object' && value.constructor === Object;
}

function init (el, binding) {
  let options = {
    threshold: 0.10
  }    

  let observer = new IntersectionObserver((entries) => {
    console.log(el, entries)
    if (entries[0].isIntersecting || entries[0].intersectionRatio > 0) {
      // console.log('is intersecting', el)
      // Create a new Image object
      let img = new Image();

      // Incase we want to add a css effect
      el.classList.add('js-lazy', 'js-lazy--loading');

      // Setup an onload event for the image
      img.onload = () => {
        if (el.nodeName.toLowerCase() === 'img') {
          // Use img src
          el.setAttribute('src', img.src);
        } else {
          // Use background image style
          el.style.backgroundImage = `url('${ img.src }')`;
        }

        // Add a loaded class which we can use to remove the css effect
        el.classList.remove('js-lazy--loading');
      }

      // Set the image src to trigger the image to load
      if (isObject(binding.value)) {
        img.src = window.matchMedia('(max-width: 767px)').matches ? binding.value.mobile : binding.value.desktop;
      } else {
        img.src = binding.value;
      }

      // Remove the observer as the element is now within view
      observer.unobserve(el);
      observer = null;
    }
  }, options);

  // Start the observer
  observer.observe(el);
}

Vue.directive('lazy', {
  bind: function (el, binding) {
    // If binding has a value when the directive binds to the element
    // then we can run init()
    if (binding.value.length > 0 || isObject(binding.value)) {
      // console.log('init on bind', el);
      init(el, binding);
    }
  },

  update: function (el, binding) {
    // If binding didn't have a value when the directive was initially bound to the element
    // then run init() when the old and current values do not match
    if (typeof binding.value === 'object') {
      if (binding.value.desktop === binding.oldValue.desktop) { 
        return;
      }
    } else if (binding.value === binding.oldValue) {
      return;
    }

    // console.log('init on update', el);
    init(el, binding);
  }
});

new Vue({
  el: "#app"
})

0 个答案:

没有答案