Почему waitForKeyElements нужен другой тайм-аут для результатов поиска Google?

Следующий скрипт выполняет то, что я хочу, но не так быстро, как хотелось бы.:-)

Цель - всегда показывать инструменты поиска, которые становятся видимыми при нажатии кнопки "Инструменты поиска" в результатах поиска Google.

Я не могу получить waitForKeyElements работать без применения таймера.
Brock Adams, поэтому я чувствую, что что-то упустил.

Этот сценарий работает, вроде как, но занимает слишком много времени и кажется хрупким:

// ==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 ответа

Решение

Иногда недостаточно дождаться определенного элемента, чтобы щелкнуть по нему. Иногда вы также должны разрешить инициализацию JavaScript, связанный с этим элементом.

Это может быть сложно на таких страницах, как Google, где 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
    );
}

Хорошо, разобрался немного по другому пути с гораздо более надежными результатами...

Нажатие кнопки "Инструменты поиска" делает несколько вещей в 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");
}
Другие вопросы по тегам