DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序编程接口)。DOM描绘了一个层次节点树,允许开发人员添加、移除和修改。

1.节点层次

<html>
  <head>
      <title>Simple Page</title>
  </head>
  <body>
      <p>Hello World!</p>
  </body>
</html>

如上的HTML文档,可以表示为一个层次结构。

文档元素:每个文档的根节点,即<html>元素。文档元素是文档最外层的元素,文档中其他元素都包含在文档元素中。每个文档只能有一个文档元素。在HTML页面中,文档元素始终都是<html>元素。在XML中,没有预定义的元素,因此任何元素都可以成为文档元素。

注意:Element titile->Text Simple Page。这个在dom节点操作的时候,不要将text这个节点忘记。

1.1Node类型

节点类型由Node类型中定义的下列数值常量白哦是,任何节点类型必居其一。

  • 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)

确定节点类型:

if(someNode.nodeType == Node.ELEMENT_NODE){  //在IE中无效,因为IE没有公开Node类型的构造函数
        alert("Node is an element");
}
if(someNode.nodeType == 1){      //适用于所有浏览器
    alert("Node is an element");
}

nodeName和nodeValue属性

if(someNode.nodeType == 1){
    value = someNode.nodeName;    //nodeName 的值是元素的标签名,因此需要先判断是否是元素
}

NodeList:一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点,但是他并不是Array的实例,虽然这个对象也有length属性。NodeList对象的独特之处在于,它实际上是基于DOM结构动态执行查询结果,因此DOM结构的变化能够自动反映在NodeList对象中。

var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;

someNode指的是父节点,childNodes指的是父节点下面所有的子节点,包括text。

将NodeList转换为数组,

//在IE8及之前版本中无效
var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes,0);
//兼容
function convertToArray(nodes){
    var array = null;
    try{
        array = Array.prototype.slice.call(nodes,0);//针对非IE浏览器
    }catch(ex){
        array = new Array();
        for(var i=0,len=nodes.length;i<len;i++){
            array.push(nodes[i]);
        }
    }
    return array;
}

父节点与同胞节点

对于上述的每个childNodes都有同一个父节点,它们的parentNode属性都指向同一个节点。此外,包含在childNodes列表中的每个节点相互之间都是同胞节点。对于一个节点而言,它有previousSibling和nextSibling属性,对应前后两个节点。

2.操作节点

2.1appendChild(),用于向childNodes列表的末尾添加一个节点。更新完成以后将会返回更新节点。

注意:如果传入到appendChild()中的节点已经是文档的一部分了,那结果就是将该节点从原来的位置转移到新位置。

2.2insertBefore(),接受两个参数:要插入的节点和作为参照的节点。插入节点以后,被插入的节点会变成参照节点的前一个同胞节点(previousSibing),同时被方法返回。

//插入称为最后一个节点
returnNode = someNode.insertBefore(newNode,null);
alert(newNode === someNode.lastChild);    //true

//插入后成为第一个节点
var returnedNoe = someNode.insertBefore(newNode,someNode.firstChild);
alert(returnedNode === someNode.newNode);  //true
alert(newNode === someNode.firstNode);  //true

//插入到最后一个子节点前面
returnedNode = someNode.insertBefore(newNode,someNode.lastChild);  
alert(newNode === someNode.childNodes[someNode.childNodes.length - 2]);  //true

(注:根据《JavaSctipt语言精粹》的建议,将“==”改为“===”,有兴趣的可以看一下这本书,总共只有155页)

2.3replaceChild(),接受两个参数:要插入的节点和要替换的节点。要替换的节点将会被删除,而以上两种方法并不会删除节点。

使用replaceChild()插入一个节点时,该节点的所有关心指针都会从被它替换的节点复制过来。尽管从技术上将,被替换的节点仍然还在文档中占据位置。

2.4removeChild(),移除节点,这个方法接受一个参数,即要移除的节点。被移除的节点将成为方法的返回值。与replaceChild()一样,通过removeChild()移除的节点仍然为文档所有,只不过在文档中已经没有了自己的位置。

注意:以上方法必须先获得父节点parentNode,并不是所有类型的节点都有子节点,如果在不支持子节点的节点上调用了这些方法,将导致错误。

