成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

瀏覽器的五種 Observer,你用過幾種?

系統 瀏覽器
瀏覽器提供了 5 種 Observer 來監聽這些變動:MutationObserver、IntersectionObserver、PerformanceObserver、ResizeObserver、ReportingObserver。

網頁開發中我們經常要處理用戶交互,我們會用 addEventListener 添加事件監聽器來監聽各種用戶操作,比如 click、mousedown、mousemove、input 等,這些都是由用戶直接觸發的事件。

那么對于一些不是由用戶直接觸發的事件呢?比如元素從不可見到可見、元素大小的改變、元素的屬性和子節點的修改等,這類事件如何監聽呢?

瀏覽器提供了 5 種 Observer 來監聽這些變動:MutationObserver、IntersectionObserver、PerformanceObserver、ResizeObserver、ReportingObserver。

我們分別來看一下:

IntersectionObserver

一個元素從不可見到可見,從可見到不可見,這種變化如何監聽呢?

用 IntersectionObserver。

IntersectionObserver 可以監聽一個元素和可視區域相交部分的比例,然后在可視比例達到某個閾值的時候觸發回調。

我們準備兩個元素:

<div id="box1">BOX111</div>
<div id="box2">BOX222</div>

加上樣式:

#box1,#box2 {
width: 100px;
height: 100px;
background: blue;
color: #fff;

position: relative;
}
#box1 {
top: 500px;
}
#box2 {
top: 800px;
}

這兩個元素分別在 500 和 800 px 的高度,我們監聽它們的可見性的改變。

const intersectionObserver = new IntersectionObserver(
function (entries) {
console.log('info:');
entries.forEach(item => {
console.log(item.target, item.intersectionRatio)
})
}, {
threshold: [0.5, 1]
});

intersectionObserver.observe( document.querySelector('#box1'));
intersectionObserver.observe( document.querySelector('#box2'));

創建一個 IntersectionObserver 對象,監聽 box1 和 box2 兩個元素,當可見比例達到 0.5 和 1 的時候觸發回調。

瀏覽器跑一下:

可以看到元素 box1 和 box2 在可視范圍達到一半(0.5)和全部(1)的時候分別觸發了回調。

這有啥用?

這太有用了,我們在做一些數據采集的時候,希望知道某個元素是否是可見的,什么時候可見的,就可以用這個 api 來監聽,還有做圖片的懶加載的時候,可以當可視比例達到某個比例再觸發加載。

除了可以監聽元素可見性,還可以監聽元素的屬性和子節點的改變:

MutationObserver

監聽一個普通 JS 對象的變化,我們會用 Object.defineProperty 或者 Proxy:

而監聽元素的屬性和子節點的變化,我們可以用 MutationObserver:

MutationObserver 可以監聽對元素的屬性的修改、對它的子節點的增刪改。

我們準備這樣一個盒子:

<div id="box"><button>光</button></div>

加上樣式:

 #box {
width: 100px;
height: 100px;
background: blue;

position: relative;
}

就是這樣的:

我們定時對它做下修改:

setTimeout(() => {
box.style.background = 'red';
},2000);

setTimeout(() => {
const dom = document.createElement('button');
dom.textContent = '東東東';
box.appendChild(dom);
},3000);

setTimeout(() => {
document.querySelectorAll('button')[0].remove();
},5000);

2s 的時候修改背景顏色為紅色,3s 的時候添加一個 button 的子元素,5s 的時候刪除第一個 button。

然后監聽它的變化:

const mutationObserver = new MutationObserver((mutationsList) => {
console.log(mutationsList)
});

mutationObserver.observe(box, {
attributes: true,
childList: true
});

創建一個 MutationObserver 對象,監聽這個盒子的屬性和子節點的變化。

瀏覽器跑一下:

可以看到在三次變化的時候都監聽到了并打印了一些信息:

第一次改變的是 attributes,屬性是 style:

第二次改變的是 childList,添加了一個節點:

第三次也是改變的 childList,刪除了一個節點:

都監聽到了!

這個可以用來做什么呢?比如文章水印被人通過 devtools 去掉了,那么就可以通過 MutationObserver 監聽這個變化,然后重新加上,讓水印去不掉。

