Safari扩展:全新标签的活动?

Kev*_*vin 3 javascript safari javascript-events safari-extension

我希望将Safari中的新标签重定向到某个URL,实质上是更改默认的新标签页.但是,我不想重定向通过以下链接打开的新选项卡.

窗口和标签API描述标签"开放"的事件,但是当这些被解雇的任何新标签页中打开(包括新的标签从链接打开).

有没有办法只为那些通过单击新选项卡按钮创建的选项卡捕获新的选项卡事件?

提前致谢!

chu*_*ter 7

open事件处理程序中,首先检查事件目标是否为选项卡.如果是,请beforeNavigate在该选项卡上注册事件的事件处理程序.如果beforeNavigate事件未在50毫秒内触发,也设置超时以取消注册处理程序.例如:

function handleOpen(e) {
    if (e.target instanceof SafariBrowserTab) {
        e.target.addEventListener('beforeNavigate', handleBeforeNavigate, false);
        setTimeout(function () {
            e.target.removeEventListener('beforeNavigate', handleBeforeNavigate, false);
        }, 50);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,在beforeNavigate制表符打开事件之后,事件有三个相关的可能结果.

案例1:beforeNavigate事件不会在超时内触发.这通常意味着选项卡为空.一个空的选项卡不能是链接点击的结果,所以我们可以在超时函数中放入一些代码来做我们喜欢的任何事情:

function handleOpen(e) {
    if (e.target instanceof SafariBrowserTab) {
        e.target.addEventListener('beforeNavigate', handleBeforeNavigate, false);
        setTimeout(function () {
            e.target.removeEventListener('beforeNavigate', handleBeforeNavigate, false);
            takeOverTab();
        }, 50);
    }
}
Run Code Online (Sandbox Code Playgroud)

案例2:beforeNavigate事件将触发,其url属性的值为null.这意味着该选项卡将加载"热门站点"页面或"书签"页面(两个特殊的Safari页面,这些页面是新选项卡的选项之一).就像一个空标签一样,这样的标签不可能是链接点击的结果,所以我们可以用标签做我们喜欢的事情.例如:

function handleBeforeNavigate(e) {
    e.target.removeEventListener('beforeNavigate', handleBeforeNavigate, false);
    if (e.url === null) {
        takeOverTab();
    }
}
Run Code Online (Sandbox Code Playgroud)

情况3:beforeNavigate将触发,其url值将是非空字符串:即实际URL.这是一个棘手的情况,因为选项卡可能来自链接点击,new-tab命令(如果用户已配置Safari以打开其主页的新选项卡),或另一个应用程序或扩展的操作.让我们调用选项卡是链接点击案例3A的结果的情况; 案例3B,它是new-tab命令的结果; 和其他应用案例,案例3C.

我想不出区分3B和3C的方法.如果真的无法区分这两种情况,那么对于您的应用来说可能非常糟糕,因为您可能不希望重定向其他应用打开的标签.

如果您不关心您的应用程序是否干扰3C选项卡,则至少有一种方法可以告知3B/3C选项卡中的3A选项卡.这是我发生的方式:

  • 在每个页面中使用注入的脚本来监听链接点击.单击链接时,将URL和点击时间转发到全局页面,这将记住它们以供将来参考.例如:

    function handleMessage(e) {
        if (e.name === 'linkClicked') {
            lastClickedLinkUrl = e.message.url;
            lastLinkClickTime = e.message.clickTime;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 在您的beforeNavigate处理程序中,测试事件的url值是否与最后单击的链接的URL不同.如果是,则新选项卡不是由该链接单击产生的,因此它可能不是由任何链接点击产生的.如果两个URL相同,请检查自上次链接点击以来是否超过100毫秒.如果是这种情况,那么URL可能只是巧合,因此您可以再次推断新选项卡不是来自链接点击.例如:

    function handleBeforeNavigate(e) {
        e.target.removeEventListener('beforeNavigate', handleBeforeNavigate, false);
        if (e.url === null) {
            takeOverTab();
        } else if (e.url !== lastClickedLinkUrl || (new Date) - lastLinkClickTime > 100) {
            takeOverTab();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

请注意,这种检测方法并非万无一失.可能有很多方法可能会出错.不过,我希望这会有所帮助.