使用第三方库

我想在我的chrome扩展中集成一个时间轴 。 我已经下载了这个插件的js文件和css文件,并将它们放在我的chrome扩展的根目录中。

chrome扩展本身就是向现有页面注入JS并修改html代码 。 但是,当我尝试使用该库时,我将收到错误消息:

Uncaught ReferenceError: vis is not defined at addTimeLine (ui.js:230) at createClientBox (ui.js:270) at ui.js:62 

这是我的manifest.json:

  "content_scripts": [{ "matches": ["https://web.whatsapp.com/*"], "css":["vis.min.css"], "js": ["content.js","jquery-3.2.1.min.js","vis.min.js"], "run_at": "document_end" }], "permissions": [ "activeTab" ], 

这里是content.js:

 function injectJs(link) { var scr = document.createElement("script"); scr.type="text/javascript"; scr.src=link; (document.head || document.body || document.documentElement).appendChild(scr); } //injectJs(chrome.extension.getURL("/vis.min.js")); injectJs(chrome.extension.getURL("/ui.js")); 

执行content.js后, ui.js成功注入页面,我在页面上看到了我添加的按钮。 现在,当我想使用这样的库时:

  var addTimeLine = function () { var visualization = document.createElement('div'); visualization.id = 'visualization'; // Get the conatiner where the timeline should be displayed var container = document.getElementById('visualization'); // Create a DataSet (allows two way data-binding) var items = new vis.DataSet([{ id: 1, content: 'item 1', start: '2013-04-20' }, { id: 2, content: 'item 2', start: '2013-04-14' }, { id: 3, content: 'item 3', start: '2013-04-18' }, { id: 4, content: 'item 4', start: '2013-04-16', end: '2013-04-19' }, { id: 5, content: 'item 5', start: '2013-04-25' }, { id: 6, content: 'item 6', start: '2013-04-27' } ]); // Configuration for the Timeline var options = {}; // Create a Timeline var timeline = new vis.Timeline(container, items, options); }; addTimeLine(); 

我将收到上述错误消息。

在Chrome扩展程序中成功使用第三方库,我错过了什么?

您错过了孤立上下文的重点以及它与动态元素的交互方式。

每个页面都包含一个DOM结构和它自己的JavaScript执行上下文,即“页面”上下文。

当扩展程序向页面添加内容脚本时,它会创建一个单独的 JavaScript上下文,并附加到同一个DOM。 这两个上下文没有看到对方:如果你有一个变量在一个,它不存在于另一个。 这包括全局对象,如window :每个上下文都有自己的副本。

这种隔离的主要原因是:

  • 安全性:页面不会干扰更高权限的内容脚本上下文,也无法直接检测其存在。
  • 方便:页面上下文和扩展可以使用不同的不兼容库; 页面上下文可以使用没有冲突的任何名称; 等等

您的代码创建了一个内容脚本上下文,并将content.jsjquery-3.2.1.min.jsvis.min.js到它(按特定顺序,如果content.js期望任何图书馆)。

但接下来发生的是您创建一个新的DOM脚本节点并在那里添加您的脚本。 这将在页面上下文中执行。

所以,在你的情况下, ui.js会加载某个没有加载ui.js地方,导致错误; 同样,如果您尝试从内容脚本上下文中使用ui.js ,则不会在那里加载它。

如果您最初尝试解决的问题是动态内容脚本注入,则有2个选项:

  1. 使用后台页面,可以根据需要从content.js执行chrome.tabs.executeScript - 这会添加到相同的上下文中。
  2. (核选项)获取脚本和eval()内容,这在内容脚本中是允许的(但在发布时可能会导致审查问题)。

如果您需要从页面上下文访问数据, 需要跨越边界 ,但您需要了解它以及如何通过它传递消息 。