使用Firefox 34和插件SDK 1.17。
我正在使用SDK的page-mod来附加内容脚本。在内容脚本中,我在尝试访问DOM元素时看到了非常奇怪的行为。
main.js
pageMod.PageMod({
include: "somewebsite",
contentScriptWhen: 'end',
contentScriptFile: [data.url("stuff.js")]
});
stuff.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有一些限制,但我显然无法做到最基本的事情。这应该得到支持吗?
编辑:最后我注意到元素在正确的位置并且我可以读取它们的属性,但是记录元素仍然只会打印一个空对象...意味着元素的每个所需属性都必须单独打印。至少它可行,但可能更好。
答案 0 :(得分:1)
如果要将对象从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并添加首选项" extensions.sdk.console.logLevel"值为" all",因此您可以记录您想要的任何消息。
但是,如果您还运行sdk cmd控制台,这将输出错误,但我不认为有任何问题需要担心,所有代码都会毫无问题地执行。
修改强> 刚刚发现我将其映射到var log时,如果firebug控制台没有打开,它会导致加载项停止工作,并且在打开firefox控制台时仍然无法正常工作。但是做一个不稳定的stindow.console.log(foo)工作正常。
答案 1 :(得分:0)
变化:
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...
答案 2 :(得分:0)
我遇到了同样的问题。它使基本脚本更麻烦。
试试这个(来自http://louisremi.com/2011/12/07/mozilla-addons-interactions-between-content-scripts-and-pages/)
“内联脚本注入
这样做的正确方法是在页面中注入内联脚本和/或使用customEvents。内联脚本是第三级脚本,可用于在全局范围内创建变量或函数:
// 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 );
验证此代码将输出警告,因为插件不应创建脚本标记。但这仍然是不安全的窗户最安全的替代方案。
<强> customEvents 强>
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 );
});"
答案 3 :(得分:0)
我在附加组件的内容脚本中遇到了同样的问题。由于某些未知原因,如果将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… }