【问题标题】:wait until something == something in javascript等到某事== javascript中的某事
【发布时间】:2018-09-23 01:14:14
【问题描述】:

我正在编写一个脚本,该脚本按下添加到购物车按钮,然后等待购物车项目数 = 当前项目数

现在,即使在 if 语句变为 false 之后,我似乎也无法摆脱我添加的 if 语句。

这是我尝试过的:

  $("#add-remove-buttons :input")[0].click();
  let cart_count = $("#items-count").text();
  if (cart_count !== `${request} items`){
    setInterval(function() {
      let cart_count = $("#items-count").text();
      console.log(cart_count, `${request} items`);
    }, 50);
  }
  if (cart_count == `${request} items`) {
    chrome.runtime.sendMessage({finished:"done_after1"});
  }

这是控制台中的结果:

正如您可以告诉它的那样,控制台记录了 1 项 2 项,然后它转到 2 项 2 项,这就是它应该停止并发送消息的时间。但由于某种原因,它一直在控制台记录

我也试过这段代码:

$("#add-remove-buttons :input")[0].click();
let cart_count = $("#items-count").text();
while (cart_count !== `${request} items`){
  let cart_count = $("#items-count").text();
  console.log(cart_count, `${request} items`);
}
chrome.runtime.sendMessage({finished:"done_after1"});

所以它应该在while循环不再为真之后退出while循环。但是由于某种原因,当我测试这个页面时,页面只是冻结了,我什至无法右键单击来检查控制台。由于某种原因,当我尝试这个 while 循环时,页面总是冻结。

如果有人知道这里出了什么问题,如果您能通过告诉我问题来帮助我,我将不胜感激。谢谢你!

【问题讨论】:

  • presses a add to cart button then waits until the cart item count = the current item count - 所以它应该一直按添加到购物车直到数字匹配?似乎您的代码只按下按钮一次 - 所以如果按下不能使它们匹配,它们永远不会

标签: javascript jquery google-chrome-extension sendmessage content-script


【解决方案1】:

只需将if 移动到setInterval - 您基本上必须在更改发生之后执行脚本

$("#add-remove-buttons :input")[0].click();
let cart_count = $("#items-count").text();
if (cart_count !== `${request} items`){
  setInterval(function() {
    let cart_count = $("#items-count").text();
    console.log(cart_count, `${request} items`);
  }, 50);
  if (cart_count == `${request} items`) {
    chrome.runtime.sendMessage({finished:"done_after1"});
  }
}

但是不要忘记也使用stopInterval

同时使用计时器来等待某些事情并不理想。最好使用在发生更改时触发的事件。

【讨论】:

  • 我将 stopInterval() 放在 if 语句中的 chrome sendMessage 正上方,但我仍然得到了无限循环,也许它不会 == 因为 car_count 是文本而请求项是字符串?跨度>
  • stopInterval() 不会停止特定的时间间隔,也不会停止任何时间间隔 - 您需要保存 intervalId ...例如let intervalId = setInterval(..... 然后使用 stopInterval(intervalId) 停止它
  • 我也试过 cart_count.toString() 还是不行。它似乎甚至没有进入 if 语句,您是否也可以编辑您的答案,以便我可以看到确切地说它是否有效
  • 你能澄清你的问题吗?如果上面的代码不起作用,那么你需要发布更多关于你在做什么的细节
  • 也没有stopInterval。它是clearInterval
【解决方案2】:

由于 #items-count 似乎不是 INPUT/TEXTAREA 等(即您可以使用 change 事件的东西,那么您可以使用 MutationObserver 如下

注意:我假设

$("#add-remove-buttons :input")[0].click();

需要单击直到值匹配 - 您的原始代码似乎只单击一次

我还使用非 jquery 来处理 #items-count 元素 - 因为在我看来它更简单

function handler(node) {
    let check = first => { // when triggered by mutation event, the argument "first" will be undefined
        let cart_count = node.textContent;
        if (cart_count === `${request} items`) {
            chrome.runtime.sendMessage({finished:"done_after1"});
            return true; // stop observing
        } else { // didn't match
            if (first) { // this is the first call - add a MutationObserver
                new MutationObserver((mutationList, observer) => {
                    if(check()) { // call with no argument, because MutationObserver is already set up
                        observer.disconnect(); // condition is met, so stop observing
                    }
                }).observe(node, {
                    childList:true
                });
            }
            // condition is not met, so click the add button
            $("#add-remove-buttons :input")[0].click();
        }
        return false; // keep observing
    };
    check(true);
}
handler(document.querySelector('#items-count'));

但是,如果 #items-count 是一个发出 change 事件的元素,那就更简单了

function handler(arg) { // when triggered by change event, arg will be defined
    let cart_count = $("#items-count").text();
    if (cart_count === `${request} items`) {
        if (arg) { // trigger by change event
            $("#items-count").off('change', handler);
        }
        chrome.runtime.sendMessage({finished:"done_after1"});
    } else {
        if (!arg) { // first call
            $("#items-count").change(handler);
        }
        $("#add-remove-buttons :input")[0].click();
    }
}
handler();

【讨论】:

  • runtime.onMessage 的事件处理程序出错:ReferenceError: arg 未定义
  • 不是问题或答案代码的一部分。所以不确定它与任何事物有什么关系
  • 我可以通过电子邮件将我的整个文件发送给您吗?因为这似乎不起作用我的电子邮件是 wojprod@gmail.com
  • 你刚刚发推给我了吗?
  • runtime.onMessage 的事件处理程序出错:ReferenceError: 处理程序未定义// 可能;)
【解决方案3】:

您没有在间隔内重新检查值,因此消息只有一次发送的机会,这将发生在间隔执行之前的某个时间。

也许可以尝试更多类似的东西......

$("#add-remove-buttons :input")[0].click ();
let cart_count = $("#items-count").text ();

if (cart_count === `${request} items`) {
    chrome.runtime.sendMessage ({ finished: "done_after1" });
} else {
    let interval = setInterval (function () {
        let cart_count = $("#items-count").text ();

        if (cart_count == `${request} items`) {
            chrome.runtime.sendMessage ({ finished: "done_after1" });
            clearInterval (interval);
        }

        console.log (cart_count, `${request} items`);
    }, 50);
}

【讨论】:

  • hmm 它可以工作,但是由于某种原因,它在获取 url 后只有一个错误,cart_count 应该随着每个 url 更新,但由于某种原因,请求保持为 2,当它转到第 3 个 url 应该更新为 3,但它只是停留在 2,不允许它执行 setInterval
  • 您的代码示例和原始帖子没有提及更改 URL,所以我不确定您的意思。
  • 我可以通过电子邮件将我的两个文件发送给您吗?我的电子邮件是 wojprod@gmail.com
  • 我不知道。我认为 PasteBin 或 JSFiddle 对帮助解决这个问题的其他人来说会更好、更公平。
  • 嗯,我有一些私人代码,我工作了很长时间,我真的不想全部展示
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-30
  • 1970-01-01
  • 2011-01-18
相关资源
最近更新 更多