DOM动态创建标记
所谓动态创建标记,就是说向页面中添加本来没有的内容。比如下面这段简单的代码:
<!doctype html>
<html lang="lang">
<head>
<meta charset="UTF-8">
<title>动态创建标记</title>
</head>
<body>
<script type="text/javascript"> </script>
</body>
</html>
页面中空空如也,如果我想在body中增加一对p标签,并且中间还有内容,这就是动态创建标记。
动态创建标记一共有很多种,下面介绍其中的9种:
- document.write()
- innerHTML
- innerText
- createElement
- appendChild
- createTextNode
- insertBefore
- insertAfter(拓展)
- createDocumentFragment
1.三个HTML专有方法和属性 |
document.write和innerHTML是两个HTML专有属性,关于HTML属性与DOM属性的区别可以参考这个:http://blog.csdn.net/bonjean/article/details/52741333
document.write() |
可以使用document下的write()方法来给页面添加内容。比如在body中添加这样的代码:
<body>
<p>这是插入的文字</p>
</body>
运用document.write就可以轻松的实现:
<script type="text/javascript"> document.write("<p>这是插入的文字</p>"); </script>
这时,p标签就被插入到页面中,document.write()方法也可以把标签和字符串进行拼接,比如上面的代码还可以写成:
<script type="text/javascript"> var str = "这是插入的文字"; document.write("<p>"); document.write(str); document.write("</p>"); </script>
但是想这样把HTML代码和js代码混在一起并不是很好,所以尽量避免使用document.write()方法。
innerHTML |
inner既支持写入也支持读取内容,但是这个属性无细节可言,比如下面这个实例:
<body>
<div id="text"><p>这是插入的文字</p></div>
<script type="text/javascript"> var p = document.getElementById("text"); alert(p.innerHTML); </script>
</body>
此时弹出的警告框:
innerHTML还可以写入数据,如果把上面代码的p标签去掉,要在页面中添加内容,用innerHTML可以写成:
<body>
<div id="text"></div>
<script type="text/javascript"> var text = document.getElementById("text"); text.innerHTML = "<p>这是插入的文字</p>"; </script>
</body>
但是如果原来的p标签存在并且有其他的内容,则会替换掉原来的内容。
innerText |
innerText属性和innerHTML非常类似,都是获取标签中的内容,区别如下:
- innerHTML指的是从对象的起始位置到终止位置的全部内容,包括html标签。
- innerText指的是从起始位置到终止位置的内容,但它去除html标签。
- 同时,innerHTML 是所有浏览器都支持的,innerText 是IE浏览器和chrome 浏览器支持的,Firefox浏览器不支持。其实,innerHTML 是W3C 组织规定的属性;而innerText 属性是IE浏览器自己的属性,不过后来的浏览器部分实现这个属性罢了。
比如上面的代码,如果把innerHTML替换成innerText,则弹出的内容是“这是插入的文字”,而没有p标签。
所以综上:innerHTML是符合W3C标准的属性,而innerText只适用于IE浏览器(现在也适应其他浏览器的新版本),因此,尽可能地去使用 innerHTML,而少用innerText,如果要输出不含HTML标签的内容,可以使用innerHTML取得包含HTML标签的内容后,再用正则表达式去除HTML标签。
如果想对标签中的内容进行处理,则要用到DOM提供的方法和属性。
2.DOM提供的方法和属性 |
用DOM来插入一个元素分为两个步骤:
- 创建一个新的元素,如使用createElement
- 把这个新元素插入节点树,如使用appendChild
createElement |
document.createElement()这个方法就是创建一个元素,还是上面的代码:
<body>
<div id="text"></div>
<script type="text/javascript"> </script>
</body>
想在div标签中创建一个p元素,那么首先就是使用document.createElement()方法,即:document.createElement("p");
但是我们看不见任何效果,此时这个p标签是一个游荡的孤儿,我们需要把它添加到页面中,也就是div中,需要用到下面的appendChild方法。
appendChild |
context.appendChild()方法就是把某个元素添加到context的后面。
继续上面的例子,代码可以写成:
<script type="text/javascript"> var text = document.getElementById("text"); var word = document.createElement("p"); text.appendChild(word); </script>
或者:
document.getElementById("text").appendChild(document.createElement("p"));
createTextNode |
createElement只能创造元素节点,而document.createTextNode()方法可以创建一个文本节点。
类似的还有:
方法名 | 说明 |
---|---|
crateAttribute(name) | 用指定名称name创建特性节点 |
createComment(text) | 创建带文本text的注释节点 |
createDocumentFragment() | 创建文档碎片节点 |
createElement(tagname) | 创建标签名为tagname的节点 |
createTextNode(text) | 创建包含文本text的文本节点 |
如果我想在p标签中添加“这是插入的文字”,用createTextNode方法可以写成:
document.createTextNode("这是插入的文字");
然后再用appendChild属性插入到p标签中,完整代码如下:
<script type="text/javascript"> var text = document.getElementById("text"); var word = document.createElement("p"); text.appendChild(word); var newText = document.createTextNode("这是插入的文字"); word.appendChild(newText); </script>
insertBefore |
insertBefore()方法可以把一个新元素插入到一个现有元素的前面,
语法是:parentElement.insetBefore(newElement,targetElement);
翻译过来就是:现有元素的父元素.insetBefore(要插入的元素,目标元素);
意思就是把要插入的元素插入到目标元素的前面
<div id="text">
<p>这是插入的文字</p>
</div>
现在要在p元素的前面再添加一个p元素,内容是“这是插入的文字2”。
首先需要创建一个元素:
var text = document.createElement("p");
给这个p标签添加内容:
var _text = document.createTextNode("这是插入的文字2");
var element = text.appendChild(_text);
把元素添加到页面去:
var oDiv = document.getElementById("text");
oDiv.appendChild(element);
此时新建的p标签被添加到原来标签的后面,再用insertBefore()调整位置:
var text2 = document.getElementById("text2");
oDiv.appendChild(element);
element.parentNode.insertBefore(element,text2);
insertAfter(拓展) |
insertAfter()方法在DOM中是没有的,不过我们可以自己写一个方法,它的作用是在现有元素后插入一个新元素。
function insertAfter(newElement, targetElement) {
var parent = targetElement.parentNode;
if (parent.lastChild == targetElement) {
targetElement.appendChild(newElement);
} else {
parent.insertBefore(newElement, targetElement.nextSibling);
}
}
使用insertAfter()方法:
想把下面代码中的第一个p元素移到id是text2的后面:
<div id="text">
<p id="text1">这是插入的文字1</p>
<p id="text2">这是插入的文字2</p>
</div>
使用insertAfter()方法代码如下:
insertAfter(document.getElementById("text1"), document.getElementById("text2"));
createDocumentFragment |
document.createDocumentFragment()方法是创建一个文档碎片。
在代码中要尽量减少DOM的回流,尽可能使用重绘,比如想创建十个段落,使用常规的方式可能会写出这样的代码:
for(var i = 0 ; i < 10; i ++) {
var p = document.createElement("p");
var oTxt = document.createTextNode("段落" + i);
p.appendChild(oTxt);
document.body.appendChild(p);
}
代码中调用了十次document.body.appendChild(),每次都要产生一次页面渲染,影响性能,这时碎片就十分有用了:
var oFragment = document.createDocumentFragment();
for(var i = 0 ; i < 10; i ++) {
var p = document.createElement("p");
var oTxt = document.createTextNode("段落" + i);
p.appendChild(oTxt);
oFragment.appendChild(p);
}
document.body.appendChild(oFragment);
在这段代码中,每个新的p元素都被添加到文档碎片中,然后这个碎片被作为参数传递给appendChild()。这里对appendChild()的调用实际上并不是把文档碎片追加到body元素中,而是仅仅追加碎片中的子节点,然后可以看到明显的性能提升,document.body.appenChild()一次替代十次,这意味着只需要进行一个内容渲染刷新。
还没有评论,来说两句吧...