將 <body/> 的內容包到一個 <div/> 中

此篇文章最近更新時間為2009-10-22 07:28:49 目前共有5篇留言

關於作者 - JosephJ

任職於 Faria。喜好戶外運動、2008 年 5 月完成「跑步環島」。對於新技術跟程式碼有著強烈的偏執狂。

將 <body/> 的內容包到一個 <div/> 中
範例程式:http://josephj.com/lab/wrapper/demo.php

2009/12/29 更新:IE 的 removeNode

P 同事反應也需要一個移除 Wrapper 的功能,但我想也應跟 applyElement 與 surroundContent 一樣盡可能不要用 appendChild 影響。P 同事說 IE 有一個 removeNode 很好用,但是這次換 Firefox 不支援好用的東西了 XD 還好找到一篇部落格有提到解法:http://blog.xuite.net/alex.yung/01/13237200。直接抄下來用果然解決了我的問題,也更新到範例程式中囉!


2009/10/27 更新:IE 的 applyElement

感謝 Hedger 提供,IE 有一個 applyElement 的方法可以一行就解決所有問題,我已經整到範例程式中了。除了 W3C 的 surroundContents 以外,其他的都可以不用看囉~


W3C 的 surroundContents 方法

標準瀏覽器都支援 W3C Range 的 surroundContents() 方法,
只要輕鬆幾行就可以將所有 body 標籤內的東西放到一個 div 中:
var dBody = document.body;
var dWrapper = document.createElement('div');
dWrapper.className = 'wrapper';
var oRange = document.createRange();
oRange.selectNodeContents(dBody);
oRange.surroundContents(dWrapper);
但是 IE 的跟 W3C Range 的定義完全不一樣,也並沒有類似 surroundContents 的方法,讓我一個頭兩個大。

innerHTML

其實一開始就有試 innerHTML 的作法:
document.body.innerHTML = '
' + document.body.innerHTML + '
';
但是光 Yahoo! 首頁就包了,看起來很正常,但是所有 Tab 的 Hover 事件都不見了。

ierange.js

後來發現有好心人在 Google Code 上維護 ierange.js 這個讓 IE 跟 W3C 使用相同 Range 方法的 Library,
不過我試了一下 surroundContents 還是包了:不知道為啥有終止執行的問題(我都是 domReady 後才做)。

XMLHttpRequest

以前在 Yahoo! 頭大時就會去問小 Z 大神,還好網路無幅界,IM 讓我們保持聯繫 = =+
小 Z 給我一個很有趣的試法:既然一定在同 Domain,何不直接終止目前的執行、直接用 XMLHttpRequest 拉 location.href 的資料、包完後再吐到頁面上、控制權完全在手上。聽起來還不賴,但是最後還是碰到了問題:讀取外部 JavaScript 時的執行順序,如果我把整理好的 HTML 用 document.write 吐,呼叫的函式一定幾乎都比外部 Library 執行的時間點快... 我實在沒把握解決掉這個問題,只能對不起小 Z 大神了。

appendChild

這個方法從一開始就知道、又再回去看了 ierange 的 code 時,發現他們的 surroundContents 就是用 appendChild 來做的,但是我開始時並沒有想到 innerHTML 與 appendChild 的差異性:innerHTML 會把物件參考給消滅、但 appendChild 會保存。於是死馬當活馬醫,用 appendChild 來試試看,沒想到 Yahoo! 首頁都還可以用!
var dBody = document.body;
var dWrapper = document.createElement('div');
dWrapper.className = 'wrapper';
while (dBody.firstChild) {
    dWrapper.appendChild(dBody.firstChild);
}
dBody.appendChild(dWrapper);
在還沒找到更好的作法時,就先這樣搞吧 XDD


Comments

  1. Anonymous 2011-11-18 19:24:42
    asdfgf [url=http://ipagehostingreview.info/]ipage[/url]
    lkjhj
    <a href="http://ipagehostingreview.info/">ipage</a> jos
    http://ipagehostingreview.info/ oiupy
  2. 裕波 2009-12-30 23:51:23
    学习了,你的文章很有营养。
  3. Awoo 2009-10-27 12:18:00
    哇,applyElement 好讚
    不過在標準瀏覽器的部份我會使用 .surroundContents
    總是會擔心 appendChild 對物件參考或事件的衝擊比較大

    有 Hedger 真好 T^T
  4. Hedger Wang 2009-10-27 04:30:24
    更好更快的作法


    var dBody = document.body;
    var dWrapper = document.createElement('div');
    dWrapper.className = 'wrapper';
    var child;

    if(dBody.applyElement) {
    // http://msdn.microsoft.com/en-us/library/ms536341%28VS.85%29.aspx
    dBody.applyElement(dWrapper, 'inside');
    } else {
    // Avoid page rereflow.
    dBody.parentNode.removeChild(dBody);

    while(child = dBody.firstChild) {
    dWrapper.appendChild(child);
    }
    dBody.appendChild(dWrapper);
    document.documentElement.appendChild(dBody);
    }




    while (dBody.firstChild) {
    dWrapper.appendChild(dBody.firstChild);
    }
    dBody.appendChild(dWrapper);
  5. laudieh 2009-10-25 01:02:24
    在看這篇時會想起之前在 ericsk 上寫的 <a href="http://blog.ericsk.org/archives/1358">這篇</a> 以為講的是同件事,但仍是不同的 XD
暱稱: 必填。
Email: 非必填。若填寫為不公開欄位,僅供站長參考聯繫。
內容: 必填。限 255 個字元以內。
驗證碼:
送出

Facebook Comment