javascript - 为什么 waitForKeyElements 对于 Google 搜索结果需要另一个超时?

标签 javascript greasemonkey tampermonkey scriptish

下面的脚本完成了我想要它做的事情,但没有我想要的那么快。 :-)

目标始终是显示在 Google 搜索结果中点击“搜索工具”按钮时可见的搜索工具。

如果不应用计时器,我无法让 waitForKeyElements 工作。
WaitForKeyElements was made for this purpose所以我觉得我错过了什么。

这个脚本可以工作,但花费的时间太长而且看起来很脆弱:

// ==UserScript==
// @name        GollyJer's Expand Google Search Tools
// @namespace   gollyjer.com
// @version     1.0
// @include      /^https?\:\/\/(www|news|maps|docs|cse|encrypted)\.google\./
// @require     http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js
// @require     https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant       GM_addStyle
// ==/UserScript==

function expandSearchTools () {
    // Fires too soon?
    // var searchToolsButton = document.getElementById("hdtb-tls");   
    // searchToolsButton.click();

    // Working but distracting.
    setTimeout(
        function(){
          var searchToolsButton = document.getElementById("hdtb-tls");   
          searchToolsButton.click();

    }, 1000);
}

waitForKeyElements ("#ires", expandSearchTools);

最佳答案

有时,仅仅等待某个特定元素并单击它是不够的。有时您还必须允许与该元素关联的 javascript 进行初始化。

这在 Google 之类的页面上可能会很困难,因为其中涉及 javascript 且人类无法(轻松)阅读。

解决此问题的一般方法是,当单击节点时检查单击的预期效果,并重复单击直到发生这种情况。

在这种情况下,点击应该会打开搜索工具 栏。所以我们可以检查是否发生这种情况并继续点击,直到页面的 click 事件处理程序准备就绪并做出响应。

这样也加了定时器,但是比题中的one-shot delay更快更灵活。
它还具有优势,因为我们使用页面的预期输入来更改内容,页面的 javascript 不会与页面不同步或进入意外状态(在最坏的情况下崩溃)。

检查预期效果在一般情况下有效,当简单的点击不起作用时:

// ==UserScript==
// @name        GollyJer's Expand Google Search Tools
// @include      /^https?\:\/\/(www|news|maps|docs|cse|encrypted)\.google\./
// @require     http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js
// @require     https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant       GM_addStyle
// ==/UserScript==

waitForKeyElements ("#hdtb-tls", clickNodeTilItSticks);

function clickNodeTilItSticks (jNode) {
    var srchToolBar = $("#hdtbMenus")[0];
    var sanityCount = 1;
    var menusVisiblePoller = setInterval ( function () {
            if (sanityCount < 20  &&  srchToolBar.offsetWidth === 0  &&  srchToolBar.offsetHeight === 0) {
                var clickEvent  = document.createEvent ('MouseEvents');
                clickEvent.initEvent ('click', true, true);
                jNode[0].dispatchEvent (clickEvent);
            }
            else {
                clearInterval (menusVisiblePoller);
            }
            sanityCount++;
        },
        88
    );
}

关于javascript - 为什么 waitForKeyElements 对于 Google 搜索结果需要另一个超时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33685355/

相关文章:

javascript - 为什么这段代码会执行无限循环?

javascript - Angular JS 过滤 UNIX 时间,认为是 1970 年,否则很好

javascript - ParseFloat 变为 NaN

google-analytics - 如何跟踪我的 Greasemonkey 脚本有多少次自动升级下载?

javascript - 如何为其他用户远程启用/禁用 tampermonkey 脚本

javascript - 如何使用 jsGrid 将项目获取到字段中的下拉列表?

javascript - 如何从 Greasemonkey 脚本中取消选中 HTML 页面上的所有 "md-checkboxes"(不是真正的复选框)?

jquery - Greasemonkey、跨域、jQuery、get() 请求失败,出现 405 "method not allowed"

php - Greasemonkey AJAX 请求不发送数据?

jquery - 使用greasemonkey/tampermonkey(例如SO)使 Bootstrap 模式与另一个网站一起工作