3

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

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

如果不使用计时器,我就无法waitForKeyElements上班。
WaitForKeyElements 就是为此目的而制作的,所以我觉得我错过了一些东西。

这个脚本工作,有点,但时间太长而且看起来很脆弱:

// ==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);
4

2 回答 2

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
    );
}
于 2015-11-13T05:42:32.850 回答
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");
}
于 2015-11-13T04:57:03.130 回答