1.DOM是什么

D=document(文档)

O=object(对象)

M=Model(模型)

DOM又称节点树

一些术语:

parent(父)   child(子)   sibling(兄弟)   node(节点)

element node(元素节点)   text node(文本节点)

2.获取元素

1.getElementById(与typeof操作符)

//getElementById 与 typeof
//typeof操作符可以告诉我们它的操作数是一个字符串、数值、函数、布尔值还是对象
//getElementById会返回一个对象,且该调用只能有一个参数(id参数,且必须放在单引号或双引号里)
alert(typeof document.getElementById("test") );

注意,这里的Element是没有“s”结尾的!后面两个才有!

按照书上的测试我们只能得出“document.getElementById("test")”的类型是一个对象,但实际上可以更进一步探讨这是个什么对象(是document对象么?):

alert( document.getElementById("test-id") );

输出的结果是object HTMLDivElement,这明显不是document对象,至于这个对象和document有何不同,和DOM有什么关系,以后再说(查文档)。

同时我也注意到,将这个方法返回的对象赋值给一个变量,该变量的类型将和右值类型相同:

var test_id = document.getElementById("test-id");
alert( test_id );
//输出的结果也是object HTMLDivElement

另外,我发现文档中称HTMLDivElement为“接口”而不是对象!为什么呢?后面要时刻注意对象、接口是什么东西,参考文章有:123

2.getElementByTagName

//getElementsByTagName
//只接受标签名作为参数
//返回一个对象数组(数组),每个对象分别对应document对象中的一个tag元素;所以我们可以使用数组对象的属性,比如length
alert( document.getElementsByTagName("li").length );

我得先看看这个返回的是什么:

alert( document.getElementsByTagName("p") );
//输出object HTMLCollection

3.getElementsByClassName

//getElementsByClassName
//以空格来同时指定多个类名——由于返回的只有一个特殊的对象,理所当然的,这里返回的是同时具有testClass、testClassTwo类的标签。
//只接受类名为参数
alert( document.getElementsByClassName("testClass testClassTwo").length );

同样的,我得先知道这个方法返回的是什么东西——这里返回的不是真正意义上的“数组”:

alert( document.getElementsByClassName("test-class") );
//输出的结果是HTMLCollection,这个对象不是Array(数组)而是一个特殊的对象数组,他也有“.length”这个方法,即返回集合中子元素的数目

标记一下,为什么不是返回数组而是返回一个新定义的对象数组?肯定有原因。

这里要注意,这个方法在IE8以下是无法使用的,我们必须借助“getElementsByTagName”来定义这个函数才能在老版本浏览器中使用,具体的方法见这篇文章,有些函数还看不懂,不知道这个实现的原理,以后要回头看懂它。P42

4.返回的类型是什么,是一个很重要的问题。

  var test_id = document.getElementById("test-id");

  var test_items = test_id.getElementsByTagName("*");
  alert(test_items.length);
  //输出该id下有多少个标签

这段代码将正确地输出id为“test-id”下有多少个标签,之所以能这样,是因为“getElementById”返回的是一个document的实例,所以第二行可以对“test_id”使用“getElementsByTagName”这个方法;同样地,因为“getElementsByTagName”返回的是一个特殊的对象,这个对象有“length”这个方法,所以我们才能在alert里面正确地输出。

如果我们把第一行和第二行反过来用,比如“某些标签里面的id=test-id的标签有几个?”,就会出错了(这是个伪命题,直接找id就好了,不需要找“某些标签里面的id”)——首先就是“getElementsByTagName”返回的对象是没有“getElem....”这种方法的,其它的就更不用说了。

同样地还能这么用:

var test_id = document.getElementById("test-id");
var test_items = test_id.getElementsByClassName("test-class");
alert(test_items.length);
//输出该id下有多少个“test-class”类的标签

要意识到,文档中的每一个元素都是一个对象,DOM对这些不同的对象都定义了不同的一整套的方法和属性;

getElementById返回一个对象,该对象对应文档里一个特定的元素节点。

getElementsByClassName、getElementsByTagName返回一个对象数组,它们分别对应文档里的一组特定的元素节点——因为你一次只能改一个元素,所以你如果想借这个操作修改这个数组里某个具体元素的值,你就必须加下标!比如getElementsByClassName("p")[1](这里只是强调下标,实际上不一定是这么写的,真正的写法见下面的例子)之类。

