1. myList.cloneNode(true); 在参数为true的情况下,执行深复制,也就是复制节点及其整个子节点树,包括属性

2. myList.cloneNode(false); 在参数为false 的情况下,执行浅复制,即只复制节点本身,包括属性

  cloneNode()方法不会复制添加到DOM 节点中的JavaScript 属性,例如事件处理程序等。这个方法只复制特性、(在明确指定的情况下也复制)子节点,其他一切都不会复制。IE 在此存在一个bug,即它会复制事件处理程序,所以我们建议在复制之前最好先移除事件处理程序。

3. Node类型 

  DOM1 级定义了一个Node 接口,该接口将由DOM 中的所有节点类型实现。这个Node 接口在JavaScript 中是作为Node 类型实现的;除了IE 之外,在其他所有浏览器中都可以访问到这个类型。JavaScript 中的所有节点类型都继承自Node 类型,因此所有节点类型都共享着相同的基本属性和方法。每个节点都有一个nodeType 属性,用于表明节点的类型。节点类型由在Node 类型中定义的下列12 个数值常量来表示,任何节点类型必居其一:

 Node.ELEMENT_NODE(1);
 Node.ATTRIBUTE_NODE(2);
 Node.TEXT_NODE(3);
 Node.CDATA_SECTION_NODE(4);
 Node.ENTITY_REFERENCE_NODE(5);
 Node.ENTITY_NODE(6);
 Node.PROCESSING_INSTRUCTION_NODE(7);
 Node.COMMENT_NODE(8);

 Node.DOCUMENT_NODE(9);
 Node.DOCUMENT_TYPE_NODE(10);
 Node.DOCUMENT_FRAGMENT_NODE(11);
 Node.NOTATION_NODE(12)。

4. DocumentFragment类型 文档片段

文档片段继承了Node 的所有方法,通常用于执行那些针对文档的DOM操作。如果将文档中的节点添加到文档片段中,就会从文档树中移除该节点,也不会从浏览器中再看到该节点。添加到文档片段中的新节点同样也不属于文档树。可以通过appendChild()或insertBefore()将文档片段中内容添加到文档中。在将文档片段作为参数传递给这两个方法时,实际上只会将文档片段的所有子节点添加到相应位置上;文档片段本身永远不会成为文档树的一部分。来看下面的HTML 示例代码:

<ul id="myList"></ul>
假设我们想为这个<ul>元素添加3 个列表项。如果逐个地添加列表项,将会导致浏览器反复渲染(呈现)新信息。为避免这个问题,可以像下面这样使用一个文档片段来保存创建的列表项,然后再一次性将它们添加到文档中。
var fragment = document.createDocumentFragment();
var ul = document.getElementById("myList");
var li = null;
for (var i=0; i < 3; i++){
li = document.createElement("li");
li.appendChild(document.createTextNode("Item " + (i+1)));
fragment.appendChild(li);
}
ul.appendChild(fragment);

在这个例子中,我们先创建一个文档片段并取得了对<ul>元素的引用。然后,通过for 循环创建3 个列表项,并通过文本表示它们的顺序。为此,需要分别创建<li>元素、创建文本节点,再把文本节点添加到<li>元素。接着使用appendChild()将<li>元素添加到文档片段中。循环结束后,再调用appendChild()并传入文档片段,将所有列表项添加到<ul>元素中。此时,文档片段的所有子节点都被删除并转移到了<ul>元素中。

5.使用NodeList

理解NodeList 及其“近亲”NamedNodeMap 和HTMLCollection,是从整体上透彻理解DOM的关键所在。这三个集合都是“动态的”;换句话说,每当文档结构发生变化时,它们都会得到更新。因此,它们始终都会保存着最新、最准确的信息。从本质上说,所有NodeList 对象都是在访问DOM文档时实时运行的查询。例如,下列代码会导致无限循环:

var divs = document.getElementsByTagName("div"),
i,
div;
for (i=0; i < divs.length; i++){
div = document.createElement("div");
document.body.appendChild(div);
}

第一行代码会取得文档中所有<div>元素的HTMLCollection。由于这个集合是“动态的”,因此只要有新<div>元素被添加到页面中,这个元素也会被添加到该集合中。浏览器不会将创建的所有集合都保存在一个列表中,而是在下一次访问集合时再更新集合。结果,在遇到上例中所示的循环代码时,就会导致一个有趣的问题。每次循环都要对条件i < divs.length 求值,意味着会运行取得所有<div>元素的查询。考虑到循环体每次都会创建一个新<div>元素并将其添加到文档中,因此divs.length 的值在每次循环后都会递增。既然i 和divs.length 每次都会同时递增,结果它们的值永远也不会相等。如果想要迭代一个NodeList,最好是使用length 属性初始化第二个变量,然后将迭代器与该变量进行比较,如下面的例子所示:
var divs = document.getElementsByTagName("div"),
i,
len,
div;
for (i=0, len=divs.length; i < len; i++){
div = document.createElement("div");
document.body.appendChild(div);
}
这个例子中初始化了第二个变量len。由于len 中保存着对divs.length 在循环开始时的一个快照,因此就会避免上一个例子中出现的无限循环问题。在本章演示迭代NodeList 对象的例子中,使用的都是这种更为保险的方式。一般来说,应该尽量减少访问NodeList 的次数。因为每次访问NodeList,都会运行一次基于文档的查询。所以,可以考虑将从NodeList 中取得的值缓存起来。

