原来这是一个经典面试题-------Day61

前几天在table的操作中,记录了动态生成表格的三种方式:

1、html语言的拼接;用字符串或者数组拼接在html语言中,这个理解起来最直观

2、插入行和列;insertRow()和insertCell()

3、生成元素;createElement()

在完成当天记录的时候还自我检讨了下,考虑的解决方法不够全面,那么认真的忏悔了一通,结果之后却意外的发现了一件令我啼笑皆非的事情:原来动态生成表格,这是一个经典的面试问题,而且还有一种更专业的解决方法。于是我之前的忏悔就成了笑话,其实还是没全面了....


仔细的研究了网上的解答,感觉比上面总结的三种方式专业了好多,技术的感觉一下子出来了,既然是一个经典的面试题,那就再认真的记录分析下吧:

1、先查看一下最终实现的结果,很漂亮(当然其实用上面的三种方式也可以的,这几次就这个生成的好看嘛,就多写点喽)

原来这是一个经典面试题-------Day61_第1张图片

2、是不是非常漂亮,我觉得挺漂亮的。来分析下需要实现的功能需求:

a、获取录入的期望行和列的值(这个现在毫无难度啊,表示无压力);

b、根据获取到的行和列的值,动态生成相应行和列的表格(就是主要来分析它的实现的);

c、点击某一单元格,获取单元格内部的值和相应单元格的背景颜色(这个在前面js获取table的一行一文中记录过);

3、上一下实现的代码

html部分:

 <body>
  <center>
	  经典的面试题<br/>
	  <hr/><br/>
	  输入行数:<input type="text" id="rowsNum"><br/>
	  输入列数:<input type="text" id="colsNum"><br/>
	  <a href="javascript:" id="go">获取表格</a>

	  <div id="tablePart"></div>

	  <div id="tipPart" style="background:cyan;"></div>
  </center>
 </body>
javascript部分:

<script type="text/javascript">
function CreateTable() {
	this.oTable  = null;
	this.bgColor = 0;
}
CreateTable.prototype.init=function(row, col) {//这是知识点1
		var oFrag = document.createDocumentFragment();//这是知识点2
		var oTemp = document.createElement("div");
		var oBody = document.body;
		var aRow  = [];
		var aCol  = [];
		for(var i = row; i--;) {
			aCol.length = 0;			
			for(var j = col; j--;) {
				this.bgColor = this.getRanColor();
				aCol.push("<td style=\"background:"+ this.bgColor +";\">"+this.randomRange(1, 15)+"</td>");
			}
			aRow.push("<tr>"+ aCol.join("") +"</tr>")
		}
		oTemp.innerHTML = "";//这个赋值为空的必要性
		oTemp.innerHTML = "<table><tbody>"+ aRow.join("") +"</tbody></table>";
		while(oTemp.firstChild) oFrag.appendChild(oTemp.firstChild);
		this.oTable && oBody.removeChild(this.oTable);
		oBody.appendChild(oFrag);
		this.oTable = oBody.lastChild
	},
	CreateTable.prototype.randomRange=function(lower, upper) {
		return Math.floor(Math.random() * (upper - lower + 1) + lower)	
	},
	CreateTable.prototype.getRanColor=function() {
		var str = this.randomRange(0, 0xF0F0F0).toString(16);
		while(str.length < 6) str = "0" + str;
		return "#" + (this.bgColor.toString().replace("#", "").toString(10) === str.toString(10) ? str + 100000 : str)
	}
;
window.onload = function() {
	var table = new CreateTable();
	var row = document.getElementById("rowsNum");
	var col = document.getElementById("colsNum");
	var go = document.getElementById("go");
	var getted= document.getElementById("tablePart");
	var tip= document.getElementById("tipPart");

	go.onclick = function() {
		//隐藏信息区域
		getted.style.display = "none";
		//防止内存泄漏
		table.oTable && (table.oTable.onclick = null);
		//重新渲染表格
		table.init(row.value, col.value);
		//事件代理
		table.oTable.onclick = function(event) {//这个虽然记录过,但这里还是标记下,很经典
			event = event ||window.event;
			var anyOne = event.target || event.srcElement;
			if(anyOne.tagName.toUpperCase() === "TD") {
				tip.style.display = "block";
				tip.innerHTML = "";
				tip.innerHTML = "<span>本单元格内容为:"+anyOne.innerHTML+"</br>背景颜色为:"+anyOne.style.backgroundColor+"</span>";	
			}
		}
	}
};
</script>
4、今日的重要所得

