【问题标题】:Why is script.onload not working in a Chrome userscript?为什么 script.onload 在 Chrome 用户脚本中不起作用?
【发布时间】:2013-05-29 03:32:40
【问题描述】:

我想使用用户脚本在站点中加载另一个脚本文件。 但是,js.onload 事件无法正常工作。

用户脚本文件:

// ==UserScript==
// @name           Code highlight
// @description    Test
// @include        http://localhost/*
// @version        1.0
// ==/UserScript==

var js = document.createElement('script');
    js.src = "http://localhost/test/js/load.js";
    document.getElementsByTagName("head")[0].appendChild(js);
    js.onload = function(){
        console.log(A)
    }

load.js 文件:

var A = {
    name:'aa'
}


在 Chrome 中,控制台输出“未定义”,但 load.js 已完全加载。

我在 Firefox 中测试过,它正确输出了A。

【问题讨论】:

  • 请注意,它仅适用于 FF+Greasemonkey,因为 @grant 默认为 none。一旦你尝试使用任何GM_ API 函数,脚本也会在 FF 上中断。

标签: javascript google-chrome userscripts script-tag


【解决方案1】:

切勿在用户脚本中使用.onload、.onclick 等。(在常规网页中这也是不好的做法)。

原因是用户脚本在沙箱 ("isolated world") 中运行,您无法在 Chrome 用户脚本或内容脚本中设置或使用页面范围的 javascript 对象。

始终使用 addEventListener()(或等效的库函数,如 jQuery .on())。此外,您应该在将 <script> 节点添加到 DOM 之前设置 load 侦听器。

最后,如果您希望访问页面范围内的变量(在这种情况下为A),您必须这样做inject the code。 (或者你可以切换到 Tampermonkey 并使用 unsafeWindow,但 Chrome 27 is causing problems with that。)

使用类似的东西:

addJS_Node (null, "http://localhost/test/js/load.js", null, fireAfterLoad);

function fireAfterLoad () {
    addJS_Node ("console.log (A);");
}

//-- addJS_Node is a standard(ish) function
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
    var D                                   = document;
    var scriptNode                          = D.createElement ('script');
    if (runOnLoad) {
        scriptNode.addEventListener ("load", runOnLoad, false);
    }
    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);
}


或者也许:

addJS_Node (null, "http://localhost/test/js/load.js", null, fireAfterLoad);

function fireAfterLoad () {
    addJS_Node (null, null, myCodeThatUsesPageJS);
}

function myCodeThatUsesPageJS () {
    console.log (A);
    //--- PLUS WHATEVER, HERE.
}

... ...

【讨论】:

  • @BrockAdams scriptNode.addEventListener ("load", runOnLoad, false); 什么是假的?
  • @viditjain,见the documentation。在这种情况下,添加显式 , false 是一种编码风格选择。
猜你喜欢
  • 2011-02-05
  • 2013-05-23
  • 1970-01-01
  • 2011-10-19
  • 1970-01-01
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
  • 2016-05-17
相关资源
最近更新 更多