2015-07-21 142 views
0

我创建了一个自定义Polymer元素,并试图在我的Chrome扩展中使用它。但是,我遇到了以下问题。Chrome扩展内容脚本中的聚合物元素

我无法从内容脚本访问元素的API。这是我的意思。

我的元素的模板

<link rel="import" href="../polymer/polymer.html"> 
<dom-module id="my-element"> 
<template> 
... some html... 
</template> 
<script src="js/my-element.js"></script> 
</dom-module> 
我-element.js

Polymer({ 
    is: 'my-element', 
    init: function() { 
    console.log('init'); 
    } 
}); 
在content.js

var link = document.createElement('link'); 
link.setAttribute('rel', 'import'); 
link.setAttribute('href', chrome.extension.getURL('my-element.html')); 
link.onload = function() { 
    var elem = document.createElement('my-element'); 
    document.body.appendChild(elem); 
    elem.init(); // Error: undefined is not a function 
}; 
document.body.appendChild(link); 

有趣的是,我可以看到my-element是所有这些都是阴影和事情。如果我在主机网页的控制台中运行document.querySelector('my-element').init(),它将无误地执行。但是,在内容脚本中执行相同的代码会产生错误。

我试过将聚合物本身作为内容脚本。我碰到registerElement的问题,但我解决了它,这要归功于this的问题。在这种情况下,我在我的content.js中定义了window.Polymer。我的元素的API变得完全可访问,但现在当我将它附加到主机网页的DOM时,它不会被渲染。

+0

我不认为浏览器由于沙箱而在正常的http/https页面上遵循'chrome-extension://'链接,至少这样的链接在这里不起作用。您是否在清单中通过[web_accessible_resources](https://developer.chrome.com/extensions/manifest/web_accessible_resources)公开了'my-element.html'? – wOxxOm

+0

是的,我在我的清单中暴露了'my-element.html'和所有相关的css文件。该元素实际上被渲染,它的方法和用'Polymer({...})声明的属性可以通过'document.querySelector()'访问,但只能从主机网页访问,而不能从内容脚本访问。我想我应该不知何故在内容脚本中声明'my-element',但我不知道如何。 – optimistiks

回答

3

你打你的内容脚本的沙箱:

内容脚本在一个特殊的环境中执行所谓的孤立 世界。他们可以访问他们注入到的页面的DOM, 但是不是由该页面创建的任何JavaScript变量或函数。 它看起来像每个内容脚本一样,没有其他JavaScript 正在其上运行的页面上执行。反过来也是如此: 页面上运行的JavaScript不能调用任何函数,也不能访问由内容脚本定义的任何 变量。

https://developer.chrome.com/extensions/content_scripts#execution-environment

的聚合物组分的脚本运行在主机页面,所以它是不可见的内容脚本。

您可以在主机页面中注入一个新的脚本标记,并从扩展中的.js文件中获取源代码。

var script = document.createElement('<script>'); 
script.src = chrome.extension.getURL('something.js'); 
document.appendChild(script); 

这将在主机页面的上下文中运行something.js,授予其访问的主机页面的所有其他脚本(包括您的聚合物成分),但也使得它无形到您的内容脚本。请特别注意在主页面注入脚本的security implications

如果您不能/不愿意将所有扩展逻辑推送到该注入的脚本中,例如因为您需要访问chrome.* API或主机页面和内容脚本之间的某种其他类型的通信,请查看message posting

+1

我在想那个。我终于决定转移到x-tag库。它具有更简洁明了的声明元素的方式,并且可以轻松地将库插入到内容脚本的作用域中,因为它作为.js文件提供。 – optimistiks

+0

通过这种方式,我无需将内容脚本中的所有逻辑移动到注入的主机脚本,也无需考虑可能存在的库冲突(例如,如果Polymer已包含在主机页面中,该怎么办)。 – optimistiks