日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

IntersectionObserve初试

發布時間:2024/4/15 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IntersectionObserve初试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

IntersectionObserve這個API,可能知道的人并不多(我也是最近才知道...),這個API可以很方便的監聽元素是否進入了可視區域。

<style> * {margin: 0;padding: 0; }.test {width: 200px;height: 1000px;background: orange; }.box {width: 150px;height: 150px;margin: 50px;background: red; } </style> <div class="test">test</div> <div class="box">box</div>

上圖代碼中,.box元素目前并不在可視區域(viewport)內,如何監聽它進入可視區域內?

傳統做法是:監聽scroll事件,實時計算.box距離viewport的top值:

const box = document.querySelector('.box'); const viewHeight = document.documentElement.clientHeight;window.addEventListener('scroll', () => {const top = box.getBoundingClientRect().top;if (top < viewHeight) {console.log('進入可視區域');} });

然而scroll事件會頻繁觸發,因此我們還需要手動節流。

使用IntersectionObserve就非常方便了:

const box = document.querySelector('.box'); const intersectionObserver = new IntersectionObserver((entries) => {entries.forEach((item) => {if (item.isIntersecting) {console.log('進入可視區域');}}) }); intersectionObserver.observe(box);

IntersectionObserver API是異步的,不隨著目標元素的滾動同步觸發,所以不會有性能問題。

IntersectionObserver構造函數

const io = new IntersectionObserver((entries) => {console.log(entries); });io.observe(dom);

調用IntersectionObserver時,需要給它傳一個回調函數。當監聽的dom元素進入可視區域或者從可視區域離開時,回調函數就會被調用。

注意: 第一次調用new IntersectionObserver時,callback函數會先調用一次,即使元素未進入可視區域。

構造函數的返回值是一個觀察器實例。實例的observe方法可以指定觀察哪個 DOM 節點。

// 開始觀察 io.observe(document.getElementById('example'));// 停止觀察 io.unobserve(element);// 關閉觀察器 io.disconnect();

IntersectionObserverEntry對象

callback函數被調用時,會傳給它一個數組,這個數組里的每個對象就是當前進入可視區域或者離開可視區域的對象(IntersectionObserverEntry對象)

這個對象有很多屬性,其中最常用的屬性是:

  • target: 被觀察的目標元素,是一個 DOM 節點對象
  • isIntersecting: 是否進入可視區域
  • intersectionRatio: 相交區域和目標元素的比例值,進入可視區域,值大于0,否則等于0

options

調用IntersectionObserver時,除了傳一個回調函數,還可以傳入一個option對象,配置如下屬性:

  • threshold: 決定了什么時候觸發回調函數。它是一個數組,每個成員都是一個門檻值,默認為[0],即交叉比例(intersectionRatio)達到0時觸發回調函數。用戶可以自定義這個數組。比如,[0, 0.25, 0.5, 0.75, 1]就表示當目標元素 0%、25%、50%、75%、100% 可見時,會觸發回調函數。
  • root: 用于觀察的根元素,默認是瀏覽器的視口,也可以指定具體元素,指定元素的時候用于觀察的元素必須是指定元素的子元素
  • rootMargin: 用來擴大或者縮小視窗的的大小,使用css的定義方法,10px 10px 30px 20px表示top、right、bottom 和 left的值
const io = new IntersectionObserver((entries) => {console.log(entries); }, {threshold: [0, 0.5],root: document.querySelector('.container'),rootMargin: "10px 10px 30px 20px", });

懶加載

圖片懶加載的原理就是:給img標簽一個自定義屬性,用來記錄真正的圖片地址。默認img標簽只加載一個占位符。當圖片進入可視區域時,再把img的src屬性更換成真正的圖片地址。

<div><img src="/empty.jpg" data-src="https://segmentfault.com/img/1.jpg" /><img src="/empty.jpg" data-src="https://segmentfault.com/img/2.jpg" /> </div> const intersectionObserver = new IntersectionObserver((entries) => {entries.forEach((item) => {if (item.isIntersecting) {item.target.src = item.target.dataset.src;// 替換成功后,停止觀察該domintersectionObserver.unobserve(item.target);}})}, {rootMargin: "150px 0px" // 提前150px進入可視區域時就加載圖片,提高用戶體驗});const imgs = document.querySelectorAll('[data-src]'); imgs.forEach((item) => {intersectionObserver.observe(item) });

打點上報

前端頁面經常有上報數據的需求,比如統計頁面上的某些元素是否被用戶查看,點擊。這時,我們就可以封裝一個Log組件,用于當元素進入可視區域時,就上報數據。
以React為例,我們希望:被Log組件包裹的元素,進入可視區域后,就向后臺發送{ appid: 1234, type: 'news'}數據

<LogclassName="container"log={{ appid: 1234, type: 'news'}}style={{ marginTop: '1400px' }}onClick={() => console.log('log')} ><div className="news" onClick={() => console.log('news')}><p>其他內容</p></div> </Log> import React, { Component } from 'react'; import PropTypes from 'prop-types';class Log extends Component {static propTypes = {log: PropTypes.object};constructor(props) {super(props);this.io = null;this.ref = React.createRef();}componentDidMount() {this.io = new IntersectionObserver(([entry]) => {if (entry.isIntersecting) {console.log('進入可視區域,將要發送log數據', this.props.log);sendLog(this.props.log);this.io.disconnect();}});this.io.observe(this.ref.current);}componentWillUnmount() {this.io && this.io.disconnect();}render() {// 把log屬性去掉,否則log屬性也會渲染在div上 // <div log="[object Object]"></div>const { log, ...props } = this.props;return (<div ref={this.ref} {...props}>{this.props.children}</div>)} }export default Log

兼容性

safari并不支持該API,因此為了兼容主流瀏覽器,我們需要引入polyfill
intersection-observer

總結

以上是生活随笔為你收集整理的IntersectionObserve初试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。