5.childNodes属性

前面分别是获取某个id的元素、获取某个标签、获取某个类的元素,现在这个是获取任何一个元素的所有子元素:

3.获取和设置属性

1.getAttribute(获取)

//getAttribute
//为了方便,我只写body里的内容。
<div id="test-id">
<p title="oneTitle">hello word1</p>
<h1 class="test-class">
<p>1</p>
<p>2</p>
</h1>
<p title="twoTitle">hello word3</p>
<p>hello word4</p>
</div>
<script>
var test_items = document.getElementsByTagName("p");
for(var i = 0 ; i < test_items.length ; i++){
alert( test_items[i].getAttribute("title") );
}
</script>
//输出的结果依次为:oneTitle、null、null、twoTitle、null

学到这,我注意到:DOM分支下之所以有那么多的对象或者说是接口,其实都是为了针对不同抽象层级的操作而诞生的。比如,文档树里的各个节点的层级,我们操作的目标往往是各个节点的属性。因为不需要获取这个节点本身,所以这里的getAttribute不是document对象的一个方法——它只专注于实现属性相关的操作,所以被独立出来,所以我们这里可以看到,要想调用getAttribute,不能通过document对象调用,而是和其“联用”,即先获取到你想更改的标签的数组(第一行代码),然后再调用节点抽象层级的对象的方法getAttribute(第二行script代码——顺带一说,这里的节点抽象层级的对象其实就是指前面提到的HTMLCollection)。

上面一段的可以简单概括为:getAttribute方法是属于HTMLCollection对象的,而HTMLCollection对象是由document对象中的getElementsByTagName等方法返回的结果。

其次,要注意到上面这段代码的输出中有“null”,在Javascript里,null的意思是“没有值”。(个别浏览器会在输出null对话框的时候输出空白对话框)

2.setAttribute(设置)

//setAttribute
//为了方便,只给出body内的代码
<div id="test-id">
<p title="oneTitle">hello word1</p>
<h1 class="test-class">
<p>1</p>
<p>2</p>
</h1>
<p title="twoTitle">hello word3</p>
<p>hello word4</p>
</div>
<script>
var test_id = document.getElementById("test-id");
alert( test_id.getAttribute("title") );
test_id.setAttribute("title","test-title");
//测试是否修改了
alert( test_id.getAttribute("title") );
</script>

setAttribute实际操作是这样的:

1.当对象属性值为null时(可能有点奇怪,但就是这样:属性没设置就相当于属性不存在,而属性不存在就是属性=null),先创建这个属性,然后设置它的值。

2.当属性的值存在时,覆盖掉它。

通过setAttribute对文档做出修改后,浏览器的开发者模式看到的源代码中属性的值并没有改变——其做出的修改不会反映在文档本身的源代码里,是“表里不一”的,这种思想源自DOM的工作模式:先加载文档的静态内容,再动态刷新,动态刷新不影响文档的静态内容。这也是DOM的真正威力:对页面内容进行刷新却不需要在浏览器里刷新页面。——————仔细想想,这是一连串的影响造成的。浏览器解析步骤的开始就是下载HTML文档,生成文档树,然后再渲染CSS、JS,如果JS改了HTML文档,那么浏览器就需要从头开始,也就是整个页面都要重新渲染一次,而这个代价出现的原因居然是修改某个属性值?所以干脆变成“动态刷新”。

