首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法访问Firefox附加组件内容脚本中的DOM元素

无法访问Firefox附加组件内容脚本中的DOM元素
EN

Stack Overflow用户
提问于 2014-12-23 01:26:57
回答 4查看 1.1K关注 0票数 4

使用Firefox 34和addon SDK 1.17。

我正在使用SDK的page-mod附加一个内容脚本。在内容脚本中,当我试图访问DOM元素时,我看到了非常奇怪的行为。

main.js

代码语言:javascript
复制
pageMod.PageMod({
    include: "somewebsite",
    contentScriptWhen: 'end',
    contentScriptFile: [data.url("stuff.js")]
});

stuff.js

代码语言:javascript
复制
log(document.getElementsByTagName("body")); // empty object
log(document.getElementById("SomeIdThatShouldBeThere")); // empty object
log(document.getElementsByTagName("li")); // x amount of empty objects...

然而,这将如预期的那样工作:

代码语言:javascript
复制
document.body.style.border = "5px solid red";

另外,对于我可以得到的空对象,我也可以这样做

代码语言:javascript
复制
obj.style.border = ...

它可以工作,html元素可以改变边框颜色等等。但是我不能读取元素的属性,所以我是盲目工作的。

我读到有人说从内容脚本修改DOM有一些限制,但我显然不能做最基本的事情。那么这是否应该得到支持呢?

编辑:最终,我注意到元素位于正确的位置,我可以读取它们的属性,但是记录一个元素仍然只会打印一个空对象……这意味着元素的每个所需属性都必须单独打印。至少它可以工作,但可以做得更好。

EN

回答 4

Stack Overflow用户

发布于 2015-08-09 13:18:21

如果您想将一个对象从dom输出到控制台,请使用:

代码语言:javascript
复制
unsafeWindow.console.log(document.getElementById("SomeIdThatShouldBeThere"));
// Or map it in your contentscript file for less typing
var log = unsafeWindow.console.log;
log(document.getElementById("SomeIdThatShouldBeThere"));

这也不需要进入about:config并添加首选项"extensions.sdk.console.logLevel“和值"all",这样您就可以记录任何您想要的消息。

但是,如果您同时运行sdk cmd控制台,这将输出一个错误,但我不认为这有什么可担心的,所有代码执行都没有问题。

火狐编辑:当我将其映射到日志时,才发现,如果firebug控制台没有打开,它会导致附加组件停止工作,并且在打开firefox控制台时仍然无法工作。但是,做一个简单的unsafeWindow.console.log(foo)可以很好地工作。

票数 1
EN

Stack Overflow用户

发布于 2015-05-10 02:13:05

我也有同样的问题。这使得基本的脚本编写变得更加繁琐。

试试这个(来自http://louisremi.com/2011/12/07/mozilla-addons-interactions-between-content-scripts-and-pages/)

内联脚本注入

正确的方法是在页面中注入内联脚本和/或使用customEvents。内联脚本是第三级脚本,可用于在全局范围内创建变量或函数:

代码语言:javascript
复制
// Quotes nesting would be a real mess now,
// let's use a separate file loaded as a contentScriptFile
var script = document.createElement( "script" );
script.innerHTML = "var test =" + JSON.stringify( anyValue )+";";
document.body.appendChild( script );

验证此代码将输出警告,因为插件不应创建脚本标记。但这仍然是unsafeWindow最安全的替代方案。

customEvents

customEvents与鼠标事件非常相似,除了它们是以编程方式触发的,并且它们可以在内容脚本和页面之间双向传输任意(jsonable)数据:

代码语言:javascript
复制
// inline script in example.com/index.html
var evt = document.createEvent("CustomEvent");
evt.initCustomEvent( "transData", true, false, jsonableValue );
window.dispatchEvent(evt);
// in contentScript.js
window.addEventListener( "transData", function( event ) {
  // the data is available in the detail property of the event
  self.port.emit( "transData", event.detail );
});"
票数 0
EN

Stack Overflow用户

发布于 2015-05-10 02:25:12

我在插件的内容脚本中遇到了同样的问题。出于某种未知的原因,如果您将object的值复制到一个新对象中,则可以将它们打印到控制台。您可以创建一个简单的函数作为变通方法:

代码语言:javascript
复制
function getLoggableObject(obj){
    var loggable={};
    for(var key in obj){
        loggable[key]=obj[key];
    }
    return loggable;
}

下面是调用此函数的示例:

代码语言:javascript
复制
 console.log("default  : ", $("table")[0]);
 console.log("loggable : ", getLoggableObject($("table")[0]));

以及这些日志语句的输出:

代码语言:javascript
复制
"default  : " Object {  }
"loggable : " Object { createCaption: "function createCaption() {
    [native code]
}", deleteCaption: "function deleteCaption() {
    [native code]
}", createTHead: "function createTHead() {
    [native code]
}", deleteTHead: "function deleteTHead() {
    [native code]
}", createTFoot: "function createTFoot() {
    [native code]
}", deleteTFoot: "function deleteTFoot() {
    [native code]
}", createTBody: "function createTBody() {
    [native code]
}", insertRow: "function insertRow() {
    [native code]
}", deleteRow: "function deleteRow() {
    [native code]
}", caption: null, 210 more… }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27607529

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档