Ger*_*ino 7 javascript mozilla firefox-addon firefox-addon-sdk
我正在尝试创建一个Firefox插件(使用插件SDK)来修改页面的显示方式,主要是作为培训/学习练习.
对于某些任务(如增加具有新功能的页面)使用pageMod完全没问题.页面加载,我运行一些JS来显示/隐藏/添加元素.
我的问题是:我可以在页面开始显示之前对DOM执行修改(所以:服务器返回的HTML文档)吗?
例如:从服务器返回的页面是:
<html>
<body>
<table>
<tr>
<td>Item 1.1</td>
<td>Item 1.2</td>
<td>Item 1.3</td>
</tr>
<tr>
<td>Item 2.1</td>
<td>Item 2.2</td>
<td>Item 2.3</td>
</tr>
</table>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
但我希望FF代替:
<html>
<body>
<ul>
<li>Item 1.1, Item 1.2, Item 1.3</li>
<li>Item 2.1, Item 2.2, Item 2.3</li>
</ul>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
在页面加载后执行此操作将首先显示表格,然后它将快速"闪烁"到列表中.它可能足够快,但如果我要更改<img>标签<a>,例如防止(不想要)图像加载,这是不够的.
我正在寻找contentScriptWhen: "start"在pageMod 中使用并尝试附加监听器,但我无法看到我如何实时修改DOM'(或事件阻止在加载所有页面之前显示任何类型的页面).
我已经检查了cloud-to-butt扩展,因为它确实修改了页面,但我甚至无法让它工作:当作为pageMod附加start代码失败时:
document.getElementById('appcontent').addEventListener('DOMContentLoaded', function(e)
Run Code Online (Sandbox Code Playgroud)
因为document.getElementById('appcontent')返回null.
我非常感谢一些指示:是否可能,如何附加脚本,如何拦截HTML并在经过一些修改后将其发送回去.
编辑:好的,所以我认为我能够拦截数据:
let { Ci,Cr,CC } = require('chrome');
let { on } = require('sdk/system/events');
let { newURI } = require('sdk/url/utils');
let ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1", "nsIScriptableInputStream", "init");
on('http-on-examine-response', function (event) {
var httpChannel = event.subject.QueryInterface(Ci.nsIHttpChannel);
var traceChannel = event.subject.QueryInterface(Ci.nsITraceableChannel);
if (/example.com/.test(event.subject.URI.spec)) {
traceChannel.setNewListener(new MyListener());
}
}, true);
function MyListener(downloader) {
this.data = "";
}
MyListener.prototype = {
onStartRequest: function(request, ctx) {
this.data = [];
},
onDataAvailable : function(request, context, inputStream, offset, count) {
var scriptStream = new ScriptableInputStream(inputStream);
this.data.push(scriptStream.read(count));
scriptStream.close();
},
onStopRequest: function(request, ctx, status) {
console.log(this.data.join(''));
}
}
Run Code Online (Sandbox Code Playgroud)
现在,onStopRequest我想对数据做一些事情并将其输出回原来的位置......
请注意,这适用于字符串而不是DOM,所以它并不完美,但它是一个开始的地方:)
EDIT2:
嗯,我得到了它的工作,虽然我有一种感觉,我不应该这样做:
onStopRequest: function(request, ctx, status) {
//var newPage = this.data.join('');
var newPage = "<html><body><h1>TEST!</h1></body></html>";
var stream = converter.convertToInputStream(newPage);
var count = {};
converter.convertToByteArray(newPage, count);
this.originalListener.onDataAvailable(request, ctx,
stream, 0, count.value);
this.originalListener.onStopRequest(request, ctx, status);
},
Run Code Online (Sandbox Code Playgroud)
我的问题是:我可以在页面开始显示之前对DOM执行修改(所以:服务器返回的HTML文档)吗?
是的,javascript执行在第一次呈现页面之前开始.DOM Parser会通知变异观察者,因此您可以在解析器添加元素后立即删除元素.
即使在加载的内容脚本中也可以注册变异观察器,contentScriptWhen: "start"因此在渲染之前应该通知他们在树中添加到树中的所有元素,因为在宏任务队列中进行渲染时,观察者通知在微任务队列中执行.
但我甚至无法让它工作:当作为pageMod附加启动代码失败时:
document.getElementById('appcontent').addEventListener('DOMContentLoaded', function(e)
当然.您不应该假设任何特定元素 - 甚至<body>标记 - 在页面加载期间早期已经可用.您将不得不等待它们变得可用.
而DOMContentLoaded事件可以简单地将上注册document的对象.我不知道你为什么要在某个元素上注册它.
(或事件阻止在加载所有页面之前显示任何类型的页面).
你并不真的想要它,因为它会增加页面加载时间,从而降低网站的响应能力.
| 归档时间: |
|
| 查看次数: |
7801 次 |
| 最近记录: |