js复制对象 和 节点类型和NodeList的更多相关文章

  1. js原型对象与Java类的比较

    在我学习Javascript的原型对象时,我总是不自觉地拿Java的类思想来做比较,时间久了,我渐渐认识到二者有巨大的不同. 首先,类是不能直接当方法来运行,它最简便的方式是调用其静态方法:而原型对象 ...

  2. js 复制对象的深复制与浅复制

    1.潜复制(修改新对象会改变原对象) var baz = {a:'hello', b: {c:'my', d:'friend'}} var foo = baz foo.a="better&q ...

  3. JS基础_数据类型-Null类型和Undefined类型

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. JS 复制对象

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs& ...

  5. JS复制对象

    CSSCommonJS.DeepCopy = function (json) { if (typeof json == 'number' || typeof json == 'string' || t ...

  6. 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间

    [源码下载] 速战速决 (5) - PHP: 动态地创建属性和方法, 对象的复制, 对象的比较, 加载指定的文件, 自动加载类文件, 命名空间 作者:webabcd 介绍速战速决 之 PHP 动态地创 ...

  7. 关于js的闭包和复制对象

    一.有关js的闭包 1.概念:所谓的闭包,就是指的两个作用域,其中内层作用于可以访问外层作用域的函数的现象 2.简单应用 for(var i = 0;i< lis.lenth;i++){ (fu ...

  8. js中Boolean类型和Number类型的一些常见方法

    Boolean类型 Boolean类型重写了valueOf() 方法, 返回基本布尔类型值true或false,重写了toString() 方法,返回基本字符串"true" 和 & ...

  9. java中复制对象通过反射或序列化

    在使用缓存读取数据后修改发现缓存被修改.于是找了下复制对象的方法. 关于对象克隆 按我的理解,对象是包含引用+数据.通常变量复制都是将引用传递过去.比如: Person p1 = new Person ...

随机推荐

  1. linux清理僵尸进程

    查看服务器时发现好3个僵尸进程,僵尸进程存在好多天了,一直不会处理,留到了今天,顺便清理下僵尸进程吧 top命令中统计了僵尸进程,是第二行最后一项3 zombie. 或者使用下面的命令得到僵尸进程数量 ...

  2. Python新手学习基础之条件语句——if/else语句

    if/else语句 条件语句实际在前面的文章里我们已经使用过几次了,在这里我们需要再次隆重的来介绍一下它,条件语句是通过对一条或多条语句判断的返回结果(True或False)来选择执行下一步命令的,比 ...

  3. struct tm->time() localtime() gmtime()

    struct tm->time() localtime() gmtime() struct tm { int tm_sec; /*代表目前秒数,正常范围为0-59,但允许至61秒 */ int ...

  4. RichTextBox控件日常使用集合

    1.RichTextBox控件自动滚动到底部 richTextBox1.ScrollToCaret(); //将控件的内容滚动到当前光标位置

  5. GO实例3 Slice append打印

    package main import "fmt" func main(){ ]int slice:=array[:] slice[]='a' slice[]='b' s1:=ap ...

  6. 从现在开始使用nodejs开发的几点答疑

    1.为什么要开始用nodejs, 而不是php 理由有三点: 因为我是前端程序员出身,nodejs都是用javascript写的,这样相当于前端和后端都使用javascript,开发更加有效率.当然很 ...

  7. translate函数说明

    TRANSLATE(expr, from_string, to_string) from_string 与 to_string 以字符为单位,对应字符一一替换. SQL> SELECT TRAN ...

  8. 掌握 Java 8 Lambda 表达式

    Lambda 表达式 是 Java8 中最重要的功能之一.使用 Lambda 表达式 可以替代只有一个函数的接口实现,告别匿名内部类,代码看起来更简洁易懂.Lambda 表达式 同时还提升了对 集合 ...

  9. MyEclipse第一个Servlet程序 --解决Win7系统下MyEclipse与Tomcat连接问题

    前言 本文旨在帮助学习java web开发的人员,熟悉环境,在Win7系统下运行自己的第一个Servlet程序,因为有时候配置不当或系统原因可能会运行不成功,这给初学者带来了一定烦恼,我也是为此烦恼过 ...

  10. python数据类型-布尔值

    布尔是计算机里最基本的判断单位,布尔只有两个值:真或假,即True False,也就是1或0. 在以后学习流程控制时会经常用到布尔值. 先来看简单的小例子: >>> 1+1 > ...