2.5cloneNode()用于创建调用这个方法的节点的一个完全相同的副本。

someNode.cloneNode(true/false);

true:表示执行深复制,即复制节点及其整个子节点树。

false:表示浅复制,即只复制节点本身。

这里需要注意的是:IE9之前的版本不会为空白符创建节点。还有一个IE中存在的bug就是,它会复制事件处理程序,所以这里建议在复制之前最好先移除事件处理程序。

3.Document类型

简单来说,在浏览器中,document用于表示HTML页面的最底层节点。可以直接使用它来获取页面上的任意节点。可以试着通过document.nodeChilds进行测试。在console中我们可以看到NodeList[2]……

Document节点的特征:

nodeType:9;nodeName:"#document";nodeValue:null;parentNode:null;ownerDocument:null;

子节点:DocumentType(最多一个)、Element(最多一个)、ProcessingInstruction或Comment。

3.1文档子节点

内置了两个访问其子节点的快速方式:documentElement,该属性始终指向HTML页面中<html>元素。另一个就是通过childNodes列表访问文档元素。

这里需要注意的是,一般情况下我们的页面开始是<!DOCTYPE html>,有这个在页面中时,document.childNodes获取的第一个是<!DOCTYPE html>,要通过childNodes遍历得到html元素是document.childNodes[1],使用从整个子节点获取需要看具体情况分析。

直接获取属性:

var body = document.body;        //获取对<body>的引用
var doctype = document.doctype;     //获取对<!DOCTYPE>的引用

浏览器对于document.doctype的支持不一致,因此这个属性并不常用。

同样还需要注意的是关于在html外面的注释是否是节点这个问题,不同的浏览器处理是不一样的。

3.2文档信息

//获取文档标题
var originalTitle = document.title;

//设置文档标题
document.title = "New page title";

//获取完整的URL
var url = document.URL;

//获得域名
var domain = document.domain;

//获得来源页面的URL
var referrer = document.referrer;

URL、domain、referrer三个属性都和页面请求有关

document.URL
>"http://www.cnblogs.com/lyhabc/p/6131034.html"
document.domain
>"www.cnblogs.com"
document.referrer
>"http://www.cnblogs.com/"

随便开个页面输出一下,我们可以看到三个属性的差别。

在这三个属性中,只有domain是可以设置的。但由于安全方面的限制,并非可以给domain设置任何值。

例如上面这个页面,只能写 document.domain = "www.cnblogs.com"/ document.domain = "cnblogs.com",由于跨域安全设置,来自不同子域的页面无法通过javascript通信,而通过将每个页面的document.domain设置为相同值,这些页面就可以相互访问对方的javascript对象了。

