为什么 waitForKeyElements 需要另一个超时才能获得 Google 搜索结果?
Why does waitForKeyElements need another timeout for Google search results?
下面的脚本完成了我想要它做的事情,但没有我想要的那么快。 :-)
目标始终是显示在 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);
好的,想出了一个稍微不同的路径,结果更可靠...
单击“搜索工具”按钮会在 DOM 中执行一些操作,但对于此问题最重要的是替换 #hdtbMenus 上的 classes 之一,这会导致搜索工具显示而不是结果计数。
我自己简单地改变这个 class 已经证明更可靠。
此代码现在运行良好。
// ==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");
}
有时,等待特定元素并单击它是不够的。有时您还必须 允许与该元素关联的 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
);
}
下面的脚本完成了我想要它做的事情,但没有我想要的那么快。 :-)
目标始终是显示在 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);
好的,想出了一个稍微不同的路径,结果更可靠...
单击“搜索工具”按钮会在 DOM 中执行一些操作,但对于此问题最重要的是替换 #hdtbMenus 上的 classes 之一,这会导致搜索工具显示而不是结果计数。
我自己简单地改变这个 class 已经证明更可靠。
此代码现在运行良好。
// ==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");
}
有时,等待特定元素并单击它是不够的。有时您还必须 允许与该元素关联的 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
);
}