使用第三方库

时间:2017-12-13 11:48:29

标签: javascript jquery google-chrome google-chrome-extension

我想在我的Chrome扩展程序中集成Timeline。我已经下载了这个插件的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扩展程序中成功使用第三方库,我错过了什么?

1 个答案:

答案 0 :(得分:2)

您错过了isolated contexts的重点以及它与动态<script>元素的互动方式。

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

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

这种隔离的主要原因是:

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

您的代码会创建一个内容脚本上下文,并向其添加content.jsjquery-3.2.1.min.jsvis.min.js(按特定顺序,如果content.js需要任何内容​​,则可能会出现问题的图书馆。)

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

因此,在您的情况下,ui.js会加载vis.min.js未加载的地方,从而导致错误;同样,如果您尝试使用内容脚本上下文中的ui.js,则不会在那里加载它。

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

  1. 使用一个后台页面,可以根据chrome.tabs.executeScript的需要执行content.js - 这会增加相同的上下文。
  2. (核选项)获取脚本的内容和eval()内容脚本中允许的内容(但在发布时可能会导致审核问题)。
  3. 如果您需要访问网页上下文中的数据,需要cross the boundary,但您需要了解它以及如何pass messages through it