在内嵌框架中会使用到这个。(http://www.3lian.com/edu/2015/05-22/215443.html这个讲的比较粗浅明白)

3.3查找元素

这个是重点!!!!!!!

1.getElementById(),通过接收获取元素的ID来找到对应元素,这里的ID必须与页面中元素的id严格对应。

这里要注意的是:在IE7及更早的版本中并不区分id的大小写,还有如果页面中存在多个相同的id值,那么它会返回第一个出现的元素。

另一个问题是,表单字段的name特性,在IE7种通过getElementById()将会去与表单中name值进行匹配。因此最好不要让表单字段的name特性与其他元素的ID相同。

2.getElementsByTagName(),通过接受一个参数获取元素的标签名,返回的是包含零个或多个元素的NodeList。

这里有个“动态”集合的概念

例如,在页面中有多个div

var list = document.getElementsByTagName('div');
console.log(list.length);      

document.body.appendChild(document.createElement('div'));

在浏览器中,直接输出list.length是9。

对于图像元素来说,还有以下方法。

var imges = document.getElementsByTagName("img");

<img src="myimage.gif" name="myImage">

var myImage = images.namedItem("myImage");
var myImage = images["myImage"];

imgaes[0].src;  //输出第一个图像元素的src特性

3.getElemnetsByName() ,是只有HTMLDocument类型才有的,即返回带有给定name特性的所有元素。

常见案例是单选按钮,它们的name必须是一样的。对于单选按钮来说,namedItem()方法只会取得第一项。

4.其他集合,这些都是HTMLCollection对象

document.anchors,包含文档中所有带name特性的<a>元素

document.forms,包含文档中所有<form>元素

document.images包含文档中所有<img>元素

document.link,包含文档中所有带href特性的元素

5.DOM一致性检测

DOM分为多个级别,也包含多个部分。

document.implementation属性提供相应信息和功能

  1. DOMImplementation
    1. __proto__:DOMImplementation
      1. constructor:DOMImplementation()
      2. createDocument:createDocument()
      3. createDocumentType:createDocumentType()
      4. createHTMLDocument:createHTMLDocument()
      5. hasFeature:hasFeature()
      6. Symbol(Symbol.toStringTag):"DOMImplementation"
      7. __proto__:Object

这里主要是使用hasFeature()进行版本检测

var hasXmlDom = document.implementation.hasFeature("XML","1.0");

通过返回的布尔值判断是否是对应版本。

这个功能并不常用,一般情况下,我们在使用一个属性判断是否可以在各种浏览其中使用时,可以直接使用通过try-catch来进行兼容。

3.6文档写入

write()、writelin()、open()、close()

write()会原样写入,writeln()会在字符串末尾添加换行符\n

这里需要注意的是,如果你在文档加载完成后使用了write()或writeln()写入,那么写入的内容将会重新整个页面。

它们可以进行HTML代码的处理,也可以写入<script>只是需要转义符。

4.Element类型

Element类型用于表现XML或HTML元素,提供了对元素标签名、子节点及特性的访问。Element节点具有以下特征:

nodeType 的值为1

nodeName 的值为元素的标签名;

nodeValue 的值为null;

parentNode 可能是Document或Element;

nodeName和tagName用于访问元素的标签名

<div id="myDiv"></div>

var div = document.getElementBId("myDiv");

alert(div.tagName);//"DIV"

alert(div.tagName === div.nodeName);//true

在HTML中,表签名始终以大写表示;而在XML中(有时候也包括XHTML)中,标签名始终与源代码中的保持一致。

所以要比较的时候最好使用:

if(element.tagName.toLowerCase() === "div"){

}

4.1HTML元素

id,元素在文档中唯一标识符。

title,有关元素的附加说明,一般通过工具提示条显示出来。

lang,元素内容的语言代码,很少使用。

dir,语言方向,值为“ltr”(left-to-right,从左至右)或“rtl”(right-to-left,从右至左),也很少使用。

className,与元素class特性对应,即为元素指定的CSS类。没有将这个属性命名为class,是因为class是ECMAScript的保留字。

(这里插一条,在IE8及以下,无法使用getElementsByClassName()获取对应的元素,因此通过className进行兼容)

<div id="myDiv" class="bd" title="Body text" lang="en" dir="ltr"></div>

var div = document.getElementById("myDiv");

div.id    //"myDiv"
div.className   //"bd"
div.title    //"Body text"
div.lang    //"en"
div.dir    //"ltr"

同时也可以进行修改

div.id = "somOtherId";
div.className = "ft";
div.title = "Some other text";
div.lang = "fr";
div.dir = "rtl";

操作特性的DOM三个主要方法:getAttribute()、setAttribute()、removeAttribute()

4.2取得特性,getAttribute()

var div = document.getElementById("div");
alert(div.getAttribute("id"));    //"myDiv"
alert(div.getAttribute("class"));
alert(div.getAttribute("title"));
alert(div.getAttribute("lang"));
alert(div.getAttribute("dir"));

注意:传递给getAttribute()的特性名与实际的特性名相同。因此要想得到class特性值,应该传入“class”而不是“className”,后者只有在通过对象属性访问特性的时候才使用。

可以使用自定义特性,同时特性名词不区分大小写。

根据HTML5规定,自定义特性应该加上data-前缀以便验证,实际浏览器不添加该前缀并不会报错,但是最好按照标准来。

对于HTML中公认的特性,该元素的DOM对象也将存在对应的属性。

对于特殊的存在:style和onclick类似事件处理程序

通过getAttribute()访问时,返回的style特性值中包含css文本,而通过属性来访问它则会返回一个对象。注意,这里是指的内联样式。

document.getElementById("d").getAttribute("style");
 >"backgroundColor:red;font-size:10px;"
document.getElementById("d").style;
>CSSStyleDeclaration {0: "font-size", alignContent: "", alignItems: "", alignSelf: "", alignmentBaseline: "", all: ""…}

onclick这样的事件处理程序。当在元素上使用时,通过getAttribute()访问,则会返回相应代码的字符串。而在访问onclick属性时,则会返回一个JavaScript函数。

一般不建议获取HTML公认特性的时候使用getAttribute(),而是使用对象属性。

4.3设置特性

div.setAttribute("id","someOtherId");
div.setAttribute("class","ft");
div.setAttribute("title","Some other text");
div.setAttribute("lang","fr");
div.setAttribute("dir","rtl");

这个方法既可以操作HTML特性也可以操作自定义特性,而div.id = "someOtherId"这种方法不可以操作自定义特性。

4.4removeAttributes()

这个方法用于彻底删除元素的特性。调用这个方法不仅会清除特性的值,而且也会从元素中完全删除特性。

4.5document.createElement()创建新元素

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

创建完成以后,可以痛过操作元素特性添加更多子节点以及其他操作。

div.id = "myNewDiv";

div.className = "box";

通过appendChild()、insertBefore()、replaceChild()方法,添加到文档树中。

在IE7以及更早的版本中,有以下已知问题:

不能设置动态创建的<iframe>元素的name特性。

不能通过表单的reset()方法重设动态创建的<input>元素。

动态创建的type特性值为“reset”的<button>元素重设不了表单。

动态创建的一批name相同的单选按钮彼此毫无关系。

这些问题可以通过createElement()中指定完整的HTML标签来解决。

    if(client.browser.ie && client.browser.ie<=7){
            //创建一个带有name特性的iframe元素
            var iframe = document.createElement("<iframe name = \"myframe\"></iframe>");
            //创建input元素
            var input = document.createElement("<input type = \"checkbox\">");
            //创建button元素
            var button = document.createElement("<button type=\"reset\"></button>");
            //创建单选按钮
            var radio1 = document.createElement("<input type=\"radio\" name=\"choice\" value=\"1\"");
            var radio2 = document.createElement("<input type=\"radio\" name=\"choice\" value=\"2\"");
        }

5.关于元素的子节点的差别childNode获得的节点

<ul id="myList">
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
</ul>

在IE中,<ul>元素会有3个子节点,分别是3个<li>元素。但如果是在其他浏览器中,<ul>会有7个元素,包括3个<li>元素和4个文本节点(包括<li>元素之间的空白符)

通过childNodes属性遍历nodeType属性,需要element.childNodes[i].nodeType === 1,判断一下。

6.Text类型

nodeType的值为3;

nodeName的值为“#text”;

nodeValue的值为节点所包含的文本;

parentNode是一个element;

不支持(没有)子节点。

在默认情况下,一个元素最多只能包含有一个文本系欸但,而且必须确实存在内容。

var textNode = div.firstChild;//获取文本节点

div.firstChild.nodeValue = "Some other message";  //修改文本节点中nodeValue内容

div.firstChild.nodeValue = "Some <strong>other</strong> message";

输出结果是"Some &lt;strong&gt;other&lt;/strong&gt; message";

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

本来标题应该是【JavaScript整理】,想要整理的稍微规范并且全面些,拿出了“尘封已久”的《JavaScript高级程序设计》,然后在强迫症的作用下一发不可收拾成了笔记摘录了。这本书还是强烈推荐都看看的,虽然很厚,不过有时候弯路才是真正的捷径,在对学习前端开始入门并且感兴趣以后,可以回归书本一下。

顺便推荐本书:《CSS禅意花园》

【javascript学习——《javascript高级程序设计》笔记】DOM操作的更多相关文章

  1. js高级程序设计 笔记 --- DOM

    DOM是针对HTML和XML文档的一个API.DOM描绘了一个层次化的节点树,允许开发人员添加.移除和修改页面的某一部分. 1,节点层次 DOM可以将任何HTML或XML文档描绘成一个由多层节点构成的 ...

  2. js高级程序设计笔记之-addEventListener()与removeEventListener(),事件解除与绑定

    js高级程序设计笔记之-addEventListener()与removeEventListener(),事件解除与绑定 addEventListener()与removeEventListener( ...

  3. Java高级程序设计笔记 • 【目录】

    持续更新中- 我的大学笔记>>> 章节 内容 实践练习 Java高级程序设计作业目录(作业笔记) 第1章 Java高级程序设计笔记 • [第1章 IO流] 第2章 Java高级程序设 ...

  4. 《JAVASCRIPT高级程序设计》DOM扩展

    虽然DOM为XML及HTML文档交互制定了一系列的API,但仍然有几个规范对标准的DOM进行了扩展.这些扩展中,有很多是浏览器专有的,但后来成了事实标准,于是其他浏览器也提供了相同的实现:浏览器开发商 ...

  5. JavaScript学习总结(一)DOM文档对象模型

    一.文档(D) 一个网页运行在浏览器中,他就是一个文档对象. 二.对象(O) "对象"是一种自足的数据集合.与某个特定对象相关联的变量被称为这个对象的属性,只能通过某个对象调用的函 ...

  6. jquery学习笔记---Dom操作

    一.DOM操作的分类 DOM(document object model)是一种与浏览器.平台.语言无关的接口,使用该接口可以访问页面中的·所有组件.DOM的操作可以分为DOM Core.HTML-D ...

  7. JavaScript高程第三版笔记-DOM扩展

    在那个刀耕火种的年代,用过jQuery的都体会到了jQuery带来的便捷,尤其是元素选择器. jQuery(www.jquery.com)的核心就是通过 CSS 选择符查询 DOM 文档取得元素的引用 ...

  8. jQuery学习之旅 Item4 细说DOM操作

    jQuery-–DOM操作(文档处理) Dom是Document Object Model的缩写,意思是文档对象模型.DOM是一种与浏览器.平台.语言无关的接口,使用该接口可以轻松访问页面中所有的标准 ...

  9. 【jQuery基础学习】02 jQuery的DOM操作

    DOM操作分为3个方面: DOM Core    任何一种支持DOM Core的语言都可以使用它,比如getElementById就是DOM Core操作 HTML-DOM  只能用来处理web文档 ...

  10. javascript高级程序设计--笔记01

    概述 JavaScript的实现包含三个部分: 1  核心(ECMAScript)   提供核心语言功能 2  文档对象模型(DOM)  一套提供了访问以及操作网页内容的API 3  浏览器对象模型( ...

随机推荐

  1. JS 验证数组中是否包含重复元素

    验证JS中是否包含重复元素,有重复返回true:否则返回false 方案一. function isRepeat(data) { var hash = {}; for (var i in data) ...

  2. 【转载】Python与ArcGIS Engine的集成

    本文转载自Fransico<Python与ArcGIS Engine的集成>   1 在Python中调用AO类库 1.1  准备工作 本文所使用环境:ArcGIS 10.0.Python ...

  3. 高斯混合模型(GMM)

    复习: 1.概率密度函数,密度函数,概率分布函数和累计分布函数 概率密度函数一般以大写“PDF”(Probability Density Function),也称概率分布函数,有的时候又简称概率分布函 ...

  4. PHP ajax基础

    后台对数据处理,并返回前台: <?php //接收 $action = $_GET['action']; if ($action == 'orderID') { $orderID = trim( ...

  5. IIS ARR 负载均衡

    阅读:http://www.cnblogs.com/jesse2013/p/dlws-loadbalancer2.html 自定义端口:http://www.th7.cn/Program/net/20 ...

  6. Windows10更新提示语言不同不能保留程序和设置

    打开注册表编辑器(Win+R,输入regedit)定位到: HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Nls\Language 在右边窗口中拉到最 ...

  7. Two Sum Leetcode Java

    Given an array of integers, return indices of the two numbers such that they add up to a specific ta ...

  8. 记录一下git 的常用命令

    以后如果要写一个东西,最好先搭建一个本地仓库,用版本控制对其进行操作,可能一开始有一些麻烦,但是很有可能会受益无穷. 说到git,必然会和github联系起来. 不管是在ubuntu里面还是在Wind ...

  9. Linq查询表达式

    目录 1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. ...

  10. 自定义el函数

    1.1.1 自定义EL函数(EL调用Java的函数) 第一步:创建一个Java类.方法必须是静态方法. public static String sayHello(String name){ retu ...