JavaScript 用于获取从当前选项卡启动的选项卡的 URL 的书签代码
JavaScript bookmarklet code to get URL of tab that was launched from current tab
我正在尝试开发一个小书签。小书签的目的是显示当前选项卡和因 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'
}
我无法获取新启动选项卡的 URL。 alert()
(在下面函数的最后)没有正确显示新启动选项卡的 URL;而是显示
about:blank
当我在 Chrome 控制台中对此进行故障排除时,我将 var currentURL, newWin
的定义移到了 getTwoURLs()
函数的范围之外。当我从控制台调用函数 getBothURLs()
时,currentURL
和 newWin
都有有效数据。
函数getBothURLs()
应该如何修改才能达到预期目的?
来自 MDN 关于 window.open 的注释:
...remote URLs won't load immediately. When window.open() returns, the window always contains about:blank. The actual fetching of the URL is deferred and starts after the current script block finishes executing...
在上述情况下,current 块以 getBothURLs()
函数结束,但您尝试检查该块本身内的新 URL,并且根据上面的引用,你看到 about:blank
url.
要解决此问题,只需将查找推迟到下一个任务。您可以使用 setTimeout
之类的东西来 post 查找下一个任务,或者更好的是,如果您希望 return 值,请使用 Promises来自函数。
示例实现可能如下所示:
function getBothURLs() {
return new Promise((resolve) => {
var newWin = window.open("//www.whosebug.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))
尽管上述解决方案有效,但我仍然建议您将新 window 的 URL 存储在一个变量中,然后使用该变量调用 open
。
更新 1:
此示例代码段使用可以 return 两个 url 的非承诺回调版本。虽然,也可以将 promise 版本修改为 return 两个 url,但由于 OP 在评论中要求提供基于非 promise 的版本,所以我提供了新的代码片段。
看看:
function getBothURLs(callback){
var current = window.location.href;
var win = window.open("https://whosebug.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}`);
})
我正在尝试开发一个小书签。小书签的目的是显示当前选项卡和因 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'
}
我无法获取新启动选项卡的 URL。 alert()
(在下面函数的最后)没有正确显示新启动选项卡的 URL;而是显示
about:blank
当我在 Chrome 控制台中对此进行故障排除时,我将 var currentURL, newWin
的定义移到了 getTwoURLs()
函数的范围之外。当我从控制台调用函数 getBothURLs()
时,currentURL
和 newWin
都有有效数据。
函数getBothURLs()
应该如何修改才能达到预期目的?
来自 MDN 关于 window.open 的注释:
...remote URLs won't load immediately. When window.open() returns, the window always contains about:blank. The actual fetching of the URL is deferred and starts after the current script block finishes executing...
在上述情况下,current 块以 getBothURLs()
函数结束,但您尝试检查该块本身内的新 URL,并且根据上面的引用,你看到 about:blank
url.
要解决此问题,只需将查找推迟到下一个任务。您可以使用 setTimeout
之类的东西来 post 查找下一个任务,或者更好的是,如果您希望 return 值,请使用 Promises来自函数。
示例实现可能如下所示:
function getBothURLs() {
return new Promise((resolve) => {
var newWin = window.open("//www.whosebug.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))
尽管上述解决方案有效,但我仍然建议您将新 window 的 URL 存储在一个变量中,然后使用该变量调用 open
。
更新 1:
此示例代码段使用可以 return 两个 url 的非承诺回调版本。虽然,也可以将 promise 版本修改为 return 两个 url,但由于 OP 在评论中要求提供基于非 promise 的版本,所以我提供了新的代码片段。 看看:
function getBothURLs(callback){
var current = window.location.href;
var win = window.open("https://whosebug.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}`);
})