首页 > 解决方案 > 如何使用 Tampermonkey 检查 webelement 状态变化之间的时间差

问题描述

我有一个带有文本“A”的网络元素。一段时间后,它将根据后端进程更改为“B”。我想编写一个 tampermonkey 脚本来检查此状态更改之间的时间差,如果它跨越某个特定时间,比如 30 分钟,那么我需要触发桌面通知。

一个小故障是检查状态变化,我现在每 5 分钟刷新一次页面。这对我的要求有什么影响吗?

// ==UserScript==
// @name         Test State Change
// @version      0.1
// @author       Aravindh
// @include      https://www.google.com
// @grant        GM_notification
// @require      http://code.jquery.com/jquery-1.12.4.min.js
// ==/UserScript==


setTimeout(function()
{
  location.reload(true);
  var runStatus = document.getElementById("id").textContent;
  var expectedStatus = "running"
  var status = runStatus.localeCompare(expectedStatus);
  console.log(status);
   if(status > -1)
    {
        GM_notification ( {title: 'foo', text: '42', timeout: 60000 } );
    }
}, 600000)

标签: javascripttampermonkey

解决方案


我从未听说过 Tampermonkey,所以我不知道这是否会以某种方式影响它,但这可以在 vanilla JavaSript 中轻松完成:

首先,JavaScript 是一种事件驱动的语言。一切都可以对环境的变化采取行动和作出反应。因此,使用setTimeout来查看是否发生了变化并不是最好的方法。

相反,您安装了一个事件监听器或观察器。我真的不能提供太多细节,因为我是一个后端并且不太熟悉 dom,可能有一个更简单的解决方案。但本质上:

// create a Mutation observer (google for details, you'll find better info than i coud give you)
const observer = new MutationObserver(([{addedNodes, removedNodes}]) => /*add some callback function here*/)

// observe the element
observer.observe(document.getElementByID('yourElement'), {childList: true, /* observe childListChanges */})

// add the timer for the max amount of time (eg. 30min)
const timeLimit = 1.8e6
let currentTimeout = setTimeout(onExpire, timeLimit)

// the callback when the timer expires
function onExpire () {
  // do something
}

现在,每次该元素的 cildList 更改时,都会调用您的回调。回调可能如下所示:

function callBack (mutations) {
  // `target` is the element, added/removedNodes is the observed change
  for (const {target, addedNodes, removedNodes} of mutations) {
    // check if the change you are looking for occured
    if (/*desired change occured*/) {
      // kill the old timeout
      clearTimeout(currentTimeout /* the timeout from above */)
      // start a new timeout
      currentTimeout = setTimeout(onExpire, timeLimit/* same params as before */)
    }
  }
}

推荐阅读