结点操作
一、结点的创建
1 document.createElement( )
标准:传入一个标签名,支持非标准的标签名 document.createElement("c")
IE6-7:可以传入连同用户一起生成
document.createElement("<input name='name'>")
eg:
//http://thunderguy.com/semicolon/2005/05/23/setting-the-name-attribute-in-internet-explorer/
function createNamedElement(type, name) {
var element = null;
// Try the IE way; this fails on standards-compliant browsers
try {
element = document.createElement('<' + type + ' name="' + name + '">');
} catch (e) {
}
if (!element || element.nodeName != type.toUpperCase()) {
// Non-IE browser; use canonical method to create named element
element = document.createElement(type);
element.name = name;
}
return element;
}
2 innerHTML
innerHTML的创建效率比createElement快2到10倍
测试代码
var start = new Date();
for(var i = 0 ;i<1000;i++){
document.createElement("c");
}
var end = new Date();
console.log(end-start)
var start = new Date();
var str =""
for(var i = 0 ;i<1000;i++){
str += "<c></c>"
}
document.innerHTML=str;
var end = new Date();
console.log(end-start)
测试结果却是快了最少2倍
innerHTML可以一次生成一大堆结点。
- 在IE6-8中使用innerHTML会对用户字符串进行trimLeft操作。
- 在IE中有些元素结点是只读的,重写innerHTML会报错。结点有
注释,style,script,link,meta,noscript
- innerHTML不会执行script中的脚本。(有defer属性时候)能执行脚本。
- 有的标签不能单独作为div的子元素,比如td,th,需要在最外面包几层,才能放到innerHTML中解释。否则浏览器会当做普通的文本结点生成。
3 insertAdjacentHTML
insertAdjacentHTML是IE私有实现的产物,兼容性比较差。有灵活的插入方式
如果不支持的insetAdjacentHTML,模拟的如下:
if (typeof HTMLElement !== "undefined" &&
!HTMLElement.prototype.insertAdjacentElement) {
HTMLElement.prototype.insertAdjacentElement = function(where, parsedNode) {
switch (where.toLowerCase()) {
case 'beforebegin':
this.parentNode.insertBefore(parsedNode, this)
break;
case 'afterbegin':
this.insertBefore(parsedNode, this.firstChild);
break;
case 'beforeend':
this.appendChild(parsedNode);
break;
case 'afterend':
if (this.nextSibling)
this.parentNode.insertBefore(parsedNode, this.nextSibling);
else
this.parentNode.appendChild(parsedNode);
break;
}
}
HTMLElement.prototype.insertAdjacentHTML = function(where, htmlStr) {
var r = this.ownerDocument.createRange();
r.setStartBefore(this);
var parsedHTML = r.createContextualFragment(htmlStr);
this.insertAdjacentElement(where, parsedHTML)
}
HTMLElement.prototype.insertAdjacentText = function(where, txtStr) {
var parsedText = document.createTextNode(txtStr)
this.insertAdjacentElement(where, parsedText)
}
}
createContextualFragment: Firefox私有属性
是Range对象的一个实力方法。相当于insertAdjacentHTML直接将内容插入到DOM树,createContextFragment允许将字符串转换为文档碎片。
通过两个构造器与一个原型实现无new实例化,这样的话链式操作不会被new关键字打断
function $(a, b) { //第一个构造器
return new $.fn.init(a, b); //第二个构造器
}
//将原型对象放到一个名字更短、更好记的属性中
//这是jQuery人性化的体现,也方便扩展原型方法
$.fn = $.prototype = {
init: function(a, b) {
this.a = a;
this.b = b;
}
}
//共用同一个原型
$.fn.init.prototype = $.fn;
var a = $(1, 2);
console.log(a instanceof $); //true
console.log(a instanceof $.fn.init); //true
传入一大推的字符成长一堆结点的功能由parseHTML方法实现。
////TODO
实现html需要注意的事情
如何实现
对应浏览器处理问题