JavaScript bookmarklet代码,用于获取从当前选项卡启动的选项卡的URL

时间:2017-08-26 08:22:19

标签: javascript url tabs bookmarklet

我正在尝试开发一个书签。小书签的目的是显示当前选项卡和由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()时,currentURLnewWin都有有效数据。

如何修改函数getBothURLs()以达到预期目的?

1 个答案:

答案 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}`); })

更新1:

此示例代码段使用可以返回两个网址的非承诺回调版本。虽然,可以修改promise版本以返回两个URL,但由于OP在评论中要求基于非承诺的版本,所以我提供了新的代码片段。 看看:

<select ng-model='names.productionType' ng-options="data for data in productionType"></select>