a、就从最简单最熟悉的开始说起:获取对象源

var anyOne=event.target||window.srcElement;
这些有些兼容的意味了,ie浏览器中没有target属性,但是有srcElement属性;而firefox则恰恰相反,它有target属性,却没有srcElement,而这样写的最终目的,则是在任何浏览器下都能得到对象源,即事件产生的源头(被点击的对象)

而obj.tagName则为获得对象源的标签,而obj.parentElement则是所取对象源的父层对象,在选中一行中,这个父层对象时关键的哦,而这里的tagName同样是关键,判定为列后,对该对象进行各种设置。

b、然后是效率提升的当前新知识:文档碎片

var oFrag = document.createDocumentFragment();
oBody.appendChild(oFrag);//最终要将文档加入body中
这是动态创建html的一种经典方法,有效的避免了多次调用,提高了工作效率,这里再来看几种经典方法:

* createAttribute(name);----用指定名称name创建特性节点

*createComment(text);-----创建带文本text的注释节点

*createDoumentFragment();---创建文档碎片节点

*createElement("tagname");---创建标签名为tagname的节点

*createTextNode(text);-----------创建包含文本text的文本节点

这里已经成功应用过的只有两个,暂时只做了解吧其它的,后期用到再说

c、protatype,这个是这个里面最出彩的地方,也是最重要的地方

首先上面的那段话还可以写成

CreateTable.prototype = {
	init: function(row, col) {
		var oFrag = document.createDocumentFragment();
		var oTemp = document.createElement("div");
		var oBody = document.body;
		var aRow  = [];
		var aCol  = [];
		for(var i = row; i--;) {
			aCol.length = 0;			
			for(var j = col; j--;) {
				this.bgColor = this.getRanColor();
				aCol.push("<td style=\"background:"+ this.bgColor +";\">"+this.randomRange(1, 15)+"</td>");
			}
			aRow.push("<tr>"+ aCol.join("") +"</tr>")
		}
		oTemp.innerHTML = "";
		oTemp.innerHTML = "<table><tbody>"+ aRow.join("") +"</tbody></table>";
		while(oTemp.firstChild) oFrag.appendChild(oTemp.firstChild);
		this.oTable && oBody.removeChild(this.oTable);
		oBody.appendChild(oFrag);
		this.oTable = oBody.lastChild
	},
	randomRange: function(lower, upper) {
		return Math.floor(Math.random() * (upper - lower + 1) + lower)	
	},
	getRanColor: function() {
		var str = this.randomRange(0, 0xF0F0F0).toString(16);
		while(str.length < 6) str = "0" + str;
		return "#" + (this.bgColor.toString().replace("#", "").toString(10) === str.toString(10) ? str + 100000 : str)
	}
};
另外说下我对prototype(原型)的一些理解,此应用中用到的是对象的prototype,而在createTable中生成的雷同于java中的私有属性,而它的prototype则可以看成共有的属性,而prototype的部分就成为另一部分的原型,这里有几点需要特别注意:

1、prototype并不是对原型的继承,但是雷同于继承,它完全克隆了原型的属性和方法,但是不同于继承的是,原型方法同样可以作为当前这个的原型,而继承的话则不会有;

2、如果在原型和当前属性中都存在一个相同属性,则先在本身进行搜索设置,原型中就不再设置了


济南据说已经到了高温城市的前三甲了,悲哀啊,闷死了,prototype还得稍微再看看啊,不过那是明天的事情了,先睡觉,困...

原来这是一个经典面试题-------Day61_第2张图片





你可能感兴趣的:(JavaScript,table,动态操作)