Почему script.onload не работает в учетной записи Chrome?

Я хочу загрузить еще один файл script на сайт с помощью usercript. Но событие js.onload работает некорректно.

Файл usercript:

// ==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 консоль выводит "undefined", но load.js полностью загружен.

Я тестировал его в Firefox, и он правильно выводит A.

Ответ 1

Никогда не используйте .onload, .onclick и т.д. из usercript. (Это также плохой опыт на обычной веб-странице).

Причина заключается в том, что пользовательские скрипты работают в изолированной среде (изолированный мир), и вы не можете устанавливать или использовать объекты javascript для области страницы в пользовательском документе или содержимом Chrome - script.

Всегда используйте addEventListener() (или эквивалентную библиотечную функцию, например jQuery .on()). Кроме того, перед добавлением узлов <script> в DOM следует установить load прослушиватели.

Наконец, если вы хотите получить доступ к переменным в области страниц (A в этом случае), вы должны ввести код, который делает это. (Или вы можете переключиться на Tampermonkey и использовать unsafeWindow, но Chrome 27 вызывает проблемы с этим.

Используйте что-то вроде:

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.
}

... ...