有人可以向我解释为什么观察者设置为观察单个元素会返回多个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"
})