使用第三方库 [英] Using third party libraries

查看:167
本文介绍了使用第三方库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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

 未捕获的ReferenceError:vis未定义
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
}],
权限:[
activeTab

这里的content.js :

 函数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';
//获取应该显示时间轴的conatiner
var container = document.getElementById('visualization');

//创建一个DataSet(允许双向数据绑定)
var items = new vis.DataSet([{
id:1,
content:'项目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',
结束:'2013-04-19'
},
{
id:5,
content:'item 5',
start:'2013-04 -25'
},
{
id:6,
content:'it em 6',
start:'2013-04-27'
}
]);

//时间轴配置
var options = {};

//创建时间轴
var timeline = new vis.Timeline(container,items,options);
};

addTimeLine();

我会收到上述错误讯息。

<

解决方案

您错过了在chrome扩展中成功使用第三方库的意义。 独立的上下文以及它如何与动态交互<脚本> 元素。



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

当扩展将内容脚本添加到页面时,它会创建一个独立的 JavaScript上下文,并附加到相同的DOM。这两种情况彼此没有看到:如果你有一个变量,它不在另一个中。这包括全局对象,如 window :每个上下文都有自己的副本。



这种隔离的主要原因是:


  • 安全性:页面不会干扰较高权限的内容脚本上下文,并且无法直接检测其存在。

    li>
  • 方便性:页面上下文和扩展可以使用不同的不兼容库;页面上下文可以使用任何没有冲突的名称;您的代码创建一个内容脚本上下文,并添加 content.js
  • jquery-3.2.1.min.js vis.min.js (以特定顺序,如果content.js需要任何库,这本身可能会成为一个问题)。



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



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



    <如果您原本试图解决的问题是动态内容脚本注入,那么您有两种选择:


    1. 使用背景页面,可以根据需要从 content.js 执行 chrome.tabs.executeScript - 这会添加到相同的上下文中。

    2. (核心选项)获取脚本的内容和 eval()它们,这在内容脚本中是允许的(但可能会在审阅时导致问题如果您需要访问页面上下文中的数据,您 需要 href =https://stackoverflow.com/questions/9515704/insert-code-into-the-page-context-using-a-content-script>跨越边界,但你需要知道关于它以及如何通过它传递消息


      I want to integrate a Timeline in a chrome extension of mine. I already downloaded the js files and css files of this addon and put them in the root directory of my chrome extension.

      The chrome extension itself is just the injection of a JS to an existing page and modifying the html code. However when I try to use the library I will get the error message:

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

      Here is my 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"
        ],
      

      Here the 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"));
      

      After the content.js is executed the ui.js is successfully injected to the page and I see my added button on the page. Now when I want to use the library like this:

          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();
      

      I will get the above error message.

      What point am I missing to successfully use third party libraries in a chrome extension?

      解决方案

      You're missing the point of isolated contexts and how it interacts with dynamic <script> elements.

      Each page contains a DOM structure and its own JavaScript execution context, the "page" context.

      When an extension is adding a content script to a page, it creates a separate JavaScript context, attached to the same DOM. The two contexts don't see each other: if you have a variable in one, it's not present in the other. This includes global objects such as window: each context gets its own copy.

      The main reason for this isolation are:

      • Security: the page can't interfere with a higher-privilege content script context and can't detect its presence directly.
      • Convenience: the page context and the extension can use different incompatible libraries; a page context can use any names without clashes; etc.

      Your code creates a content script context and adds content.js, jquery-3.2.1.min.js and vis.min.js to it (in that specific order, which may be a problem in itself if content.js expects any of the libraries).

      But what happens next is that you create a new DOM script node and add your script there. This gets executed in the page context instead.

      So, in your situation, ui.js loads somewhere that vis.min.js isn't loaded, leading to the error; likewise, if you try to use ui.js from the content script context, it won't be loaded there.

      If the problem you were originally trying to solve was dynamic content script injection, you have 2 options:

      1. Employ a background page, which can execute chrome.tabs.executeScript on demand from content.js - this adds to the same context.
      2. (Nuclear option) Get contents of your script and eval() them, which is allowed in content scripts (but may cause problems with review when publishing).

      If you need to access data from the page context, you will need to cross the boundary, but you need to be aware about it and how to pass messages through it.

      这篇关于使用第三方库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