Почему script.onload не работает в пользовательском скрипте Chrome?
Я хочу загрузить другой файл скрипта на сайт, используя скрипт пользователя. Но 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 консоль выводит "undefined", но load.js загрузился полностью.
Я проверил это в Firefox, и он выводит A
правильно.
1 ответ
Никогда не используйте .onload
, .onclick
и т. д. из пользовательского сценария. (Это также плохая практика на обычной веб-странице).
Причина в том, что пользовательские сценарии работают в изолированной программной среде ( "изолированном мире"), и вы не можете устанавливать или использовать объекты javascript области страницы в пользовательском сценарии Chrome или сценарии содержимого.
Всегда используйте addEventListener()
(или эквивалентная библиотечная функция, такая как jQuery .on()
). Кроме того, вы должны установить load
слушатели перед добавлением <script>
узлы в DOM.
Наконец, если вы хотите получить доступ к переменным в области видимости страницы (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.
}
... ...