69

我正在寫一個Chrome擴展。我想在我的擴展中使用jQuery。我沒有使用任何背景頁面,只是背景腳本如何在Chrome擴展中使用jQuery?

這裏是我的文件:

manifest.json

{ 
    "manifest_version": 2, 

    "name": "Extension name", 
    "description": "This extension does something,", 
    "version": "0.1", 

    "permissions": [ 
     "activeTab" 
    ], 

    "browser_action": { 
     "default_icon": "images/icon_128.png" 
    }, 

    "background": { 
     "scripts": ["background.js"], 
     "persistent": false 
    }, 

    "icons": { 
     "16": "images/icon_16.png", 
     "48": "images/icon_48.png", 
     "128": "images/icon_128.png" 
    } 
} 

background.js文件只運行一個名爲work.js

​​

另一個文件我的分機的主要邏輯是內部work.js。我認爲這個問題的內容並不重要。

我想問的是如何在我的擴展中使用jQuery。由於我沒有使用任何背景頁面。我不能只是將jQuery添加到它。那麼我如何在我的擴展中添加和使用jQuery?

我試着運行jQuery以及來自background.js文件的我的work.js。

// Respond to the click on extension Icon 
chrome.browserAction.onClicked.addListener(function (tab) { 
    chrome.tabs.executeScript({ 
     file: 'thirdParty/jquery-2.0.3.js' 
    }); 
    chrome.tabs.executeScript({ 
     file: 'work.js' 
    }); 
}); 

它工作正常,但我擔心腳本添加是否以這種方式執行異步執行。如果是,那麼可能會發生這樣的情況,即使在 jQuery(或將來我可能添加的其他庫)之前,work.js仍會運行

我也想知道什麼是使用第三方庫的正確和最好的方式,在我的Chrome擴展中。

+2

正確的方法是去香草! – bjb568

+0

如果你在這裏尋找如何將jQuery添加到彈出式擴展(像我一樣),請參閱此問題:http://stackoverflow.com/questions/12035242/loading-jquery-into-chrome-extension –

回答

77

你有你的jQuery腳本添加到您的Chrome擴展項目和您的manifest.json像這樣的background部分:

"background": 
    { 
     "scripts": ["thirdParty/jquery-2.0.3.js", "background.js"] 
    } 

如果您在content_scripts需要的jQuery,你必須將它添加在艙單中:

"content_scripts": 
    [ 
     { 
      "matches":["http://website*"], 
      "js":["thirdParty/jquery.1.10.2.min.js", "script.js"], 
      "css": ["css/style.css"], 
      "run_at": "document_end" 
     } 
    ] 

這就是我所做的。

此外,如果我記得正確,後臺腳本在背景窗口中執行,您可以通過chrome://extensions打開。

+1

'你必須將你的jQuery腳本添加到你的chrome-extension項目',你到底意味着什麼? 我這樣做: 的manifest.json: ' 「背景」:{' ' 「腳本」:[ 「第三方/ jquery的-2.0.3.js」, 「background.js」],' '「persistent」:false' '},' 我已將jQuery下載到thirdParty文件夾。不過,我仍然不能使用jQuery。它給出錯誤:'未捕獲的ReferenceError:$未定義' 我將其添加到我的'work.js'文件中進行測試。 '$(「body」)。html(「Foo!」);' – Ishan

+0

上面的評論看起來像一團糟,但添加評論預覽時未顯示。 請原諒我。 – Ishan

+0

我的意思是將它添加到你的Chrome擴展文件夾。像/home/you/chromexetension_source_files/thirdParty/jquery-2.0.3.js一樣。 你應該對你的work.js做同樣的事情。 – Nico

10

它很容易只是做到以下幾點:

添加下面一行在你mainfest.json

"content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'", 

現在你可以自由的jQuery直接從URL加載

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script> 

來源:google doc

+0

如果您有多個要加載的腳本,該怎麼辦? – another

8

And it works fine, but I am having the concern whether the scripts added to be executed in this manner are being executed asynchronously. If yes then it can happen that work.js runs even before jQuery (or other libraries which I may add in future).

這應該不是一個問題:你排隊要在某個JS上下文中執行的腳本,並且該上下文不能有競爭條件,因爲它是單線程的。

然而,爲了消除這種擔憂的正確方法是鏈上的呼叫:

chrome.browserAction.onClicked.addListener(function (tab) { 
    chrome.tabs.executeScript({ 
     file: 'thirdParty/jquery-2.0.3.js' 
    }, function() { 
     // Guaranteed to execute only after the previous script returns 
     chrome.tabs.executeScript({ 
      file: 'work.js' 
     }); 
    }); 
}); 

或者,概括:

function injectScripts(scripts, callback) { 
    if(scripts.length) { 
    var script = scripts.shift(); 
    chrome.tabs.executeScript({file: script}, function() { 
     if(chrome.runtime.lastError && typeof callback === "function") { 
     callback(false); // Injection failed 
     } 
     injectScripts(scripts, callback); 
    }); 
    } else { 
    if(typeof callback === "function") { 
     callback(true); 
    } 
    } 
} 

injectScripts(["thirdParty/jquery-2.0.3.js", "work.js"], doSomethingElse); 

或者promisified(和符合正確的簽名帶來了更多的):

function injectScript(tabId, injectDetails) { 
    return new Promise((resolve, reject) => { 
    chrome.tabs.executeScript(tabId, injectDetails, (data) => { 
     if (chrome.runtime.lastError) { 
     reject(chrome.runtime.lastError.message); 
     } else { 
     resolve(data); 
     } 
    }); 
    }); 
} 

injectScript(null, {file: "thirdParty/jquery-2.0.3.js"}).then(
() => injectScript(null, {file: "work.js"}) 
).then(
() => doSomethingElse 
).catch(
    (error) => console.error(error) 
); 

或者說,爲什麼赫克沒有,async/await -ed爲更加清晰的語法:

function injectScript(tabId, injectDetails) { 
    return new Promise((resolve, reject) => { 
    chrome.tabs.executeScript(tabId, injectDetails, (data) => { 
     if (chrome.runtime.lastError) { 
     reject(chrome.runtime.lastError.message); 
     } else { 
     resolve(data); 
     } 
    }); 
    }); 
} 

try { 
    await injectScript(null, {file: "thirdParty/jquery-2.0.3.js"}); 
    await injectScript(null, {file: "work.js"}); 
    doSomethingElse(); 
} catch (err) { 
    console.error(err); 
} 

注意,在Firefox中你可以使用browser.tabs.executeScript,因爲它會返回一個承諾。