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,因为它会返回一个承诺。