2009-10-08 53 views
17

我想創建一個頁面,該頁面在DOM完全加載後運行包含document.write的第三方腳本。我的頁面不是XHTML。我的問題是,document.write正在覆蓋我自己的頁面。 (這是它加載DOM後的功能)。JavaScript - 控制document.write的插入點

我試着覆蓋document.write函數(與http://ejohn.org/blog/xhtml-documentwrite-and-adsense/類似),但不包括document.write包含部分標記的情況。

這樣會破壞上面的代碼中的一個例子是:

document.write("<"+"div"); 
document.write(">"+"Done here<"+"/"); 
document.write("div>"); 

是否有某種方式通過JavaScript修改文件撰寫插入點?有沒有人有更好的想法如何做到這一點?編輯之前

+0

是第三方腳本下載,所以你可以編輯它?我認爲這可能是一個比黑客更好的解決方案'document.write()' – peirix 2009-10-08 10:56:16

+0

我的例子沒有通過。我的意思是: document.write('<'+'div'); document.write('>'+'Text Content'+'<'); document.write('\ div>') – 2009-10-08 10:59:12

+0

我可以編輯它,但除了完整的JS解析,有沒有一種方法來保證編輯的代碼將正常工作? – 2009-10-08 11:01:14

回答

3

原來的答案:


基本的document.write的問題是,它does not work in XHTML documents。然後,最廣泛的解決方案(如同看起來那樣苛刻)是不能爲您的頁面使用XHTML/xml。由於IE + XHTML和mimetype problem,谷歌Adsense打破(可能是一件好事:),並向HTML5的總體轉變,我認爲它不像看起來那麼糟糕。

但是,如果你願意真的喜歡爲你的頁面使用XHTML,那麼你鏈接到的John腳本是你在這一點上最好的。只需在服務器上嗅探IE即可。如果請求是來自IE,請不要做任何事情(並且不要服務於application/xhtml+xml mimetype!)。否則,將其放入您網頁的<head>,然後您即將參加比賽。

重新閱讀您的問題,是否存在與John腳本有關的特定問題?已知在Safari 2.0中失敗,但這就是它。

+0

我的頁面沒有使用XHTML,但是我在加載DOM後加載第三方腳本,並且它們覆蓋了我的頁面。 我的問題是,下面的代碼將失敗: document.write('<'+'div');
document.write('>'+'Text Content'+'<');
document.write('\ div>'); – 2009-10-08 11:09:11

+0

@yeeeev:哇,所以這與XHTML無關?您應該將這些代碼放入您的作爲一個代碼片段的問題,所以我們可以幫助你更好的。它看起來不正確的評論。 – 2009-10-08 11:12:09

+0

@yeeev:我看到你實際上已經嘗試把它放在已經。讓我編輯你的問題.... – 2009-10-08 11:13:15

0

爲了在DOM渲染後改變頁面的內容,你需要使用一個JavaScript庫在特定的位置追加HTML或文本(jQuery,mootools,prototype,...)或者只是使用innerHTML每個DOM元素的屬性可以改變/附加文本。這適用於crossbrowser並且不需要任何庫。

-2

有更好的方法來做到這一點。 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> 
+0

不愛正確的答案? – 2009-12-30 14:40:06

+2

如果你不能改變第三方腳本,這個解決方案就沒有用了,解決方案#2也會用'hello world'取代整個身體。Typo? – gregers 2010-01-20 14:38:24

+0

@gregers。這只是一個技巧的例子 – 2012-11-09 11:05:56

3

您可以在the Javascript library I developed感興趣允許後的window.onload加載使用document.write 第三方腳本。在內部,庫重寫document.write,動態附加DOM元素,運行任何可能使用document.write的包含腳本。

不像約翰Resig的解決方案(這是啓發爲我自己的代碼的一部分),我公司開發的模塊支持部分寫入比如你給與div的,例如:

document.write("<"+"div"); 
document.write(">"+"Done here<"+"/"); 
document.write("div>"); 

我的圖書館將等待解析和呈現標記之前腳本的結尾。在上面的例子中,它將運行一次全字符串"<div>Done here</div>"而不是3次部分標記。

我已經設置了a demo, in which I load 3 Google Ads, an Amazon widget as well as Google Analytics dynamically

11

如果您正在處理第三方腳本,只需更換document.write以捕獲輸出並將其保留在正確的位置並不夠好,因爲它們可以更改腳本,然後您的站點就會中斷。

writeCapture.js做你所需要的(完全披露:我是作者)。它基本上重寫腳本標記,以便每個人都捕獲它自己的輸出並將其放在正確的位置。使用(使用jQuery)會是這樣的:

$(document.body).writeCapture().append('<script type="text/javascript" src="http://3rdparty.com/foo.js"></script>'); 

在這裏我假設你想追加到正文的結尾。所有的jQuery選擇器和操作方法都可以與插件一起使用,所以你可以在任何地方注入它,不管你想要什麼。如果這是一個問題,它也可以在沒有jQuery的情況下使用。

+0

當我使用這個代碼,鉻咆哮在我身上,並引發錯誤:'未捕獲的SyntaxError:意外的令牌非法' – 2013-11-16 01:00:57

4

可以覆蓋document.write方法。所以你可以緩衝發送到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 

我已經證明我寫,我使用時遇到的各種問題document.write替換:https://github.com/gregersrygg/crapLoader/wiki/What-to-think-about-when-replacing-document.write

但是使用document.write替換的危險都是可能出現的未知問題。有些甚至無法避開。

document.write("<scr"+"ipt src='http://someadserver.com/adLib.js'></scr"+"ipt>"); 
adLib.doSomething(); // ReferenceError: adLib is not defined 

幸運的是,我還沒有碰到過在野外上述問題,但並不能保證它不會發生;)

還是想嘗試一下?試用crapLoader(我的)或writeCapture

您還應該檢查出friendly iframes。基本上它會創建一個同域iframe,並將所有內容加載到文件中而不是文件中。不幸的是,我還沒有找到任何好的庫來處理這個問題。

1

FWIW,我發現postscribe是目前最好的選擇 - 它處理包裹一個令人討厭的廣告渲染模塊,就像一個魅力,允許我們的頁面加載而不被阻止。