1. 程式人生 > >【JS】純前端程式碼複用技術

【JS】純前端程式碼複用技術

引言

結合了後端的頁面有多種程式碼複用技術,如jsp使用<%@ include file="" %>即可引入公共的頁面成分,如header,footer等結構。但在純前端實現上就很具有侷限性,本文將會介紹網上流傳的幾種純前端程式碼複用方法,以及筆者本人使用的方法。

1.預編譯

通過在靜態頁面中引入類似jsp<%@ include file="" %>的標籤,然後利用gulp-file-include等預編譯工具進行一次替換,之後頁面就是完整的。

HTML 程式碼複用實踐

優點:生成的頁面完整,相對於各種非預編譯方法,減少了使用者訪問時的實際請求數,也就提供了最快的訪問速度。
缺點:編碼時不太方便,想要預覽完整頁面需要先預編譯。

2.使用document.writeln()

將需要的HTML程式碼轉成document.writeln()形式的JS檔案,在需要的地方<script src='' ></script>一下即可。

HTML不同頁面中重用程式碼

優點:簡單粗暴,有自動的HTML轉JS工具,速度快。
缺點:document.writeln()可能會引起頁面重繪,不建議使用。同時生成的JS檔案不便於修改。

3.使用vue.js component

日漸流行的新興前端框架,如Vue,React,Angular,都可以通過類似引入component的形式引入程式碼。

4.使用jQuery .append()

使用ajax方法獲取到HTML程式碼,然後新增到指定的元素內。除了.append()方法,類似的還有.prepend() .html() .data() .load()等方法,都可以實現類似的效果。

優點:較為靈活,ajax獲取到後還可以進行一些處理,比如替換一些變數值。
缺點:增加了使用者訪問的請求數,每新增一個重用元素,都會增加使用者訪問時的請求。

筆者的方法

筆者也在做一個小型的Web專案,目前採用的方法是類似於上述第4種的方法,只是加上了一些自己的封裝,具體如下:

common-main.js

function initTry
() { /** * 修改剩餘待載入的資源,如果全部載入完成,呼叫init() */ --global.leftLoadingRes; if(!global.leftLoadingRes) { init(); } } function loadResAsync(url, doFunc) { /** * ajax非同步載入資源,如果載入成功,呼叫initTry() * @param {string} url - 需要獲取資源的Url * @callback requestCallback */ /** * @param {requestCallback} doFunc(data) - ajax請求完成後執行的CallBack * @return {Boolean} 返回true表示資源載入成功,返回false表示資源載入失敗 */ $.ajax({ url: url, type: 'get', //async:false, success: function(data, status) { var result = doFunc(data); if(result) { initTry(); } } }); }

normal.html

<script src='各種lib.js'></script>
<script src='common-main.js'></script>
<script>
	global = {
		leftLoadingRes: 2
	}
	//所有resource載入完成後執行的init
	function init() {
		//先對非動態部分init
		tbm_init();
		sm_init();
		//最後對動態載入部分init
		main_init();
	}
	loadResAsync('header.html', function(data) {
		//沒資源依賴的在這個資源載入完畢後直接init
		$('#header').append(data);
		header_init();
		return true;
	});
	loadResAsync('searchCollapse.html', function(data) {
		$('#searchCollapse').append(data);
		return true;
	});
	function main_init() {
		//有資源依賴的放在這裡等到所有資源載入完成後統一init
	}
</script>

通過loadResAsync()裡的CallBack,不依賴其他動態載入資源的init直接在CallBack裡init;有依賴的放在main_init()裡,等最後所有資源都載入完了統一init,既保證了資源載入的正確性,又儘可能地提高資源載入的效率。由於loadResAsync()中的ajax是非同步請求,所以不會因為某個請求響應過慢而導致下面的請求無法執行。

但是要注意,因為使用了非同步請求,所以相應的程式碼有可能需要變動。如:

  1. 我引入的sb-admin-2.js,init是在$(function() {})中,但是頁面載入完成時可能我的header資源還在載入,導致init失敗。這種情況下就要修改sb-admin-2.js,把init方法改名為sba_init(),並在對應資源的CallBack中予以呼叫,即可正確載入。
  2. 對於形如$('selector').click(function(){})的函式,如果在資源載入前載入完畢,就會導致函式未繫結到對應元素。這種情況下就需要改為$('parentSelector').on('click','selector',function(){}),讓對應的事件繫結到頁面中非動態載入的元素,如<body>或者<html>