我正在尝试开发一个书签。小书签的目的是显示当前选项卡和由window.open
调用启动的新选项卡的URL。为简化起见,假设launcher.com
启动随机URL访问。
function getBothURLs() {
var currentURL, newWin;
function launchNew () {
currentURL = window.location.href;
newWin = window.open("https://www.launcher.com");
}
launchNew();
alert(currentURL);
alert(newWin.location.href); // displays 'about:blank'
}
我无法获取新启动的标签的网址。 alert()
(位于下方函数的最后)无法正确显示新启动标签的网址;而是显示
about:blank
当我在Chrome控制台中进行故障排除时,我将var currentURL, newWin
的定义移到了getTwoURLs()
功能的范围之外。当我从控制台中调用函数getBothURLs()
时,currentURL
和newWin
都有有效数据。
如何修改函数getBothURLs()
以达到预期目的?
答案 0 :(得分:1)
来自MDN的window.open注释:
...远程网址不会立即加载。当 window.open()返回时,窗口始终包含 about:blank 。实际提取的URL是延迟,并在当前脚本块完成执行后启动...
在上述情况下,当前块以about:blank
函数结束,但您尝试检查该块本身内的新URL,并根据上面的引用,您看到setTimeout
网址
要解决此问题,只需将查找推迟到下一个任务。您可以使用类似function getBothURLs() {
return new Promise((resolve) => {
var newWin = window.open("//www.stackoverflow.com");
setTimeout(() => resolve(newWin))
}).then((win) => {
return new Promise((resolve, reject) => {
var check = setInterval(() => {
try {
if(win.location.href !== "about:blank"){
clearInterval(check);
resolve(win.location.href)
}
} catch(e) {
clearInterval(check);
reject(e);
}
}, 50)
})
})
}
getBothURLs().then(url => console.log(url))
的内容将发布查找到下一个任务,或者更好的是,如果您希望从函数中返回值,则使用Promises。
示例实现可能如下所示:
open
虽然上述解决方案有效,但我仍然建议您将新窗口的URL存储在变量中,然后使用该变量调用function getBothURLs(callback){
var current = window.location.href;
var win = window.open("https://stackoverflow.com");
var check = setInterval(() => {
try {
if(win.location.href !== "about:blank"){
clearInterval(check);
callback(null, current, win.location.href)
}
} catch(e) {
clearInterval(check);
callback(e);
}
}, 50);
}
getBothURLs((err, _cur, _new) => {
if(err){
// some error occurred, probably a cross-origin access
console.error("Failed to get URL", err);
return;
}
console.log(`Current: ${_cur} New: ${_new}`);
})
。
此示例代码段使用可以返回两个网址的非承诺回调版本。虽然,可以修改promise版本以返回两个URL,但由于OP在评论中要求基于非承诺的版本,所以我提供了新的代码片段。 看看:
<select ng-model='names.productionType' ng-options="data for data in productionType"></select>