這里主要總結瀏覽器前端的侵入性問題,諸如nodejs那樣的應用不在本文的討論范圍。
編寫瀏覽器的js應用無非用到三大件:js、css、html,而這三樣東西都有可能對瀏覽器造成侵入性,這樣前端的js應用免不了會和頁面中的其他相關內容起沖突,如樣式亂掉、JS錯誤、某html標簽不被支持等問題,造成侵入后,要么是自身的東西影響了其他的,要么自身的東西被影響了。當然如果全部是項目定制開發,具有一定的代碼規范和命名規則,這倒是還好,相信資源沖突的可能性比較小。在這里不得不噴一下jquery-ui,經常會看到其ui被站點樣式影響到,變得奇形怪狀的。
在編寫kooboo cms inline editing應用的時候,遇到了很多的侵入性問題,inline editing所運行的環境是成千上萬個kooboo cms站點的前台頁面,環境相當的復雜而且不可預測,你永遠不知道用戶會開發什么樣的站點,用什么樣的js、css、html,用戶的js是不是有運行錯誤,用戶的css是不是有兼容性問題,用戶的html是不是有正常閉合或是嵌套錯誤。。。。
以下是總結:
1.html標簽的使用,如果你的應用所用的標簽都是div,那我想被影響的幾率將會非常的大,其實可以使用一些不常見的標簽比如<var></var>等等,或完全可以使用自己定義的標簽來如<rulee></rulee>,在inline editing中使用了var標簽,雖然比起div,沖突的可能性已經比較小了,至少以目前的實際使用情況來講是這樣的,不過因為這是一個w3c中有定義的標簽,心里總是覺得不那么放心,找個機會還是要換掉var的,要是早點一研究出使用自定義標簽的方法就好了。
------對的,自定義標簽其實不是可以自己隨便定義的,我實驗的結果是:除IE6、IE7、IE8外所有瀏覽器都可以自定義標簽,也就是能正常解析<rulee></rulee>,相互嵌套也正常,顯示為inline樣式。IE6、IE7、IE8不能正常解析和顯示,用Devtoolbar查看顯示為嵌套不正常,出現各種問題。。。直到在同事推介用一個js組件的時候這個問題才解開,這個組件就是http://code.google.com/p/html5shiv/,它的作用就是讓舊版本的IE瀏覽器認識html5的新標簽類型,它的代碼非常的簡單,其中最重要的一句代碼就是document.createElement('rulee'),執行這樣一句代碼后舊版本的瀏覽器就認識了rulee標簽,顯示正常為inline樣式,嵌套沒問題,哦也!
<rulee class="main"> <rulee class="title">I'm rulee.</rulee> </rulee>
2.css樣式的使用,有了自定義的標簽后如果樣式沒有使用好,沖突依然到處存在,因為你想如果js應用這樣使用<rulee class="title">a</rulee>,這樣的樣式名.title那是多么的常見啊,不被影響到才怪呢,所以開發通用組件的時候,推介的命名方式是加上標簽名限定rulee.title或外加上一個名稱前綴.rulee-title也還行,這樣就大大降低了沖突的可能性了。
rulee.main{ float:left; } rulee.title { color:red; }
3.js相互的污染,熟悉js的朋友都知道js的特性,它的動態語言特性,幾乎一切都是可以自由替換和擴展,造成的問題是js應用和頁面其他js非常容易相互侵入和污染,莫名其妙的問題接踵而來,所以腳本的使用也要很小心,閉包是必須的,養成一個良好的js代碼習慣,用閉包隔離組件的js和外部js,同時避免污染window域,非到不得已不輕易掛接對象到window上,因為永遠都不會知道會不會有另外的一個js也使用了同一個key在window上掛接對象、造成沖突。當組件依賴第三方工具時,如jquery,它會在window上掛接jQuery和$兩個key。這樣很可能會和用戶自己引入的jquery對象造成沖突(也就是一個頁面上出現多個jquery引用),jquery的開發着有考慮到了這樣的一個可能性,並提供了一個解決這個問題的API:jQuery.noConflict。其它第三方工具可以參考jquery的這個API去解決相互污染的問題。
(function($){ var context = {};
// your code })(jQuery);
(function($){ // your code $.noConflict(true); // this api called at the end of your component. })(jQuery);
4.神器iframe,這是一個創建了獨立運行空間的html標簽,說它是一個html標簽好像太小看它的功能了,其創建了一個新的頁面運行環境,內部完全不受父頁面內容的影響,那是不是把組件的內容render到iframe中就完美了?當然不是,這個要看應用場合,首先iframe在顯示時創建了一個新的運行域,代價比較大,會影響到頁面的性能,另外通過腳本來控制也是相對比較麻煩的。目前大部分廣告管理系統會青睞使用iframe來輸出內容來避免侵入性,包括我自己做的廣告管理系統也是使用了iframe作為輸出載體,不過其實如果用好了以上的1,2,3點,完全可以拋棄iframe的。
<iframe src="about:blank;"></iframe>
var win = iframe.contentWindow; var doc = win.document; doc.open('text/html'); doc.write('html content'); doc.close();
容易產生侵入性的地方,一般是在目標運行環境不確定的情況,所以一般普通的項目不會太注重這個,但是強烈建議做通用組件的朋友們應該多減少侵入性的發生,這樣才會是一個健壯的組件,希望這個對大家有用。