Javascript DOM 编程艺术(第二版)读书笔记——DOM基础的更多相关文章

  1. 【JavaScript DOM编程艺术(第二版)】笔记

    第1章 javascript简史 1.什么是DOM? 简单的说,DOM是一套对文档的内容进行抽象和概念化的方法.\         第2章 javascript语法 1.内建对象: 内建在javasc ...

  2. JavaScript DOM 编程艺术(第二版) 初读学习笔记

    这本书留给我的印象就是结构.表现和行为层的分离,以及书后面部分一直在强调的最佳实践原则:平稳退化,逐步增强,向后兼容以及性能考虑. 要注意这不是一本JavaScript入门书籍~ 2.1 准备工作 用 ...

  3. JavaScript DOM编程艺术第二版学习(1/4)

    接下来项目需要网页相关知识,故在大牛的指引下前来阅读本书. 记录方式:本书分四部分阅读,完成阅读之后会多写一篇包括思维导图的算是阅读指南的东西,浏览的童鞋看着指南可以跳过一些不必要的坑~ 当前水平:H ...

  4. JavaScript DOM 编程艺术(第二版) 有待解决的问题

    原书 P181,var repeat = "moveElement('"+elementID+"', "+final_x+", "+fina ...

  5. JavaScript DOM 编程艺术(第二版) 常用JS小脚本

    function addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') ...

  6. 《JavaScript_DOM编程艺术第二版(中文)》整书笔记

    目录 第3章:DOM 第4章:案例研究 第5章:最佳实践 第6章:案例改进 第7章:动态创建标记 第8章:充实文档的内容 第9章:CSS-DOM 第3章:DOM 文档:DOM中的"D&quo ...

  7. JavaScript_DOM编程艺术第二版[阅]

    前两年迫于项目的需要,只是拿来JQuery用到项目中,并没有实质上理解javascript(貌似其他人也是这么干的)~ 随着最近几年,得益于Nodejs, React, Vue等,javascript ...

  8. 《ECMAScript标准入门》第二版读书笔记

    title: <ECMAScript标准入门>第二版 date: 2017-04-10 tags: JavaScript categories: Reading-note 2015年6月, ...

  9. JavaScript高级程序设计第三版-读书笔记(1-3章)

    这是我第一次用markdown,也是我第一次在网上记录我自己的学习过程. 第一章 JavaScript主要由以下三个不同的部分构成 ECMAScript   提供核心语言功能 DOM     提供访问 ...

  10. 《细说PHP》第二版--读书笔记

    第五章 PHP的基本语法 5.2.4 在程序中使用空白的处理 5.3 变量 5.3.1 变量的声明 在php中变量的声明必须是使用一个$符号,后面跟变量名来表示 unset()函数释放指定变量 iss ...

随机推荐

  1. 使用maven时,如何修改JVM的配置参数;maven命令执行时到底消耗多少内存?

    maven是使用java启动的,因此依赖JVM,那么如何修改JVM参数? MAVEN_OPTS 在系统的环境变量中,设置MAVEN_OPTS,用以存放JVM的参数,具体设置的步骤,参数示例如下: MA ...

  2. mvn打包源码的方法:maven-source-plugin

    maven-javadoc-plugin可以打包 dubbo-demo-provider-2.6.1-javadoc.jar maven-jar-plugin 打包插件 dubbo-demo-prov ...

  3. ppc_85xx-gcc -shared -fPIC liberr.c -o liberr.so

    fPIC作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),   则产生的代码中,没有绝对地址,所有使用相对地址.故而代码能够被载入器载入到内存的随意 ...

  4. Dell PowerEdgeServerT110II USB Boot更新

    可引导USB设备更新Dell PowerEdge服务器 当显示Boot Options(“启动选项”)时,选择option 1(选项 1)以开始固件更新. 现在正在加载的Linux发行版本 然后固件更 ...

  5. 慎用Outline ,UGUI Outline实现原理分析

    使用 UGUI 制作背包的时候.同事发现假设背包中加入了大量的物品.比方两百个.Unity就会出错,提示 Canvas element contains more than 65535 vertice ...

  6. RAD 极速应用开发 Spring ROO 入门样例

    官网                                      http://projects.spring.io/spring-roo/ Spring ROO in action   ...

  7. Angularjs1.x 项目结构

    大部分的项目结构是以 directives , service, controller 为基础来搭建的项目架构的,但这里更偏向于以应用场景来进行项目架构,因此这里的文件夹结构可能与您之前遇到的结构不同 ...

  8. HNOI模拟 Day3.25 By Yqc

    怕老婆 [问题描述] 有一天hzy9819,来到了一座大城市拥有了属于他自己的一双滑板鞋.但是他还是不满足想要拥有属于自己的一栋楼,他来到了一条宽敞的大道上,一个一个记录着这些楼的层数以方便自己选择. ...

  9. android 6.0编译时出现ERROR:Security problem ,see jack server log【转】

    本文转载自:http://blog.csdn.net/a567890k/article/details/52956798 最近编译Android6.0时经常出现以下错误 临时解决方法: Buildin ...

  10. 06_锅炉压力案例_progressbar实现

    相关的native方法可以用javah来生成一个头文件.拿着这个的MainActivity,用它来生成一个头文件. Signature是当前这个方法的方法签名.() V全空参数返回的是void. /* ...