-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IntersectionObserver是什么? #169
Comments
IntersectionObserver概览
|
IntersectionObserver构造器
参数
|
IntersectionObserver方法
示例下面的例子在threshold值变化在10%以上时触发myObserverCallback。 let observer = new IntersectionObserver(myObserverCallback, { "threshold": 0.1 }); |
IntersectionObserver懒加载(vue单文件组件简版)<template>
<div>
<img v-for="(image, i) in images" :key="i" src :data-img-url="image" />
</div>
</template>
<script>
export default {
data() {
return {
images: [
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574247890587&di=88d4066be3d57ac962a6bec37e265d37&imgtype=0&src=http%3A%2F%2F01.imgmini.eastday.com%2Fmobile%2F20170810%2F20170810151144_d41d8cd98f00b204e9800998ecf8427e_3.jpeg',
'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4054762707,1853885380&fm=26&gp=0.jpg',
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574247912077&di=508a949e5e291875debf6ca844292cd4&imgtype=0&src=http%3A%2F%2F03imgmini.eastday.com%2Fmobile%2F20180827%2F20180827095359_6759372e9bd28026ee6f53b500fb4291_2.jpeg',
],
};
},
mounted() {
const images = document.querySelectorAll('img');
const observerLazyLoad = new IntersectionObserver((entries) => {
entries.forEach((item) => {
if (item.isIntersecting) {
item.target.src = item.target.dataset.imgUrl;
}
});
});
images.forEach((image) => {
observerLazyLoad.observe(image);
});
},
};
</script>
<style lang="scss" scoped>
img {
display: block;
height: 500px;
margin: 30px;
}
</style> |
IntersectionObserver吸顶(vue单文件组件简版)<template>
<div>
<p class="fixed-top-helper"></p>
<p class="fixed-top-reference"></p>
<header>头部</header>
<main>
<img v-for="(image, i) in images" :key="i" :src="image" />
</main>
</div>
</template>
<script>
export default {
data() {
return {
images: [
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574247890587&di=88d4066be3d57ac962a6bec37e265d37&imgtype=0&src=http%3A%2F%2F01.imgmini.eastday.com%2Fmobile%2F20170810%2F20170810151144_d41d8cd98f00b204e9800998ecf8427e_3.jpeg',
'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4054762707,1853885380&fm=26&gp=0.jpg',
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574247912077&di=508a949e5e291875debf6ca844292cd4&imgtype=0&src=http%3A%2F%2F03imgmini.eastday.com%2Fmobile%2F20180827%2F20180827095359_6759372e9bd28026ee6f53b500fb4291_2.jpeg',
],
};
},
mounted() {
const header = document.querySelector('header');
const fixedTopReference = document.querySelector('.fixed-top-reference');
fixedTopReference.style.top = `${header.offsetTop}px`;
const observerFixedTop = new IntersectionObserver((entries) => {
entries.forEach((item) => {
if (item.boundingClientRect.top < 0) {
header.classList.add('fixed');
} else {
header.classList.remove('fixed');
}
});
});
observerFixedTop.observe(fixedTopReference);
},
};
</script>
<style lang="scss" scoped>
.fixed-top-helper {
height: 1px;
background: #ccc;
}
header {
background: #ccc;
&.fixed {
position: fixed;
top: 0;
left: 0;
width: 100%;
}
}
main {
img {
display: block;
height: 500px;
margin: 30px;
}
}
</style> 注意事项:
吸顶抖动 |
IntersectionObserver触底(vue单文件组件简版)<template>
<div>
<main>
<img v-for="(image, i) in images" :key="i" src="image" />
</main>
<footer>底部</footer>
</div>
</template>
<script>
export default {
data() {
return {
images: [
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574247890587&di=88d4066be3d57ac962a6bec37e265d37&imgtype=0&src=http%3A%2F%2F01.imgmini.eastday.com%2Fmobile%2F20170810%2F20170810151144_d41d8cd98f00b204e9800998ecf8427e_3.jpeg',
'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4054762707,1853885380&fm=26&gp=0.jpg',
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574247912077&di=508a949e5e291875debf6ca844292cd4&imgtype=0&src=http%3A%2F%2F03imgmini.eastday.com%2Fmobile%2F20180827%2F20180827095359_6759372e9bd28026ee6f53b500fb4291_2.jpeg',
],
};
},
mounted() {
const footer = document.querySelector('footer');
const observerTouchBottom = new IntersectionObserver((entries) => {
entries.forEach((item) => {
if (item.isIntersecting) {
setTimeout(() => {
console.log('滚动到了底部,可以发request请求数据了');
}, 2000);
}
});
});
observerTouchBottom.observe(footer);
},
};
</script>
<style lang="scss" scoped>
main {
img {
display: block;
height: 500px;
margin: 30px;
}
}
footer {
background: #ccc;
}
</style> |
IntersectionObserver懒加载、吸顶、触底综合(vue单文件组件实战版)上面的例子是为了脱离框架更好的揭示IntersectionObserver的用法本质,如果在实际项目中使用,还需要考虑一些其他问题。 考虑内容如下:
<template>
<div>
<p class="fixed-top-helper"></p>
<p class="fixed-top-reference"></p>
<header>头部</header>
<main>
<img v-for="(image, i) in images" :key="i" src :data-img-url="image" />
</main>
<footer>底部</footer>
</div>
</template>
<script>
const images = [
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574247890587&di=88d4066be3d57ac962a6bec37e265d37&imgtype=0&src=http%3A%2F%2F01.imgmini.eastday.com%2Fmobile%2F20170810%2F20170810151144_d41d8cd98f00b204e9800998ecf8427e_3.jpeg',
'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4054762707,1853885380&fm=26&gp=0.jpg',
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574247912077&di=508a949e5e291875debf6ca844292cd4&imgtype=0&src=http%3A%2F%2F03imgmini.eastday.com%2Fmobile%2F20180827%2F20180827095359_6759372e9bd28026ee6f53b500fb4291_2.jpeg',
];
export default {
data() {
return {
images,
lazyLoad: {
target: null,
observer: null,
},
touchFooter: {
target: null,
observer: null,
},
stickHeader: {
target: null,
reference: null,
observer: null,
},
};
},
mounted() {
this.createLazyLoadObserver();
this.createTouchFooterObserver();
this.createStickHeaderObserver();
},
beforeDestroy() {
this.unobserveAllIntersectionObservers();
},
methods: {
/*
* 创建懒加载observer并遍历监听所有img
*/
createLazyLoadObserver() {
this.lazyLoad.target = document.querySelectorAll('img');
this.lazyLoad.observer = new IntersectionObserver((entries) => {
entries.forEach((item) => {
if (item.isIntersecting) {
item.target.src = item.target.dataset.imgUrl;
}
});
});
this.lazyLoad.target.forEach((image) => {
this.lazyLoad.observer.observe(image);
});
},
/*
* 创建触底observer并监听footer
*/
createTouchFooterObserver() {
this.touchFooter.target = document.querySelector('footer');
this.touchFooter.observer = new IntersectionObserver((entries) => {
entries.forEach((item) => {
if (item.isIntersecting) {
setTimeout(() => {
console.log('滚动到了底部,可以发request请求数据了');
}, 2000);
}
});
});
this.touchFooter.observer.observe(this.touchFooter.target);
},
/*
* 创建吸顶observer并监听header
* 创建reference首次防抖,.fixed-top-helper二次防抖
*/
createStickHeaderObserver() {
this.stickHeader.target = document.querySelector('header');
this.stickHeader.reference = document.querySelector('.fixed-top-reference');
this.stickHeader.reference.style.top = `${this.stickHeader.target.offsetTop}px`;
this.stickHeader.observer = new IntersectionObserver((entries) => {
entries.forEach((item) => {
if (item.boundingClientRect.top < 0) {
this.stickHeader.target.classList.add('fixed');
} else {
this.stickHeader.target.classList.remove('fixed');
}
});
});
this.stickHeader.observer.observe(this.stickHeader.reference);
},
/*
* 取消observe所有监听目标
*/
unobserveAllIntersectionObservers() {
/*
* disconncet()可以取消所有observed目标
* 如果调用unobserve取消监听,稍显冗余的代码如下:
this.lazyLoad.target.forEach((image) => {
this.lazyLoad.observer.unobserve(image);
});
*/
this.lazyLoad.observer.disconnect();
/*
* 由于touchFooter和stickHeader只observe了一个目标,因此单独unobserve即可
* 当然disconnect()也是ok的
*/
this.touchFooter.observer.unobserve(this.touchFooter.target);
this.stickHeader.observer.unobserve(this.stickHeader.reference);
},
},
};
</script>
<style lang="scss" scoped>
.fixed-top-helper {
height: 1px;
background: #ccc;
}
header {
background: #ccc;
&.fixed {
position: fixed;
top: 0;
left: 0;
width: 100%;
}
}
main {
img {
display: block;
height: 500px;
margin: 30px;
}
}
footer {
background: #ccc;
}
</style> |
基于Intersection的开源工具 Scrollama官方提供了Basic Process,Progress,Sticky Side,Sticky Overlay几种示例。 Basic ProcessProgressSticky SideSticky Overlay在项目中可以当做适当引用。 项目地址:https://github.com/russellgoldenberg/scrollama |
总结
参考资料https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver |
The text was updated successfully, but these errors were encountered: