功能說明:本地包含
應用平臺:IE6
應用場景:做快速原型時有點用
背景:公司做小項目比較多,經常要做快速原型,要做成頁面,不能是PSD,PSD不能顯示Flash,以及不能讓客戶在快速原型中點擊鏈接進行瀏覽。
又因為是快速原型,最好是不要使用服務端技術,像asp\php\jsp之類的就可以退散了,我們都是直接做HTML文件,打個包發給客戶,客戶解壓后,可以看到非常顯眼的一個主頁文件(其它文件放在文件夾中,最外層只有一個主頁文件),雙擊就會在瀏覽器中瀏覽了。
在做網站時,公用部分比如頁頭、菜單、登陸區、頁腳等改動會比較多,像菜單的組織方式改動,頁腳區建設單位、聯系方式、版權的說明文字改動等,這時我們會希望重用這些部分。我們一般有如下的做法:
- 使用服務端技術,用<include>包含
- 使用<frameset>或<iframe>分塊處理
- 使用js文件引入,并在js文件里面寫document.write()
- 還可以使用ajax去讀另一個文件,再插入到合適的地方
以上幾種方法,服務端的<include>可以直接退散了,原因之前說過了;
使用ajax去讀另一個文件也不行,因為沒有架設web服務器,ajax是不能直接讀本地文件的,出于安全考慮,是沒有這個權限的,這個看官們可以自己去試;
使用<frameset>會且僅會占滿一個屏幕,你想要一個滾動條?對不起,它會把你分成兩個或更多個滾動條;
使用<iframe>不能根據包含的內容自動設置高度,雖然我知道可以寫一些代碼來做到這一點,但我總是不能很好的調整好這個效果,也許是我不夠精通此道,對于寫代碼來調整iframe的高度這事件,我感覺還是不靠譜;
使用js文件引入,這個方法其實挺不錯,唯一的缺點就是不夠友好,在document.write()中的字符串,沒有友好的格式,以及代碼顏色;
以上是背景,回到“本地包含”的問題上,這個本地包含的JS就是解決上面的問題的,不多說,直接上代碼:
<script src="jquery.js"></script>
<script src="divsrc.js"></script>
<div src="header.html"></div>
<div src="menu.html" onload="selectMenu(0);"></div>
這里是首頁內容啊,有木有!!!
<div src="footer.html"></div>
divsrc.js 就是我寫的東西啦,如何使用?<div>標簽有src屬性就行了,接下來分析實現思路。
實現方式和ajax差不多,假設將b頁面包含到a頁面中,通過一種方式讀取到b頁面的代碼,再插入到a頁面中,關鍵就在這里。
- 在a頁面中插入一個<iframe>,并設置為隱藏
- 動態設置iframe的src屬性,讓iframe加載b頁面
- 通過iframe.contentWindow.document.body.innerHTML來訪問b頁面的代碼
- 最后將讀到的代碼插入到合適的位置即可
可以看到這是使用了一種比較另類的方式實現和ajax差不多效果的功能。
然后,我們還需要再面臨一些小問題。
- 在iframe內部頁如果是本地磁盤的一個文件,在谷歌、火狐等瀏覽器上,同樣會出現沒有權限訪問的吧?
是的,所以我這個JS只支持在IE6上工作,請原諒我還在使用IE6,我的客戶都是IE6。
- 頁面加載會有延遲吧?如何保證在iframe內部頁加載完成之后,再讀取內部頁的內容?
首先,這個JS就是用于解決不使用服務端技術時,需要包含本地文件的場景,那么既然是本地,加載速度是很快的。
當然,無論多快,總是會有延時的,這里我采用了每隔20毫秒去檢查iframe加載完成了沒有的辦法(如果發現加載完成后,計時器就會結束)
可能不是很好,但我感覺還能接受。
我不想讓開發人員一定要在b頁面插入什么指定的代碼。如果沒有這個堅持,那我就可以去掉上面那個計時器方案,讓這個JS工作得更好。
- b頁面如果有js代碼,會被執行兩次吧?一次是在<iframe>中,一次在重新插入到a頁面時。
是的,會執行兩次,但這只是快速原型,兩次就兩次吧,客戶不會察覺也不會介意的。只要我們正式運行在生產機上采用了服務端技術的程序沒有這個問題就行。
- 我感覺這是一個好小的問題,有必要為一個這么小的問題搞得如此糾結嗎?
代碼能被重用,節省我很多時間,雖然是小問題,但很重要,看官要是不喜歡,就可以退散了。
最后上divsrc.js的代碼(需要jquery支持):
$.fn.extend({divsrc:function(){
var divs=this;
var ifr=$('iframe[id=ifr_divsrc]');
if(!ifr.length)ifr=$('<iframe src="" style="display:none;"></iframe>').appendTo(document.body);
function ___divsrc___load(divs, i, init){
var div=$(divs[i]);
if(init){
ifr.attr('src', div.attr('src'));
setTimeout(function(){___divsrc___load(divs, i, false);}, 20);
}else{
if(!ifr[0].contentWindow||!ifr[0].contentWindow.document
||!ifr[0].contentWindow.document.body||!ifr[0].contentWindow.document.body.innerHTML){
___divsrc___load(divs, i, false);
}else{
div.html(ifr[0].contentWindow.document.body.innerHTML);
if(div.attr('onload')) eval(div.attr('onload'));
if(i<divs.length) ___divsrc___load(divs, i+1, true);
}
}
}
___divsrc___load(divs, 0, true);
}});
$(function(){ $('div[src]').divsrc(); });
還有全部源代碼的下載: 點擊下載html本地包含
浙公網安備 33010602011771號