Harley Wang

为了心中的美好,不妥协直到变老

Technical discuss & life Note-taking.


InnerJS,找到你的使用场景

InnerJS是我两年前写的代码,名称的由来是innerHTML,看字眼大概也知道它是干什么用的,它包含了innerHTML的能力;但是一直没有大规模(UV亿级以上的站点)的使用, 我只是希望更多的人证实该方案可行,才会去大规模使用。

为什么写了这么久的代码今天又拿出来了呢,其实我想将InnerJS与Pjax一起应用,可以很容易的动态绑定DOM。好了,不啰嗦了,以下是InnerJS的源码:

/*
 * InnerJS.js
 *
 * Release 1.2.8
 * @author  <a href="mailto:haley.wang.vip@gmail.com">Haley Wang</a>
 * @describe  InnerJS,插入并执行JavaScript/HTML/CSS
 */
var InnerJS = {
	set:function(element, str){
		element.innerHTML = '<div style="display:none">InnerJS</div>'+str;
		element.removeChild( element.children[0] );

		var scripts = element.getElementsByTagName('script');
		if(scripts.length > 0){
			this.task = []
			for(var i=0, len=scripts.length; i<len; i++){
				this.task.push(scripts[i]);
			}
			this.overwrite();
			this.run();
		}
	},
	overwrite:function(){
		var that = this;
		document.write = function(str){
			that.insertHTML(that.exeScript, "beforeBegin", str);
		};
		document.writeln = function(str){
			that.insertHTML(that.exeScript, "beforeBegin", str+"\n");
		};
	},
	run:function(){
		var script = this.task.shift();
		if(!script)return;

		var resObj = document.createElement('script');
		resObj.type = "text/javascript";
		var that = this;
		if(script.src){
			if (resObj.readyState){
				resObj.onreadystatechange = function(){
					if(resObj.readyState == "loaded" || resObj.readyState == "complete"){
						resObj.onreadystatechange = null;
						that.run();
					}
				};
			}else {
				resObj.onload = function(){
					that.run();
				};
			}
			resObj.src = script.src;
		}else{
			resObj.text = script.text;
		}
		this.exeScript = resObj;
		script.parentNode.replaceChild(resObj, script);
		if(!script.src){
			that.run();
		}
	},
	insertHTML:function (ele, falg, html) {
		if (ele.insertAdjacentHTML) {
			ele.insertAdjacentHTML(falg, html)
		}else{
			var range = ele.ownerDocument.createRange();
			falg = falg.toUpperCase();
			if (falg == "AFTERBEGIN" || falg == "BEFOREEND") {
				range.selectNodeContents(ele);
				range.collapse(falg == "AFTERBEGIN")
			} else {
				var f = falg == "BEFOREBEGIN";
				range[f ? "setStartBefore" : "setEndAfter"](ele);
				range.collapse(f)
			}
			range.insertNode(range.createContextualFragment(html))
		}
	}
};

下载 InnerJS Demo

注意:InnerJS每次都会生成全新的DOM结构,执行JavaScript所生成的对象,会被重新覆盖; 这里有一个问题,第一次执行InnerJS向一个全局Array插入元素,如果第二次执行又向这个Array插入元素,应用中又会用到这个Array,那么就会出现一些问题,除非每次都去初始化这个全局Array;毕竟我们不能给用户设定规则去使用InnerJS,所有我也在考虑怎么去更好的完善或规避这个问题。

如果你看完了也使用过Demo了,有什么问题希望一起交流!

最近的文章

OS X El Capitan 制作U盘安装盘

①下载安装程序:从 App Store中下载完整的(Install OS X El Captain / 安装 OS X El Captain) 安装程序,该安装程序下载完后会存放在(应用程序 / Applications)文件夹中。请注意,此时一定不要直接启动该程序安装 OS X El Captain,因为一旦安装完后该安装程序会被删除。至少,你应该先做完独立安装介质之后再启动该程序安装。②准备独立安装盘介质:你需要一个容量至少大于 8GB 的移动存储设备,比如 U 盘、移动硬盘或 SD ...…

继续阅读
更早的文章

Git常用命令备忘

克隆远程版本库:git clone git@git.example.com:tech/front.git克隆远程版本库的一个分支(develop):git clone -b develop git@git.example.com:tech/front.git查看文件状态:git status添加修改的文件到暂存区:git add [filename / dir / -A]提交修改:git commit -m “这里简单写一些修改了什么”拉取最新的远程仓库数据:git pull推送提交的修改...…

继续阅读