所谓动态创建标记,就是说向页面中添加本来没有的内容。比如下面这段简单的代码:
<> <script type="text/javascript"> </script>
页面中空空如也,如果我想在body中增加一对p标签,并且中间还有内容,这就是动态创建标记。
动态创建标记一共有很多种,下面介绍其中的9种:
1.三个HTML专有方法和属性 |
document.write和innerHTML是两个HTML专有属性,关于HTML属性与DOM属性的区别可以参考这个:https://blog.csdn.net/bonjean/article/details/52741333
document.write() |
可以使用document下的write()方法来给页面添加内容。比如在body中添加这样的代码:
这是插入的文字
运用document.write就可以轻松的实现:
<script type="text/javascript"> document.write("这是插入的文字
"); </script>
这时,p标签就被插入到页面中,document.write()方法也可以把标签和字符串进行拼接,比如上面的代码还可以写成:
<script type="text/javascript"> var str = "这是插入的文字"; document.write(""); document.write(str); document.write("
"); </script>
但是想这样把HTML代码和js代码混在一起并不是很好,所以尽量避免使用document.write()方法。
innerHTML |
inner既支持写入也支持读取内容,但是这个属性无细节可言,比如下面这个实例:
这是插入的文字
<script type="text/javascript"> var p = document.getElementById("text"); alert(p.innerHTML); </script>此时弹出的警告框:
innerHTML还可以写入数据,如果把上面代码的p标签去掉,要在页面中添加内容,用innerHTML可以写成:
<script type="text/javascript"> var text = document.getElementById("text"); text.innerHTML = "
这是插入的文字
"; </script>但是如果原来的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 把这个新元素插入节点树,如使用appendChildcreateElement |
document.createElement()这个方法就是创建一个元素,还是上面的代码:
<script type="text/javascript"> </script>
想在p标签中创建一个p元素,那么首先就是使用document.createElement()方法,即:document.createElement("p");但是我们看不见任何效果,此时这个p标签是一个游荡的孤儿,我们需要把它添加到页面中,也就是p中,需要用到下面的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(要插入的元素,目标元素);
意思就是把要插入的元素插入到目标元素的前面
这是插入的文字
现在要在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的后面:
这是插入的文字1
这是插入的文字2
使用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()一次替代十次,这意味着只需要进行一个内容渲染刷新。