为什么waitForKeyElements需要为Google搜索结果再次超时?

时间:2015-11-13 03:16:06

标签: 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);

2 个答案:

答案 0 :(得分:2)

有时等待特定元素,点击它是不够的。有时您还必须允许与该元素关联的javascript初始化。

在像谷歌这样的网页上,这可能很难,因为javascript非常复杂,而且不易(人们)可读。

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

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

这也增加了一个计时器,但它比问题中的一次性延迟更快,更灵活 它还有一个好处,因为我们使用页面的预期输入来改变事物,页面的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
    );
}

答案 1 :(得分:1)

好的,想出一条路径略有不同,结果更可靠......

单击“搜索工具”按钮会在DOM中执行一些操作,但对此问题最重要的是替换#hdtbMenus上的一个类,这会导致显示搜索工具而不是结果计数。

简单地改变这门课程已被证明更可靠 这段代码现在效果很好。

// ==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==

// Hide the Search Tools button.
GM_addStyle("#hdtb-tls { display: none !important; }");

// Remove the menu animation for "instant" change to the menu.
GM_addStyle("#hdtbMenus { transition: none !important; }");

// Show the Search Tools menu.
waitForKeyElements ("#hdtbMenus", expandSearchTools);
function expandSearchTools (jNode) {
    jNode.removeClass("hdtb-td-c hdtb-td-h").addClass("hdtb-td-o");
}