當然,還有很多別的用途,這里只是介紹功能。

除了監聽元素的可見性、屬性和子節點的變化,還可以監聽大小變化:

ResizeObserver

窗口我們可以用 addEventListener 監聽 resize 事件,那元素呢?

元素可以用 ResizeObserver 監聽大小的改變,當 width、height 被修改時會觸發回調。

我們準備這樣一個元素:

<div id="box"></div>

添加樣式:

#box {
width: 100px;
height: 100px;
background: blue;
}

在 2s 的時候修改它的高度:

const box = document.querySelector('#box');

setTimeout(() => {
box.style.width = '200px';
}, 3000);

然后我們用 ResizeObserver 監聽它的變化:

const resizeObserver = new ResizeObserver(entries => {
console.log('當前大小', entries)
});
resizeObserver.observe(box);

在瀏覽器跑一下:

大小變化被監聽到了,看下打印的信息:

可以拿到元素和它的位置、尺寸。

這樣我們就實現了對元素的 resize 的監聽。

除了元素的大小、可見性、屬性子節點等變化的監聽外,還支持對 performance 錄制行為的監聽:

PerformanceObserver

瀏覽器提供了 performance 的 api 用于記錄一些時間點、某個時間段、資源加載的耗時等。

我們希望記錄了 performance 那就馬上上報,可是怎么知道啥時候會記錄 performance 數據呢?

用 PeformanceObserver。

PerformanceObserver 用于監聽記錄 performance 數據的行為,一旦記錄了就會觸發回調,這樣我們就可以在回調里把這些數據上報。

比如 performance 可以用 mark 方法記錄某個時間點:

performance.mark('registered-observer');

用 measure 方法記錄某個時間段:

performance.measure('button clicked', 'from', 'to');

后兩個個參數是時間點,不傳代表從開始到現在。

我們可以用 PerformanceObserver 監聽它們:

<html>
<body>
<button onclick="measureClick()">Measure</button>

<img src="https://p9-passport.byteacctimg.com/img/user-avatar/4e9e751e2b32fb8afbbf559a296ccbf2~300x300.image" />

<script>
const performanceObserver = new PerformanceObserver(list => {
list.getEntries().forEach(entry => {
console.log(entry);// 上報
})
});
performanceObserver.observe({entryTypes: ['resource', 'mark', 'measure']});

performance.mark('registered-observer');

function measureClick() {
performance.measure('button clicked');
}
</script>
</body>
</html>

創建 PerformanceObserver 對象,監聽 mark(時間點)、measure(時間段)、resource(資源加載耗時) 這三種記錄時間的行為。

然后我們用 mark 記錄了某個時間點,點擊 button 的時候用 measure 記錄了某個時間段的數據,還加載了一個圖片。

當這些記錄行為發生的時候,希望能觸發回調,在里面可以上報。

我們在瀏覽器跑一下試試:

可以看到 mark 的時間點記錄、資源加載的耗時、點擊按鈕的 measure 時間段記錄都監聽到了。

分別打印了這三種記錄行為的數據:

mark:

圖片加載:

measure:

用了這些數據,就可以上報上去做性能分析了。

除了元素、performance 外,瀏覽器還有一個 reporting 的監聽:

ReportingObserver

當瀏覽器運行到過時(deprecation)的 api 的時候,會在控制臺打印一個過時的報告:

瀏覽器還會在一些情況下對網頁行為做一些干預(intervention),比如會把占用 cpu 太多的廣告的 iframe 刪掉:

會在網絡比較慢的時候把圖片替換為占位圖片,點擊才會加載:

這些干預都是瀏覽器做的,會在控制臺打印一個報告:

這些干預或者過時的 api 并不是報錯,所以不能用錯誤監聽的方式來拿到,但這些情況對網頁 app 來說可能也是很重要的:

比如我這個網頁就是為了展示廣告的,但瀏覽器一干預給我把廣告刪掉了,我卻不知道。如果我知道的話或許可以優化下 iframe。

比如我這個網頁的圖片很重要,結果瀏覽器一干預給我換成占位圖了,我卻不知道。如果我知道的話可能會優化下圖片大小。

所以自然也要監聽,所以瀏覽器提供了 ReportingObserver 的 api 用來監聽這些報告的打印,我們可以拿到這些報告然后上傳。

