如何在没有“不安全窗口”的情况下编程
How to program without "unsafeWindow"?
在我的Greasemonkey脚本中,我想重写一个仍然存在于网页中的函数。
所以我使用这个JavaScript代码:
var oldDoWork = DoWork;
unsafeWindow.DoWork = function()
{
// Do some new work
...
oldDoWork(); // Call the old function
}
。
但是这种方法有两个问题:
-
unsafeWindow
功能是一个安全问题,来自Greasemonkey说。 - 在这个新函数中,我们不能使用
GM_getValue
和GM_setValue
。使用计时器的解决方案会导致异步作业的一些其他问题。
如何在不使用unsafeWindow
的情况下管理上述代码?
要避免使用unsafeWindow,您可以使用:
location.assign("javascript:YOUR_CODE_GOES_HERE");
但是这也不允许你使用GM_*函数。
使用GM_* "out of the GM scope"的唯一方法是使用计时器。
所以基本上,你的问题的答案是:你的方法是正确的,你只是无能为力。
如果你的函数没有返回任何东西,那么我建议你使用location.assign
如果您想避免unsafeWindow
,请将与页面的JS交互的代码注入到页面中。参见addJS_Node()
要从这些事件中触发GM_函数,应该能够通过:进行交互。
-
编写节点并监听
DOMSubtreeModified
(在W3C规范中已弃用)。但是,FF/GM的一个bug现在阻止了这一点。 -
发送自定义事件。同样,GM/FF的bug和功能现在阻止了这一点。请注意,例如,当用户物理单击时,
click
事件可以调用使用GM_函数的代码。但是,以编程方式生成相同的单击事件,它会失败,并出现"Greasemonkey access violation: unsafeWindow cannot call..."
错误。
unsafeWindow
,如果你愿意:
//--- Put everything that goes into the main page, inside myJS().
function myJS () {
window.oldDoWork = DoWork;
window.DoWork = function() {
// Do some new work
callGM_setValue ("From target page", "some value");
window.oldDoWork(); // Call the old function
}
function callGM_setValue (varName, varValue) {
//--- Generate and dispatch a synthetic event.
var zEvent = document.createEvent ("CustomEvent");
zEvent.initCustomEvent (
"messageToGM_setvalue", true, false,
{Name: varName, Value: varValue}
);
document.body.dispatchEvent (zEvent);
}
}
document.body.addEventListener (
"messageToGM_setvalue", fireGM_setValue, false
);
function fireGM_setValue (zEvent) {
/*--- setTimeout remains one of the few things that can cleanse
the calling tree of it's "unsafe" origins.
*/
setTimeout (function() {
GM_setValue (zEvent.detail.Name, zEvent.detail.Value);
}, 0);
}
addJS_Node (null, null, myJS);
function addJS_Node (text, s_URL, funcToRun) {
var D = document;
var scriptNode = D.createElement ('script');
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = '('
+ funcToRun.toString()
+ ')()';
var targ = D.getElementsByTagName('head')[0]
|| D.body
|| D.documentElement;
targ.appendChild (scriptNode);
}
相关文章:
- JavaScript-在手机上不工作的情况下,在外部单击时隐藏元素
- 使用php脚本验证访问者的年龄,并在不刷新的情况下根据结果加载iframe
- 切换菜单仅在单击时打开,而不是默认情况下打开
- 如何在不滚动的情况下将 PDF 嵌入到真实大小的网站上
- 如何在不刷新的情况下停止类的事件
- 在不__proto__的情况下配置 [[原型]] 链
- 如何动态设置填充并在不刷新的情况下显示它
- 如何在不停止的情况下永远运行node-js
- 如何在不覆盖的情况下添加同一JPanel类的不同实例
- 在不渲染的情况下计算字符串大小
- Cant在不刷新的情况下进行多个插入
- knightlab timeline js-如何在不重叠的情况下显示事件
- jquery:如何在不滚动的情况下跳转到位置
- 如何在不强制的情况下添加条件文本?[101,pdf格式]
- 在不刷新的情况下无法删除最近创建的cookie
- 如何在加载时仅在用户自己不滚动的情况下滚动页面
- 如何在不闪烁的情况下加载Iframe
- 在不刷新的情况下跟踪某个正方形中的地图标记
- 在不提交的情况下验证表单
- 如何在没有“不安全窗口”的情况下编程