我想创建一个运行第三方的脚本,包括页面document.write
的DOM已经满载后。
我的页面是不是XHTML。 我的问题是,文件撰写被改写自己的网页。 (这是它做什么,一旦DOM被加载)。
我试图重写文件撰写的功能(在某种程度上类同http://ejohn.org/blog/xhtml-documentwrite-and-adsense/ ),但其中包含文件撰写部分标签未覆盖的情况。
会破坏上面的代码的一个例子是:
document.write("<"+"div");
document.write(">"+"Done here<"+"/");
document.write("div>");
是否有某种方式通过JavaScript修改文件撰写插入点? 有没有人有一个更好的主意如何做到这一点?
如果你正在处理与第三方的脚本,只需更换文件撰写捕获输出,并把它贴在正确的位置不够好,因为它们可以改变脚本,那么你的网站将打破。
writeCapture.js做你需要什么(全面披露:我是作者)。 它基本上是重写剧本标签使每一个捕获它自己的document.write
的输出,并把它在正确的位置。 (使用jQuery)的用法是这样的:
$(document.body).writeCapture().append('<script type="text/javascript" src="http://3rdparty.com/foo.js"></script>');
在这里,我假设你要追加到身体的末端。 所有jQuery选择和操作方法将与插件,所以你可以在任何地方,并且按照自己希望它注入。 它也可以不使用jQuery的,如果这是一个问题。
它可以覆盖该文件撰写方法。 所以,你可以发送缓冲对document.write输出任何你喜欢的缓冲区中的字符串。 然而从同步更改脚本异步可能会导致错误,如果不能正确处理。 下面是一个例子:
简化文件撰写更换
(function() {
// WARNING: This is just a simplified example
// to illustrate a problem.
// Do NOT use this code!
var buffer = [];
document.write = function(str) {
// Every time document.write is called push
// the data into buffer. document.write can
// be called from anywhere, so we also need
// a mechanism for multiple positions if
// that's needed.
buffer.push(str);
};
function flushBuffer() {
// Join everything in the buffer to one string and put
// inside the element we want the output.
var output = buffer.join('');
document.getElementById("ad-position-1").innerHTML = output;
}
// Inject the thid-party script dynamically and
// call flushBuffer when the script is loaded
// (and executed).
var script = document.createElement("script");
script.onload = flushBuffer;
script.src = "http://someadserver.com/example.js";
})();
内容http://someadserver.com/example.js
var flashAdObject = "<object>...</object>";
document.write("<div id='example'></div>");
// Since we buffer the data the getElementById will fail
var example = document.getElementById("example");
example.innerHTML = flashAdObject; // ReferenceError: example is not defined
我已经证明我已经编写和使用我的文件撰写更换时遇到的各种问题: https://github.com/gregersrygg/crapLoader/wiki/What-to-think-about-when-replacing-document.write
但是,使用文件撰写替代的危险都可能出现的未知问题。 有些甚至是不可能得到解决。
document.write("<scr"+"ipt src='http://someadserver.com/adLib.js'></scr"+"ipt>");
adLib.doSomething(); // ReferenceError: adLib is not defined
幸运的是,我还没有碰到过在野外上述问题,但并不能保证它不会发生;)
还是想尝试一下? 尝试crapLoader (矿)或writeCapture :
您也应该检查出的iframe 。 基本上,它会创建一个相同的域iframe和您的文档中有加载的一切,而不是。 不幸的是我还没有找到处理这个还没有任何好的库。
编辑之前原来的答案:
基本的问题document.write
的是,它并没有在XHTML文档工作 。 最广泛的解决方案,然后(苛刻,因为它可能看起来)是不使用XHTML / XML为您的网页。 由于IE + XHTML和MIME类型的问题 ,谷歌的Adsense破碎(可能是一个很好的事情:),并朝着HTML5的通用转变,我不认为这是因为它看起来那么糟。
但是,如果你真的想使用XHTML为您的网页,那么您链接到约翰的剧本是你在这一点上已经得到了最好。 只是嗅探IE在服务器上。 如果请求来自IE,没有做任何事情( 不要服务application/xhtml+xml
MIME类型!)。 否则,把它扔到<head>
您的网页,你是去比赛。
重读你的问题,是你有与约翰的剧本一个具体问题? 众所周知,在Safari 2.0失败,但仅此而已。
您可能感兴趣的JavaScript库我公司开发 ,它允许加载使用document.write在window.onload 之后第三方脚本。 在内部,该库覆盖document.write,用附加的DOM元素动态地,在运行任何包括其可使用文件撰写以及脚本。
不像约翰Resig的解决方案(这是启发为我自己的代码的一部分),我公司开发的模块支持部分写入比如你给与div的,例如:
document.write("<"+"div");
document.write(">"+"Done here<"+"/");
document.write("div>");
我的图书馆将等待剧本的最后解析和渲染标记之前。 在上面的例子中,将与完整的字符串运行一次"<div>Done here</div>"
代替3次,局部标记。
我已经建立了一个演示,我在其中加载谷歌3个广告,亚马逊的部件以及谷歌Analytics(分析)动态 。
FWIW,我发现postscribe是最好的选择,在那里这些天-它处理一个包裹讨厌的广告渲染模块就像一个魅力让我们的页面,而不会被加载。
为了改变页面的内容在DOM渲染后,你要么使用JavaScript库附加在某些点HTML或文本(jQuery的,MooTools的,原型,...),或只是使用每个DOM的innerHTML属性元素来改变/追加文本。 这工作跨浏览器,并且不需要任何库。
有更好的方法来做到这一点。 2种方式
1)追加
<html><head>
<script>
window.onload = function () {
var el = document.createTextNode('hello world');
document.body.appendChild(el);
}
</script></head><body></body></html>
2)的innerHTML
<html><head><script>
window.onload = function () {
document.body.innerHTML = 'hello world';
}
</script></head><body></body></html>