Javascript 将jQuery从Safari扩展注入网页

Javascript 将jQuery从Safari扩展注入网页,javascript,jquery,safari,safari-extension,Javascript,Jquery,Safari,Safari Extension,我只想将jQuery从safari扩展注入网页。但仅限于某些页面,因为将jQuery添加为start-/endscript会将其注入所有页面,这会导致浏览速度变慢。 我尝试使用其onload函数创建脚本标记: var node = document.createElement('script'); node.onload = function(){ initjquerycheck(function($) { dosomethingusingjQuery($);

我只想将jQuery从safari扩展注入网页。但仅限于某些页面,因为将jQuery添加为start-/endscript会将其注入所有页面,这会导致浏览速度变慢。 我尝试使用其onload函数创建脚本标记:

var node = document.createElement('script');    
node.onload = function(){
    initjquerycheck(function($) {
        dosomethingusingjQuery($);
    });
};
node.async = "async";
node.type = "text/javascript";
node.src = "https://code.jquery.com/jquery-2.0.3.min.js";
document.getElementsByTagName('head')[0].appendChild(node);
要检查是否加载了jquery,我使用:

initjquerycheck: function(callback) {
    if(typeof(jQuery) != 'undefined'){
        callback(jQuery);
    }else {
        window.setTimeout(function() { initjquerycheck(callback); }, 100);
    }
}
但是typeof(jQuery)仍然没有定义。(使用console.log()检查了这一点)。
只有当我从调试控制台调用console.log(typeof(jQuery))时,它才会返回“function”。有没有办法解决这个问题?提前谢谢

扩展注入脚本无法访问网页的JavaScript命名空间。注入的脚本创建一个
元素并将其添加到页面的DOM中,但是脚本实例化的
jQuery
对象属于页面的名称空间,而不是注入的脚本的名称空间

至少有两种可能的解决方案。第一,使用扩展API以正常方式将jQuery注入页面。只有当您所针对的网页可以使用URL模式进行分类时,此方法才可行

第二,用于在注入的脚本和网页名称空间之间进行通信。您需要将另一个
添加到页面中,并在该脚本中为
消息
事件提供一个侦听器。监听器将能够使用jQuery,就好像它是页面本身的“本机”一样

如果需要,这里有一些代码可以帮助您开始

在扩展注入脚本中:

var s0 = document.createElement('script');
s0.type = 'text/javascript';
s0.src = 'https://code.jquery.com/jquery-2.0.3.min.js';
document.head.appendChild(s0);

var s1 = document.createElement('script');
s1.type = 'text/javascript';
s1.src = safari.extension.baseURI + 'bridge.js';
document.head.appendChild(s1);

window.addEventListener('message', function (e) {
    if (e.origin != window.location.origin)
        return;
    console.log(e.data);
}, false);

window.postMessage('What jQuery version?', window.location.origin);
在bridge.js中:

window.addEventListener('message', function (e) {
    if (e.origin != window.location.origin)
        return;
    if (e.data == 'What jQuery version?') {
        e.source.postMessage('Version ' + $.fn.jquery, window.location.origin);
    }
}, false);

您能否扩展第一个选项(“以正常方式将jQuery注入页面”),您的意思是通过
addContentScriptFromURL
?此外,如果注入的脚本具有不同的命名空间,它如何访问
窗口
对象(即,它如何访问
窗口
,而不是
$
)?它似乎本质上是在向自己发送消息。@meleyal,是的,我的意思是
addContentScript
addContentScriptFromURL
。关于注入脚本如何访问窗口对象,在我看来,注入脚本和页面自己的脚本的行为就像它们驻留在两个不同的窗口中一样;人们可能会认为它们是虚拟窗口,恰好占用了浏览器中的相同空间。但是这些虚拟窗口共享相同的位置和来源,这就是为什么一个脚本可以向另一个虚拟窗口发送消息的原因。(它们也共享相同的DOM,但这与消息传递无关。)