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



使用 Firefox 34 和插件 SDK 1.17。

我正在使用SDK的页面模组来附加内容脚本。在内容脚本中,我在尝试访问 DOM 元素时看到了非常奇怪的行为。

主.js

pageMod.PageMod({
    include: "somewebsite",
    contentScriptWhen: 'end',
    contentScriptFile: [data.url("stuff.js")]
});

东西.js

log(document.getElementsByTagName("body")); // empty object
log(document.getElementById("SomeIdThatShouldBeThere")); // empty object
log(document.getElementsByTagName("li")); // x amount of empty objects...

但是,这将按预期工作:

document.body.style.border = "5px solid red";

对于我得到的空对象,我可以做

obj.style.border = ...

它将起作用,HTML 元素可以看到更改边框颜色等。但是我无法读取元素的属性,所以我是盲目的工作。

我读过有人说从内容脚本修改 DOM 有一些限制,但我显然甚至无法做最基本的事情。那么这应该得到支持吗?

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

如果要

将对象从 dom 输出到控制台,请使用:

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并添加值为"all"的首选项"extensions.sdk.console.logLevel"即可,因此您可以记录所需的任何消息。

但是,如果您还运行 sdk cmd 控制台,这将输出错误,但我认为这没什么可担心的,所有代码都可以毫无问题地执行。

编辑:当我将其映射到var日志时才发现,如果Firebug控制台未打开,则会导致附加组件停止工作,并且在打开Firefox控制台时仍然无法正常工作。但是,做一个海峡不安全的窗口.控制台.log(foo)工作正常。

我遇到了同样的问题。它使基本脚本更加繁琐。

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

"内联脚本注入

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

// 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 与鼠标事件非常相似,不同之处在于它们是以编程方式触发的,并且可以在内容脚本和页面之间双向传输任意(jsonable)数据:

// 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 );
});"

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

function getLoggableObject(obj){
    var loggable={};
    for(var key in obj){
        loggable[key]=obj[key];
    }
    return loggable;
}

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

 console.log("default  : ", $("table")[0]);
 console.log("loggable : ", getLoggableObject($("table")[0]));

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

"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… }

更改:

log(document.getElementsByTagName("body")); // empty object
log(document.getElementById("SomeIdThatShouldBeThere")); // empty object
log(document.getElementsByTagName("li")); // x amount of empty objects...

要这样:

console.log(document.getElementsByTagName("body")); // empty object
console.log(document.getElementById("SomeIdThatShouldBeThere")); // empty object
console.log(document.getElementsByTagName("li")); // x amount of empty objects...

最新更新