zoukankan      html  css  js  c++  java
  • 第十四课:js操作节点的插入,复制,移除

    节点插入

    appendChild方法,insertBefore方法是常用的两个节点插入方法,具体实现,请看js高级程序设计,或者自行百度。

    这里提一下面试时经常会问到的问题,插入多个节点时,你是怎么插入的。如果你回答一个一个插入,那么每插入一次就会引起一次回流,插入100次,(面试官一般会说100,或者1000个节点的插入),就引起100次的回流,这势必让面试官觉得你连基本的东西都不懂,秒杀掉。

    其实这时你应该用到的是文档碎片,先把新建的元素插入文档碎片中,然后再一次性的把文档碎片中的元素插入到页面中。不管添加多少个,只会引起一次回流。

    节点的复制

    cloneNode,复制节点,文档碎片对象也可以通过此方法复制。

    但是IE6-IE8会自作多情的把节点上的attachEvent绑定的事件也一起复制。早些年,为了在IE6-IE8中不复制attachEvent事件,jQuery动用outerHTML复制节点。

    另外,标准浏览器的cloneNode,只会复制元素写在标签内的属性与通过setAttribute设置的属性,而IE6-IE8还支持通过node.aaa = "xxx",设置的属性复制。

    IE6-IE8不能复制script节点的text属性。

    IE6-IE8不能复制input和textarea标签的默认值。

    IE6-IE8不能复制option节点的选中状态。

    IE6-IE8不能复制checkbox和radio节点的选中状态。

    IE6-IE7不能复制checkbox和radio节点的defaultChecked属性(就是没有这个属性了)。

    所有浏览器会给没有value的checkbox一个默认的value值"on",而chrome没有。

    节点的移除

    removeChild,创建Range对象选中目标节点然后deleteContents,textContent。

    removeChild在ie6-7下有内存泄露问题.不仅跟垃圾回收有关还跟IE的DOM超空间有关。IE8尽管有DOM超空间,但是不会引起removeChild的内存泄露。

    在IE6-IE8中存在一个DOM超空间的概念,当元素被移除DOM树,又有js关联时,元素不会消失,它被保存在一个叫做超空间的地方。可以用是否存在parentNode来判断元素是否在超空间。

    举个例子:

    var div = dcoument.createElement("div");

    document.body.removeChild(documen.body.appendChild(div));     //appendChild返回新添加的节点

    div.parentNode     //IE6-8下会显示object,因为js中的div变量关联着这个div元素,所以它会存在DOM超空间中,所以它的parentNode存在。但是其他浏览器就显示null。

    if(div.parentNode )  div.parentNode.nodeType     //11   ->   文档碎片

    因此IE6-IE8下,如果内存中出现很多这样的碎片,将会很容易造成内存泄露。IE8进行了优化,所以解决了removeChild内存泄露问题。

    对于IE6-IE7删除节点的方法,可以使用innerHTML="";

    举个例子:

    var div = dcoument.createElement("div");

    documen.body.appendChild(div);

    documen.body.innerHTML = "";

    div.parentNode       //null,所有浏览器都是。

    innerHTML 方式清除节点,不会弄到DOM超空间去。

    但innerHTML删除节点,在IE6-8下也有个问题,

    举一个例子:

    <div id="test">test</div>

    var div = dcoument.getElementById("test");

    div.parentNode.removeChild(div);  

    console.log(div.id    div.innerHTML)      //test   test   所有浏览器都是。

    如果使用innerHTML ,

    div.parentNode.innerHTML ="";  

    console.log(div.id    div.innerHTML)      //test   test  标准浏览器。test  ""  IE6-IE8。

    纯粹的js操作不会带来什么消耗,95%的消耗是DOM操作引起的。因此,我们在设置样式前,将元素移除DOM树,设置完后(因为设置的样式可能有多条,如果每条都会引起重绘甚至回流,那么性能会很差),再插回来(这样只会引起一次重绘或者回流)。因为对移除DOM树的元素进行操作,不会影响DOM树。

    jQuery中,如果要实现以上功能,最好使用detach方法移除节点,因为此方法仅仅移除节点不会清除数据,而remove会清楚数据。(这里的数据是指jQuery本身的数据缓存系统中的数据)

    下面介绍几种清空元素内部的API:node可以是元素节点或文档碎片对象

    (1)while(node.firstChild)  node.removeChild(node.firstChild)

    (2)创建一个Range对象,设置边界(开始节点和结束节点),清空内容(边界里面的节点并且包括边界)。不支持ie8以及以下版本,

    var deleteRange = document.createRange();

    deleteRange.setStartBefore(node.firstChild);  

    deleteRange.setEndAfter(node.lastChild);

    deleteRange.deleteContents();

    (3)node.textContent = "";  textContent 是W3C版本的innerText(IE中的节点属性),不支持ie8以及以下版本 。     

    加油!

  • 相关阅读:
    深入解析Mysql中事务的四大隔离级别及其所解决的读现象
    MySQL的B+Tree索引
    数据库中的乐观锁与悲观锁
    github 页面及功能介绍(转载)- 很建议看看
    python 修改文件的创建时间、修改时间、访问时间
    Go-常识补充-切片-map(类似字典)-字符串-指针-结构体
    Django-djangorestframework-渲染模块
    Django-djangorestframework-请求模块-获取请求参数
    Go-函数高级使用-条件分支-包管理-for循环-switch语句-数组及切片-与或非逻辑符
    Go-环境搭建-hello world-变量常量定义-函数使用基础
  • 原文地址:https://www.cnblogs.com/chaojidan/p/4143479.html
Copyright © 2011-2022 走看看