亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

使用JavaScript實(shí)現(xiàn)檢測(cè)網(wǎng)頁(yè)是否為空閑狀態(tài)

 更新時(shí)間:2024年03月28日 11:14:40   作者:求知若饑  
最近開(kāi)發(fā)項(xiàng)目時(shí),常碰到“用戶在一定時(shí)間內(nèi)無(wú)任何操作時(shí),跳轉(zhuǎn)到某個(gè)頁(yè)面”的需求,所以本文就來(lái)使用JavaScript實(shí)現(xiàn)這一要求,需要的可以參考下

1. 背景

最近開(kāi)發(fā)項(xiàng)目時(shí),常碰到“用戶在一定時(shí)間內(nèi)無(wú)任何操作時(shí),跳轉(zhuǎn)到某個(gè)頁(yè)面”的需求。

網(wǎng)上沖浪后,也沒(méi)有找到一個(gè)比較好的js封裝去解決這個(gè)問(wèn)題,從而決定自己實(shí)現(xiàn)。

2. 如何判斷頁(yè)面是否空閑(用戶長(zhǎng)時(shí)間無(wú)操作)

首先,我們要知道什么是空閑?用戶一定時(shí)間內(nèi),沒(méi)有對(duì)網(wǎng)頁(yè)進(jìn)行任何操作,則當(dāng)前網(wǎng)頁(yè)為空閑狀態(tài)。

用戶操作網(wǎng)頁(yè),無(wú)非就是通過(guò)鼠標(biāo)、鍵盤兩個(gè)輸入設(shè)備(暫不考慮手柄等設(shè)備)。因而我們可以監(jiān)聽(tīng)相應(yīng)的輸入事件,來(lái)判斷網(wǎng)頁(yè)是否空閑(用戶是否操作網(wǎng)頁(yè))。

  • 監(jiān)聽(tīng)鼠標(biāo)移動(dòng)事件mousemove;
  • 監(jiān)聽(tīng)鍵盤按下事件mousedown;
  • 在用戶進(jìn)入網(wǎng)頁(yè)后,設(shè)置延時(shí)跳轉(zhuǎn),如果觸發(fā)以上事件,則移除延時(shí)器,并重新開(kāi)始。

3. 網(wǎng)頁(yè)空閑檢測(cè)實(shí)現(xiàn)

3.1 簡(jiǎn)易實(shí)現(xiàn)

以下代碼,簡(jiǎn)易實(shí)現(xiàn)了一個(gè)判斷網(wǎng)頁(yè)空閑的方法。

const onIdleDetection = (callback, timeout = 15, immediate = false) => {
  let pageTimer;
  
  const onClearTimer = () => {
    pageTimer && clearTimeout(pageTimer);
    pageTimer = undefined;
  };
  const onStartTimer = () => {
    onClearTimer();
    pageTimer = setTimeout(() => {
      callback();
    }, timeout * 1000);
  };

  const startDetection = () => {
    onStartTimer();
    document.addEventListener('mousedown', onStartTimer);
    document.addEventListener('mousemove', onStartTimer);
  };
  const stopDetection = () => {
    onClearTimer();
    document.removeEventListener('mousedown', onStartTimer);
    document.removeEventListener('mousemove', onStartTimer);
  };
  const restartDetection = () => {
      onClearTimer();
      onStartTimer();
  };

  if (immediate) {
    startDetection();
  }

  return {
    startDetection,
    stopDetection,
    restartDetection
  };
};

也許你注意到了,我并沒(méi)有針對(duì)onStartTimer事件進(jìn)行防抖,那這是不是會(huì)對(duì)性能有影響呢?

是的,肯定有那么點(diǎn)影響,那我為啥不添加防抖呢?

這是因?yàn)樘砑臃蓝逗?,形成?code>setTimeout嵌套,嵌套setTimeout會(huì)有精度問(wèn)題(參考)。

或許你還會(huì)說(shuō),非活動(dòng)標(biāo)簽頁(yè)(網(wǎng)頁(yè)被隱藏)的setTimeout的執(zhí)行和精度會(huì)有問(wèn)題(參考非活動(dòng)標(biāo)簽的超時(shí))。

確實(shí)存在以上問(wèn)題,接下來(lái)我們就來(lái)一一解決吧!

3.2 處理頻繁觸發(fā)問(wèn)題

我們可以通過(guò)添加一個(gè)變量記錄開(kāi)始執(zhí)行時(shí)間,當(dāng)下一次執(zhí)行與當(dāng)前的時(shí)間間隔小于某個(gè)值時(shí)直接退出函數(shù),從而解決這個(gè)問(wèn)題(節(jié)流思想應(yīng)用)。

