2013-10-05 40 views
2

我只想將jQuery注入Safari瀏覽器擴展的網頁中。但僅限於某些頁面,因爲將jQuery添加爲start/endscript會將其注入到所有頁面,這會導致瀏覽速度變慢。 我嘗試了通過創建使用其的onload功能的腳本標籤:從Safari擴展中注入jQuery到網頁

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'。任何想法如何解決這個問題?提前致謝!

回答

4

擴展插入的腳本無法訪問網頁的JavaScript名稱空間。您的注入腳本創建一個<script>元素並將其添加到頁面的DOM中,但該腳本實例化的jQuery對象屬於該頁面的名稱空間,而不是您的注入腳本。

至少有兩種可能的解決方案。一,使用擴展API以正常方式將jQuery注入頁面。如果您要定位的網頁可以使用網址格式進行分類,則此方法纔可行。

二,使用Window.postMessage在注入的腳本和網頁的名稱空間之間進行通信。您需要在頁面中添加另一個<script>,並在此腳本中爲message事件設置偵聽器。監聽器將能夠使用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); 
+0

你能在第一個選項擴展( 「jQuery注入的頁面以正常的方式」),你意思是通過'addContentScriptFromURL'? – meleyal

+0

另外,如果注入的腳本有不同的命名空間,它如何訪問'window'對象(即如何訪問'window'而不是'$')?它似乎本質上是發佈消息。 – meleyal

+1

@meleyal,是的,我的意思是'addContentScript'和'addContentScriptFromURL'。關於注入的腳本如何訪問窗口對象,在我看來,注入的腳本和頁面自己的腳本就好像它們居住在兩個不同的窗口中一樣;人們可能會認爲它們是碰巧在瀏覽器中佔據相同空間的虛擬窗口。但是這些虛擬窗口共享相同的位置和來源,這就是爲什麼一個腳本可能將消息發送到另一個虛擬窗口的原因。 (他們也共享相同的DOM,但這與消息傳遞的目的不相關。) – canisbos