const reportingObserver = new ReportingObserver((reports, observer) => {
for (const report of reports) {
console.log(report.body);//上報
}
}, {types: ['intervention', 'deprecation']});

reportingObserver.observe();

ReportingObserver 可以監聽過時的 api、瀏覽器干預等報告等的打印,在回調里上報,這些是錯誤監聽無法監聽到但對了解網頁運行情況很有用的數據。

文中的代碼上傳到了 github:https://github.com/QuarkGluonPlasma/browser-api-exercize

總結

監聽用戶的交互行為,我們會用 addEventListener 來監聽 click、mousedown、keydown、input 等事件,但對于元素的變化、performance 的記錄、瀏覽器干預行為這些不是用戶交互的事件就要用 XxxObserver 的 api 了。

瀏覽器提供了這 5 種 Observer:

  • IntersectionObserver:監聽元素可見性變化,常用來做元素顯示的數據采集、圖片的懶加載
  • MutationObserver:監聽元素屬性和子節點變化,比如可以用來做去不掉的水印
  • ResizeObserver:監聽元素大小變化
  • 還有兩個與元素無關的:
  • PerformanceObserver:監聽 performance 記錄的行為,來上報數據
  • ReportingObserver:監聽過時的 api、瀏覽器的一些干預行為的報告,可以讓我們更全面的了解網頁 app 的運行情況

這些 api 相比 addEventListener 添加的交互事件來說用的比較少,但是在特定場景下都是很有用的。

瀏覽器的 5 種 Observer,你用過幾種呢?在什么情況下用到過呢?

責任編輯:姜華 來源: 神光的編程秘籍
相關推薦

2024-10-30 16:39:45

2019-07-22 13:39:59

Python編輯器開發

2022-03-28 20:57:31

私有屬性class屬性和方法

2021-12-15 23:10:34

JS Debugger 前端開發

2020-10-12 09:59:59

AndroidGoogle瀏覽器

2024-01-17 13:58:00

算法C#冒泡排序

2023-11-22 09:45:44

2021-03-03 00:01:30

Redis數據結雙向鏈表

2010-04-05 21:57:14

Netscape瀏覽器

2016-11-11 14:03:01

2020-11-16 07:05:34

瀏覽器請求硬核

2021-03-08 05:42:26

瀏覽器FirefoxVIA瀏覽器

2024-03-20 08:06:20

瀏覽器擴展插件iTab

2016-06-02 13:22:12

LinuxWeb瀏覽器

2019-04-30 10:00:59

CSS居中前端

2021-10-08 08:20:06

LinuxChromium瀏覽器

2011-04-25 11:05:10

javascript

2016-01-05 12:54:52

瀏覽器瀏覽器端緩存

2024-04-24 11:24:43

C#數據去重

2012-03-20 11:41:18

海豚瀏覽器
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩久久综合 | 日韩成人在线播放 | 欧美激情在线播放 | 久久久国产一区二区 | 中文字幕人成乱码在线观看 | 在线视频一区二区三区 | 一区二区三区亚洲视频 | 国产精品99久久久久久久久久久久 | 国产日韩欧美 | 伊人久久综合 | 成人av免费 | 国产精品久久久久aaaa九色 | 精品久久久久久久 | 国产精品欧美一区二区 | 国产91视频播放 | 久久精品视频在线免费观看 | 欧美一区二区综合 | 91色视频在线观看 | 一级毛片中国 | 99免费精品视频 | 久国久产久精永久网页 | 久久一区精品 | 久久久91精品国产一区二区三区 | 国产丝袜一区二区三区免费视频 | 欧美激情综合色综合啪啪五月 | 欧美日韩在线观看一区 | 91av导航| 中文在线a在线 | 一级黄色毛片免费 | 黄色免费av | 国内精品在线视频 | 91亚洲精品久久久电影 | 欧美一区二区在线 | 日本一级淫片免费啪啪3 | 日本成人综合 | 最新中文字幕久久 | 日韩电影免费观看中文字幕 | 亚洲精品乱码久久久久久蜜桃91 | 久久久一区二区三区 | 黄色免费网站在线看 | 中文字幕在线观看av |