如何使用书签脚本避免弹出窗口拦截器

13

我编写了一个书签工具,可以快速将选定的文本使用Google翻译在弹出窗口中进行翻译:

javascript:(function(){
    var text = encodeURI(document.getSelection());
    if (!text.length) {
        text = prompt('Texto')
    }
    var url = 'http://translate.google.com/translate_t?hl=&ie=UTF-8&text=' + text + ' &sl=es&tl=pt#';
    window.open(url,'trans','left=20,top=20,width=1000,height=500,toolbar=0,location=0,resizable=1');
})();

然而,Firefox弹窗拦截器不允许新窗口被打开。我可以为每个使用弹窗的网站添加例外,但这可能会非常烦人...

我以为书签脚本可以打开弹窗窗口 - 实际上,很多脚本都可以做到,对吗?我做错了什么吗?还是不可能实现?

4个回答

13

有另一种绕过弹出窗口拦截器的方法,可以先在页面上叠加一个链接,然后允许用户单击该链接生成弹出窗口。书签脚本JavaScript可以存储在单独的文件中。这就是Pinterest的书签脚本如何实现的。首先,他们从页面中选择图像并直接覆盖在页面上。然后,当用户点击选择其中一张照片时,弹出窗口会出现。因为此操作是由用户发起的,所以弹出窗口有效。

以下是可用于测试的代码:

将此代码放入名为bookmarklet.js的文件中:

var popupProperties='width=600,height=400,toolbar=0,location=0,resizable=1';
var newA = document.createElement("a");
var url = 'http://www.stackoverflow.com';
newA.setAttribute("href","javascript:window.open(url,'Hi',popupProperties);");
newA.setAttribute("style","position:fixed;z-index:9999999;top:0;left:0;width:100px;height:100px;color:#000;background:#fff;display:block;");
var newT = document.createTextNode("Open this");
newA.appendChild(newT);
document.body.appendChild(newA);

然后你的书签链接可以像这样:

javascript:var jsCode = document.createElement('script');jsCode.setAttribute('src', 'http://localhost/bookmarklet.js?r='+Math.random()*99999999);document.body.appendChild(jsCode);

或者,你需要将弹出窗口包含在实际的书签链接中。这意味着用户要进行任何更改,唯一的方法就是重新安装书签。

编辑:除了上面的方法,我后来发现使用easyXDM甚至有另外一种绕过此问题的方式。它可以帮助你绕过同源策略。 http://easyxdm.net/wp/

使用它,你可以为你的书签使用一个iframe,甚至可以在你的iframe内部拥有一个“关闭”链接,以便能够从父页面中删除iframe。


1
你甚至可以在 anchor 上添加一个 ID 并做一些花里胡哨的事情,如 document.getElementById('myid').click(),就可以直接触发它(这里有一些灰色地带...)。Native DOM .click 很难找到支持文档,但现代 Chrome 和 FF 在我的简短测试中都能正常工作。 - Alex Mcp

7

防止浏览器提示弹出窗口拦截的一种方法是将JavaScript完全包含在锚标签中。

一旦引用了另一个文件,它显然会触发浏览器的弹出窗口拦截器。

例如,当用户将锚点拖动到其浏览器的书签栏时,以下代码不会触发弹出窗口拦截器:

<a href="javascript:window.open('http://tagsby.me/index.small.php','newWindowName','width=960,height=400,scrollbars=yes,status=no,titlebar=no,toolbar=no');void(0);">No blocker</a>

然而,如果你在另一个文件 noblocker.js 中引用相同的代码,并将其附加到用户当前访问的站点的文档对象中:

<a id="tbm" class="testing" href="javascript:(function(){document.body.appendChild(document.createElement('script')).src='http://domain.com/noblocker.js';})();">

这将触发弹出窗口拦截器。可能还有其他方法,但这是我现在在http://tagsby.me网站上运行的方法。


你有没有想到其他的方法?我发现Pinterest通过他们的“Pin it”书签管理非阻塞弹出窗口,即使它是通过远程JavaScript文件调用的 - 在http://pinterest.com/about/goodies/上实时检查一下。 - gwendall

1

有趣的问题,我的直觉告诉我这是不可能的,因为浏览器不一定会跟踪哪些代码试图打开新窗口,所以它不能 '允许' 它,因为它来自 X 网站。

我认为更好的选择是在同一窗口中以对话框的形式打开内容。查看如何实现 jQuery 书签并且剩下的应该很直接:

http://www.latentmotion.com/how-to-create-a-jquery-bookmarklet/


这很奇怪,因为有人说在这里可能是可行的:stackoverflow.com/q/4048008/287976。然而,我尝试使用一个我认为可以做到这一点的书签小工具(用于在Delicious上保存链接的书签小工具):首先它失败了,然后它只是改变了文档的位置...这很不幸,因为我真的想在另一个窗口中打开它...也许我会尝试jQuery,但我敢打赌,对于我想要翻译一些文本的一些常见网站,添加一些例外就足够了... - brandizzi

-2
弹出窗口拦截器有添加例外的功能。也许可以尝试为translate.google.com添加一个例外。
(工具菜单->选项->内容部分)

1
实际上,它不起作用是因为包含内容的网站被视为源网站。例如,如果我要求它翻译 es.wikipedia.org 上的一个单词,我应该将 es.wikipedia.org 添加到例外列表中,并对任何其他网站执行相同操作... - brandizzi
抱歉,我不知怎么错过了你的 OP 的那一部分。 - horatio
实际上,我是在发布后添加的,但是没有看到你的建议。所以没关系 :) - brandizzi
原始帖子/原始发布者 - horatio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接