【JS】纯前端代码复用技术

版权声明:原创 https://blog.csdn.net/hangvane123/article/details/84944160

引言

结合了后端的页面有多种代码复用技术,如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>

猜你喜欢

转载自blog.csdn.net/hangvane123/article/details/84944160