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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

js如何监听元素事件是否被移除_JavaScript 监听元素是否进入/移出可视区域

發布時間:2023/12/3 javascript 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js如何监听元素事件是否被移除_JavaScript 监听元素是否进入/移出可视区域 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JavaScript 監聽元素是否進入/移出可視區域

常規操作

防抖節流

IntersectionObserver

兼容的代碼

常規操作

通常的做法是,監聽srcoll事件,根據元素的offset來判斷。

window.addEventListener('scroll', this.scrollHandle, true);

使用getBoundingClientRec()來獲取元素的位置。

scrollHandle () {

const offset = this.$el.getBoundingClientRect(); // vue中,使用this.$el獲取當前組件的根元素

const offsetTop = offset.top;

const offsetBottom = offset.bottom;

const offsetHeight = offset.height;

// 進入可視區域

if (offsetTop <= window.innerHeight && offsetBottom >= 0) {

console.log('進入可視區域');

// do something...

} else {

console.log('移出可視區域');

// do something...

}

}

記得在適當的時候移除事件監聽

window.removeEventListener('scroll', this.scrollHandle, true);

但是這種操作,使得我們的開銷變得很大,所以可以考慮防抖和節流。

防抖節流

關于防抖和節流,看過不一樣的理解,有的人認為防抖和節流是一個意思,在這里,按照我的理解,給防抖和節流的定義如下:

防抖:在停止觸發一段時間后再調用方法;

節流:再一段時間內至少調用一次方法;

具體的原理就不講了,直接上代碼,iselapsed參數表示是否等待上一次,也就是iselapsed為true,則為節流。

/**

* 防抖節流

* @param {*} action 回調

* @param {*} delay 等待的時間

* @param {*} context this指針

* @param {Boolean} iselapsed 是否等待上一次

* @returns {Function}

*/

function throttle (action, delay, context, iselapsed) {

let timeout = null;

let lastRun = 0;

return function () {

if (timeout) {

if (iselapsed) {

return;

} else {

clearTimeout(timeout);

timeout = null;

}

}

let elapsed = Date.now() - lastRun;

let args = arguments;

if (iselapsed && elapsed >= delay) {

runCallback();

} else {

timeout = setTimeout(runCallback, delay);

}

/**

* 執行回調

*/

function runCallback() {

lastRun = Date.now();

timeout = false;

action.apply(context, args);

}

};

}

在這里,我希望方法在一段時間內至少執行一次,所以我用節流

window.addEventListener('scroll', this.scrollHandle, true);

this.scrollHandle = throttle(this.scrollThrottle, 200, this, true)

scrollThrottle () {

const offset = this.$el.getBoundingClientRect();

const offsetTop = offset.top;

const offsetBottom = offset.bottom;

const offsetHeight = offset.height;

// 進入可視區域

if (offsetTop <= window.innerHeight && offsetBottom >= 0) {

console.log('進入可視區域');

// do something...

} else {

console.log('移出可視區域');

this.enabledPause = false;

// do something...

}

}

IntersectionObserver

安卓設備和部分瀏覽器支持IntersectionObserver來通知我們元素進入/移出可視區域。

判斷是否支持IntersectionObserver:

if ('IntersectionObserver' in window &&

'IntersectionObserverEntry' in window &&

'intersectionRatio' in window.IntersectionObserverEntry.prototype) {

// do something

}

創建IntersectionObserver,并傳入回調,指定進入/移出可視區域時的操作。還可以傳入一個對象({threshold, root}),用來配置IntersectionObserver。

threshold屬性決定了什么時候觸發回調函數。它是一個數組,每個成員都是一個門檻值,例如[0, 0.25, 0.5, 0.75, 1]。默認為[0],即交叉比例(intersectionRatio)達到0時觸發回調函數。

root屬性用來指定根元素。

callback函數的參數entries是一個數組,每個成員都是一個IntersectionObserverEntry對象,其中的intersectionRatio屬性表示監聽的元素與根元素的交叉的比例,>0則表示此時進入可視區域。

this.observer = new IntersectionObserver(entries => {

if (entries[0].intersectionRatio > 0) {

console.log('進入可視區域');

// do something

} else {

console.log('移出可視區域');

// do something

}

});

開始監聽

this.observer.observe(this.$el);

取消監聽

this.observer.disconnect();

兼容的代碼

因為iOS不支持IntersectionObserver,所以我們要在不支持的時候繼續監聽scroll事件。

貼上完整的代碼

import throttle from '../throttle.js';

export default {

data () {

return {

observer: null,

scrollHandle: throttle(this.scrollThrottle, 200, this, true)

};

},

mounted () {

// 判斷是否支持 IntersectionObserver

if ('IntersectionObserver' in window &&

'IntersectionObserverEntry' in window &&

'intersectionRatio' in window.IntersectionObserverEntry.prototype) {

this.observer = new IntersectionObserver(entries => {

if (entries[0].intersectionRatio > 0) {

console.log('進入可視區域');

// do something

} else {

console.log('移出可視區域');

// do something

}

});

}

},

methods: {

startObserve () {

if (this.observer) {

this.observer.observe(this.$el);

} else {

window.addEventListener('scroll', this.scrollHandle, true);

}

},

endObserve () {

if (this.observer) {

this.observer.disconnect();

} else {

window.removeEventListener('scroll', this.scrollHandle, true);

}

},

scrollThrottle () {

const offset = this.$el.getBoundingClientRect();

const offsetTop = offset.top;

const offsetBottom = offset.bottom;

const offsetHeight = offset.height;

// 進入可視區域

if (offsetTop <= window.innerHeight && offsetBottom >= 0) {

console.log('進入可視區域');

// do something

} else {

console.log('移出可視區域');

// do something

}

}

}

}

throttle.js

/**

* 回調節流

*

* @export

* @param {*} action 回調

* @param {*} delay 等待的時間

* @param {*} context this指針

* @param {Boolean} iselapsed 是否等待上一次

* @returns {Function}

*/

export default function throttle (action, delay, context, iselapsed) {

let timeout = null;

let lastRun = 0;

return function () {

if (timeout) {

if (iselapsed) {

return;

} else {

clearTimeout(timeout);

timeout = null;

}

// return;

}

let elapsed = Date.now() - lastRun;

let args = arguments;

if (iselapsed && elapsed >= delay) {

runCallback();

} else {

timeout = setTimeout(runCallback, delay);

}

/**

* 執行回調

*/

function runCallback() {

lastRun = Date.now();

timeout = false;

action.apply(context, args);

}

};

}

總結

以上是生活随笔為你收集整理的js如何监听元素事件是否被移除_JavaScript 监听元素是否进入/移出可视区域的全部內容,希望文章能夠幫你解決所遇到的問題。

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