const onIdleDetection = (callback, timeout = 15, immediate = false) => {
  let pageTimer;
  // 記錄開(kāi)始時(shí)間
  let beginTime = 0;
  const onStartTimer = () => {
    // 觸發(fā)間隔小于100ms時(shí),直接返回
    const currentTime = Date.now();
    if (pageTimer && currentTime - beginTime < 100) {
      return;
    }

    onClearTimer();
    // 更新開(kāi)始時(shí)間
    beginTime = currentTime;
    pageTimer = setTimeout(() => {
      callback();
    }, timeout * 1000);
  };
  const onClearTimer = () => {
    pageTimer && clearTimeout(pageTimer);
    pageTimer = undefined;
  };
  
  const startDetection = () => {
    onStartTimer();
    document.addEventListener('mousedown', onStartTimer);
    document.addEventListener('mousemove', onStartTimer);
  };
  const stopDetection = () => {
    onClearTimer();
    document.removeEventListener('mousedown', onStartTimer);
    document.removeEventListener('mousemove', onStartTimer);
  };
  const restartDetection = () => {
      onClearTimer();
      onStartTimer();
  };
  
  if (immediate) {
    startDetection();
  }

  return {
    startDetection,
    stopDetection,
    restartDetection
  };
};

3.3 處理頁(yè)面被隱藏的情況(完整實(shí)現(xiàn))

我們可以監(jiān)聽(tīng)visibilitychange事件,在頁(yè)面隱藏時(shí)移除延時(shí)器,然后頁(yè)面顯示時(shí)繼續(xù)計(jì)時(shí),從而解決這個(gè)問(wèn)題。

/**
 * 網(wǎng)頁(yè)空閑檢測(cè)
 * @param {() => void} callback 空閑時(shí)執(zhí)行,即一定時(shí)長(zhǎng)無(wú)操作時(shí)觸發(fā)
 * @param {number} [timeout=15] 時(shí)長(zhǎng),默認(rèn)15s,單位:秒
 * @param {boolean} [immediate=false] 是否立即開(kāi)始,默認(rèn) false
 * @returns
 */
const onIdleDetection = (callback, timeout = 15, immediate = false) => {
  let pageTimer;
  let beginTime = 0;
  const onClearTimer = () => {
    pageTimer && clearTimeout(pageTimer);
    pageTimer = undefined;
  };
  const onStartTimer = () => {
    const currentTime = Date.now();
    if (pageTimer && currentTime - beginTime < 100) {
      return;
    }

    onClearTimer();
    beginTime = currentTime;
    pageTimer = setTimeout(() => {
      callback();
    }, timeout * 1000);
  };

  const onPageVisibility = () => {
     // 頁(yè)面顯示狀態(tài)改變時(shí),移除延時(shí)器
     onClearTimer();

     if (document.visibilityState === 'visible') {
       const currentTime = Date.now();
       // 頁(yè)面顯示時(shí),計(jì)算時(shí)間,如果超出限制時(shí)間則直接執(zhí)行回調(diào)函數(shù)
       if (currentTime - beginTime >= timeout * 1000) {
         callback();
         return;
       }
       // 繼續(xù)計(jì)時(shí)
       pageTimer = setTimeout(() => {
         callback();
       }, timeout * 1000 - (currentTime - beginTime));
     }
  };

  const startDetection = () => {
    onStartTimer();
    document.addEventListener('mousedown', onStartTimer);
    document.addEventListener('mousemove', onStartTimer);
    document.addEventListener('visibilitychange', onPageVisibility);
  };

  const stopDetection = () => {
    onClearTimer();
    document.removeEventListener('mousedown', onStartTimer);
    document.removeEventListener('mousemove', onStartTimer);
    document.removeEventListener('visibilitychange', onPageVisibility);
  };
  
  const restartDetection = () => {
      onClearTimer();
      onStartTimer();
  };

  if (immediate) {
    startDetection();
  }

  return {
    startDetection,
    stopDetection,
    restartDetection
  };
};

通過(guò)以上代碼,我們就完整地實(shí)現(xiàn)了一個(gè)網(wǎng)頁(yè)空閑狀態(tài)檢測(cè)的方法。

4. 擴(kuò)展

chrome瀏覽器其實(shí)提供了一個(gè)Idle DetectionAPI,來(lái)實(shí)現(xiàn)網(wǎng)頁(yè)空閑狀態(tài)的檢測(cè),但是這個(gè)API還是一個(gè)實(shí)驗(yàn)性特性,并且Firefox與Safari不支持。API參考

到此這篇關(guān)于使用JavaScript實(shí)現(xiàn)檢測(cè)網(wǎng)頁(yè)是否為空閑狀態(tài)的文章就介紹到這了,更多相關(guān)JavaScript檢測(cè)網(wǎng)頁(yè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論