javascript 确保页面已完全加载后单击按钮
javascript click button after be shure that page has completely loaded
我有网站 example.com,在这个网站上有一个 ID 为 "button1" 的按钮,点击这个按钮,它会打开一个未知的 url "example.com/unknownUrl"上面有已知按钮 "buttonOnUnknownPage"。我如何确定未知页面已完成加载并且我可以单击 "buttonOnUnknownPage"?
注意:"example.com" 在脚本之外的另一个 window 中打开。这意味着,脚本在 "example.com" 重新加载后不会停止 运行。
到目前为止我一直在使用这个:
// open example.com and get button1
exampleWindow = window.open("http://example.com", "_blank");
button1 = exampleWindow.document.getElementById('button1');
// clicking on button 1 opens example.com/unknownUrl
button1.click();
//and now wait 1000ms until page might be loaded
setTimeout(function() {
buttonOnUnknownPage = exampleWindow.document.getElementById('buttonOnUnknownPage');
buttonOnUnknownPage.click()
}, 1000);
这个问题是,我每次都需要等待 1000 毫秒,但仍然不能确定 "example.com/unknownUrl" 是否已加载。
是否有更有效的方法来确保 "example.com/unknownUrl" 已加载?像 document.onload
?
这样的东西
在其他 window 更改位置时对其进行监视是相当复杂的,之所以复杂是因为每次其他 window 加载新文档时,整个 window
状态被清除,所有事件监听器被清除,一个全新的文档被创建。因此,您不能安装一次事件侦听器并继续使用它,因为每次单击新的 link 和更改页面位置时它都会被清除。
为特定 URL 创建新的 window 的过程将(在某些浏览器中)首先加载名为 [=13 的 URL =],然后加载真正的 URL,导致您的监控有时会检测到 about:blank 内部 URL 的加载,而不是您要监控的真正 URL。 IE(即使是新版本)对此特别不利(不足为奇)。
因此,可以跟踪这些外部 windows 的加载,但需要一些技巧才能使其正常工作。黑客攻击需要以下步骤:
- 获取 window 的原始 URL(在您告诉它加载新内容之前它是什么)。
- 等到 window 的 window.location.href 值不再是原来的 URL。这表示 window 现在已经开始加载其新的 URL.
- 加载新的 URL 后,请等待 window 显示它有一个
.addEventListener
属性。由于某些未知原因,在 IE 中新创建的 windows 还没有这个 属性。这意味着您不能在新创建的 window 上安装 load
事件处理程序。相反,您必须等到 属性 可用,然后才能安装 load
事件处理程序。
- 当
.addEventListener
属性 可用时,查看文档是否已完成加载。如果是这样,请继续您的 DOM 操作。如果没有,则在文档加载完成时注册一个事件处理程序。
我创建了一个函数调用 monitorWindowLoad()
来执行上述这些步骤:
function monitorWindowLoad(win, origURL, fn) {
log("monitorWindowLoad: origURL = " + origURL);
function windowInitiated() {
// at this point, we know the new URL is in window.location.href
// so the loading of the new window has started
// unfortunately for us, IE does not necessarily have a fully formed
// window object yet so we have to wait until the addEventListener
// property is available
checkCondition(function() {
return !!win.addEventListener;
}, windowListen);
}
// new window is ready for a listener
function windowListen() {
if (win.document.readyState === "complete") {
log("found readyState");
fn();
} else {
log("no readyState, setting load event handler");
win.addEventListener("load", fn);
}
}
if (origURL) {
// wait until URL changes before starting to monitor
// the changing of the URL will signal that the new loading window has been initialized
// enough for us to monitor its load status
checkCondition(function() {
return win.location.href !== origURL;
}, windowInitiated);
} else {
windowInitiated();
}
}
// Check a condition. If immediately true, then call completeFn
// if not immediately true, then keep testing the condition
// on an interval timer until it is true
function checkCondition(condFn, completeFn) {
if (condFn()) {
completeFn();
} else {
var timer = setInterval(function() {
if (condFn()) {
clearInterval(timer);
completeFn();
}
}, 1);
}
}
然后可以使用此函数在多个加载页面中单击连续的 links:
function go() {
// open new window
var exampleWindow = window.open("window2.html");
monitorWindowLoad(exampleWindow, "about:blank", function() {
var loc = exampleWindow.location.href;
clickButton(exampleWindow, "button2");
monitorWindowLoad(exampleWindow, loc, function() {
loc = exampleWindow.location.href;
clickButton(exampleWindow, "button3");
monitorWindowLoad(exampleWindow, loc, function() {
// last page loaded now
});
});
});
}
实际上有这个概念的工作演示 here。这将加载一个名为 window1a.html 的文件。该页面中的 Javascript 会为 window2.html 打开一个新的 window,当它被加载时,它会单击那个 window 中的特定 link。单击 link 会打开 window3.html,加载后,它会单击 window 中的 link,然后打开 window4.html。您最终应该打开两个 windows(window1a.html 和 window4.html)。 window1a.html 将包含它执行的各种事件的日志。
window1.html 中的脚本不知道任何 URL。它只是单击 link 并在新加载的 window 加载时进行监视,以便它可以单击下一个 link 等等。
我有网站 example.com,在这个网站上有一个 ID 为 "button1" 的按钮,点击这个按钮,它会打开一个未知的 url "example.com/unknownUrl"上面有已知按钮 "buttonOnUnknownPage"。我如何确定未知页面已完成加载并且我可以单击 "buttonOnUnknownPage"?
注意:"example.com" 在脚本之外的另一个 window 中打开。这意味着,脚本在 "example.com" 重新加载后不会停止 运行。
到目前为止我一直在使用这个:
// open example.com and get button1
exampleWindow = window.open("http://example.com", "_blank");
button1 = exampleWindow.document.getElementById('button1');
// clicking on button 1 opens example.com/unknownUrl
button1.click();
//and now wait 1000ms until page might be loaded
setTimeout(function() {
buttonOnUnknownPage = exampleWindow.document.getElementById('buttonOnUnknownPage');
buttonOnUnknownPage.click()
}, 1000);
这个问题是,我每次都需要等待 1000 毫秒,但仍然不能确定 "example.com/unknownUrl" 是否已加载。
是否有更有效的方法来确保 "example.com/unknownUrl" 已加载?像 document.onload
?
在其他 window 更改位置时对其进行监视是相当复杂的,之所以复杂是因为每次其他 window 加载新文档时,整个 window
状态被清除,所有事件监听器被清除,一个全新的文档被创建。因此,您不能安装一次事件侦听器并继续使用它,因为每次单击新的 link 和更改页面位置时它都会被清除。
为特定 URL 创建新的 window 的过程将(在某些浏览器中)首先加载名为 [=13 的 URL =],然后加载真正的 URL,导致您的监控有时会检测到 about:blank 内部 URL 的加载,而不是您要监控的真正 URL。 IE(即使是新版本)对此特别不利(不足为奇)。
因此,可以跟踪这些外部 windows 的加载,但需要一些技巧才能使其正常工作。黑客攻击需要以下步骤:
- 获取 window 的原始 URL(在您告诉它加载新内容之前它是什么)。
- 等到 window 的 window.location.href 值不再是原来的 URL。这表示 window 现在已经开始加载其新的 URL.
- 加载新的 URL 后,请等待 window 显示它有一个
.addEventListener
属性。由于某些未知原因,在 IE 中新创建的 windows 还没有这个 属性。这意味着您不能在新创建的 window 上安装load
事件处理程序。相反,您必须等到 属性 可用,然后才能安装load
事件处理程序。 - 当
.addEventListener
属性 可用时,查看文档是否已完成加载。如果是这样,请继续您的 DOM 操作。如果没有,则在文档加载完成时注册一个事件处理程序。
我创建了一个函数调用 monitorWindowLoad()
来执行上述这些步骤:
function monitorWindowLoad(win, origURL, fn) {
log("monitorWindowLoad: origURL = " + origURL);
function windowInitiated() {
// at this point, we know the new URL is in window.location.href
// so the loading of the new window has started
// unfortunately for us, IE does not necessarily have a fully formed
// window object yet so we have to wait until the addEventListener
// property is available
checkCondition(function() {
return !!win.addEventListener;
}, windowListen);
}
// new window is ready for a listener
function windowListen() {
if (win.document.readyState === "complete") {
log("found readyState");
fn();
} else {
log("no readyState, setting load event handler");
win.addEventListener("load", fn);
}
}
if (origURL) {
// wait until URL changes before starting to monitor
// the changing of the URL will signal that the new loading window has been initialized
// enough for us to monitor its load status
checkCondition(function() {
return win.location.href !== origURL;
}, windowInitiated);
} else {
windowInitiated();
}
}
// Check a condition. If immediately true, then call completeFn
// if not immediately true, then keep testing the condition
// on an interval timer until it is true
function checkCondition(condFn, completeFn) {
if (condFn()) {
completeFn();
} else {
var timer = setInterval(function() {
if (condFn()) {
clearInterval(timer);
completeFn();
}
}, 1);
}
}
然后可以使用此函数在多个加载页面中单击连续的 links:
function go() {
// open new window
var exampleWindow = window.open("window2.html");
monitorWindowLoad(exampleWindow, "about:blank", function() {
var loc = exampleWindow.location.href;
clickButton(exampleWindow, "button2");
monitorWindowLoad(exampleWindow, loc, function() {
loc = exampleWindow.location.href;
clickButton(exampleWindow, "button3");
monitorWindowLoad(exampleWindow, loc, function() {
// last page loaded now
});
});
});
}
实际上有这个概念的工作演示 here。这将加载一个名为 window1a.html 的文件。该页面中的 Javascript 会为 window2.html 打开一个新的 window,当它被加载时,它会单击那个 window 中的特定 link。单击 link 会打开 window3.html,加载后,它会单击 window 中的 link,然后打开 window4.html。您最终应该打开两个 windows(window1a.html 和 window4.html)。 window1a.html 将包含它执行的各种事件的日志。
window1.html 中的脚本不知道任何 URL。它只是单击 link 并在新加载的 window 加载时进行监视,以便它可以单击下一个 link 等等。