目录

第3章:DOM

文档:DOM中的“D”

当创建了一个网页并把它加载到Web浏览器中时,DOM就产生了,它把你编写的网页文档转换为一个文档对象。

对象:DOM中的“O”

JavaScript语言里的对象可以分为三种类型:

  • 用户自定义对象:由程序员自行创建的对象
  • 内建对象:内建在JavaScript语言里的对象,如 Array、Math 和 Date 等
  • 宿主对象:由浏览器提供的对象,如 window、document

window对象对应着浏览器窗口本身,这个对象的属性和方法统称为BOM(浏览器对象模型)

模型:DOM中的“M”

DOM 把一份文档表示为一棵树(家谱树)。

节点

  1. 元素节点:DOM 的原子,即标签的名字,如 html、p、ul、li

  2. 文本节点:总是被包含在元素节点的内部,但并非所有的元素节点都包含文本节点

  3. 属性节点:用来对元素做出更具体的描述,如 title 属性,并非所有的元素都包含属性,但所有的属性都被元素包含。

  4. CSS:除了DOM与网页结构打交道,还可以通过CSS告诉浏览器如何显示一份文档的内容。

  5. 获取元素

    • getElementById:是 document 对象特有的函数

        document.getElementById(id)
    • getElementsByTagName:返回一个对象数组

        element.getElementsById(tag)
    • getElementsByClassName:可以查找那些带有多个类名的元素,可以指定多个类名,用空格分隔

        element.getElementsByClassName(class)
  6. 盘点知识点

    • 一份文档就是一颗节点树
    • 节点分为不同的类型:元素节点、属性节点和文本节点等
    • getElementById 将返回一个对象,该对象对应着文档里的一个特定的元素即诶但
    • getElementsByTagNamegetElementsByClassName 将返回一个对象数组,它们分别对应着文档里的一组特定的元素节点。

获取和设置属性

  1. getAttribute:获取元素的各个属性

    getAttribute 方法不属于 document 对象,所以不能通过 document 对象调用。它只能通过元素节点对象调用。

     object.getAttribute(attribute)
  2. setAttribute:更改属性节点的值

     object.getAttribute(attribute, value)

    注意:通过 setAttribute 对文档做出修改后,在通过浏览器 view source 选项去查看文档的源代码时看到的仍将是改变前的属性值,即,setAttribute 做出的修改不会反映在文档本身的源代码里。

    这种“表里不一”的现象源自 DOM 的工作模式:先加载文档的静态内容,再动态刷新,动态刷新不影响文档的静态内容。

    这正是 DOM 的真正威力:对页面内容进行刷新却不需要在浏览器里刷新页面。

小结

本章介绍了DOM提供的五个基础方法:

  • getElementById
  • getElementsByTagName
  • getElementsByClassName
  • getAttribute
  • setAttribute

第4章:案例研究

几个 DOM 提供的新属性:childNodesnodeTypenodeValuefirstChildlastChild

childNodes:用来获取任何一个元素的所有子元素,它包含这个元素全部子元素的数组。

nodeType:nodeType 属性共有12种取值,但其中仅有3种具有实用价值:

  • 元素节点的 nodeType 属性值是1
  • 属性节点的 nodeType 属性值是2
  • 文本节点的 nodeType 属性值是3

nodeValue:获取文本节点的值,而非元素本身的值。

第5章:最佳实践

性能考虑

  1. 尽量少访问DOM和尽量减少标记

    • 访问DOM会搜索整个DOM树

    • 文档中的过多不必要的元素(标记数量)会增加DOM树的规模,进而增加遍历DOM树以查找特定元素的时间

  2. 合并和放置脚本

    • 将多个脚本文件合并到一个脚本文件中,这样,可以减少加载页面时发送的请求数量。而减少请求数量通常是性能优化时首要考虑的。

    • 脚本在标记中的位置对页面的初次加载时间也有很大影响。将脚本放在之前,可以让页面变得更快。这样,在加载脚本时,window 对象的 load 事件依然可以执行对文档进行的各种操作。

    一般来说,根据 HTTP 规范,浏览器每次从同一个域名中最多只能同时下载两个文件。而在下载脚本期间,浏览器不会下载其他任何文件,即使是来自不同域名的文件也不会下载,所有其他资源都要等脚本加载完毕后才能下载。

  3. 压缩脚本

    • 压缩脚本,即把脚本文件中不必要的字节,如空格和注释,统统删除,从而达到“压缩”文件的目的。

第6章:案例改进

优化

  1. if(variable) 代替 if (variable !== null)

  2. 有判断的情况下,用三元操作符取值

    var variable = condition ? if true : if false;

     links[i].onclick = function() {
    if (showPic(this)) {
    return false;
    } else {
    return true;
    }
    }

    改为:

     links[i].onclick = function() {
    return showPic(this) ? false : true;
    }

DOM Core 和 HTML-DOM

  • getElementByIdgetElemntsByTagNamegetAttributesetAttribute 这些方法都是 DOM Core 的组成部分。它们并不专属于 JavaScript,支持 DOM 的任何一种程序设计语言都可以使用它们。它们的用途也并非仅限于处理网页,它们可以用来处理任何一种标记语言(如XML)编写出来的文档。

  • 使用 JavaScript 语言和 DOM 为 HTML 文件编写脚本时,有许多属性可供选择,如onclickformsrchref等,这些属性术语 HTML-DOM。

    document.getElementsByTagName('form') 等价于 document.forms

    element.getAttribute('src') 等价于 element.src

第7章:动态创建标记

传统技术

  1. documnet.write()

  2. innerHTML

DOM 方法

  1. createElement:创建元素节点

     document.createElement(nodeName);
  2. createTextNode:创建文本节点

     document.createTextNode(text);
  3. appendChild

     parent.appendChild(child);

重回图片库

  1. insertBefore

     parentElement.insertBefore(newElement, targetElement);
  2. 编写 insertAfter 函数

     function insertAfter(newElement, targetElement) {
    var parent = targetElement.parentNode;
    if (parent.lastChild == targetElement) {
    parent.appendChild(newElement);
    } else {
    parent.insertBefore(newElement, targetElement.nextSibling);
    }
    } var child2 = document.createElement('div');
    var child2Txt = document.createTextNode('I am child2');
    child2.appendChild(child2Txt); // 刷新 child2Txt 的文本值
    child2Txt.nodeValue = 'I am child2 new'; var child3 = document.createElement('div');
    /*var child3Txt = document.createTextNode('I am child3');
    child3.appendChild(child3Txt);*/ // 替代方式
    child3.innerText = 'I am child3'; var child1 = document.getElementsByClassName('child1')[0];
    var parent = document.getElementsByClassName('parent')[0];
    parent.insertBefore(child2, child1); insertAfter(child3, child2);

Ajax

Ajax 的主要优势:对页面的请求以异步方式发送到服务器。而服务器不会用整个页面来响应请求,它会在后台处理请求,与此同时用户还能继续浏览页面并与页面交互。你的脚本则可以按需加载和创建页面内容,而不会打断用户的浏览体验。

XMLHttpRequest 对象

Ajax 技术的核心,该对象充当着浏览器中的脚本(客户端)与服务器之间的中间人的角色。以往的请求都由浏览器发出,而 JavaScript 通过这个对象可以自己发送请求,同时也自己处理响应。

var xmlhttp;
if (window.XMLHttpRequest) {
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xmlhttp = new XMLHttpRequest();
} else {
// IE6, IE5 浏览器执行代码
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} // 发起一个请求
xmlhttp.open('GET', './test.txt', true); // 事件处理函数
// 在服务器给 XMLHTTPReqest 对象送回响应时被触发执行
xmlhttp.onreadystatechange = function() { // readyState 属性为4,表示完成,status 为 200,表示响应已就绪
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var para = document.createElement('p');
var txt = document.createTextNode(xmlhttp.responseText);
para.appendChild(txt);
document.getElementById('new').appendChild(para);
}
}; // 发送请求
xmlhttp.send(null);

访问服务器发送回来的数据要通过两个属性完成:1)responseText 属性,用于保存文本字符串形式的数据;2)responseXML 属性,用于保存 Content-Type 头部中指定为 "text/xml" 的数据,其实就是一个 DocumentFragment 对象。

你可以使用各种 DOM 方法来处理这个对象,这也正是 XMLHttpRequest 这个名称里有 XML 的原因。

注意:当使用 async=false 时,请不要编写 onreadystatechange 函数,把它放到 send() 语句后面即可。

Ajax 应用的一个特色就是减少重复加载页面的次数。但这种缺少状态记录的技术会与浏览器的一些使用惯例产生冲突,导致用户无法使用后退按钮或者无法为特定状态下的页面添加书签。

渐进增强的 Ajax

Ajax 应用主要依赖于服务器端处理,而非客户端处理。

第8章:充实文档的内容

不应该做什么

  1. 渐进增强

    原则:应该总是从最核心的部分,即内容开始。应该根据内容使用标记实现良好的结构;然后再逐步加强这些内容。这些增强工作既可以通过 CSS 改进呈现效果,也可以是通过 DOM 添加各种行为。

  2. 平稳退化

    渐进增强的实现必然支持平稳退化。如果你按照渐进增强的原则去充实内容,你为内容添加的样式和行为就自然支持平稳退化,那些缺乏必要的 CSS 和 DOM 支持的访问者仍可以访问到你的核心内容。

内容

某些浏览器要根据 DOCTYPE 来决定是使用标准模式,还是使用兼容模式来呈现页面。

兼容模式:浏览器要模仿某些早期浏览器的“怪异行为”,并容许那些不规范的页面在新浏览器也能正常工作。

一般来说,我们都应该坚持使用标准模式,避免出发兼容模式。HTML5 DOCTYPE 默认对应的就是标准模式。

第9章:CSS-DOM

分离

  • 使用 (X)HTML 去搭建文档的结构;
  • 使用 CSS 去设置文档的呈现效果;
  • 使用 DOM 脚本去实现文档的行为。

这三种技术之间存在着一些重叠区域,用DOM可以改变网页的结构,DOM样式可以给元素设定样式,CSS也能使用伪类走进DOM的领地。

style 属性

  • 一些属性,如 parentNodepreviousSiblingchildNodesfirstChildlastChild 等,告诉我们文档中各节点之间的关系信息。
  • 一些属性,如 nodeTypenodeValue 包含元素本身的信息;

style 属性包含元素的样式,查询该属性将返回一个对象而不是简单的字符串,样式都存放在这个 style 对象的属性里:

element.style.property

不仅文档里的每个元素都是一个对象,每个元素都有一个 style 属性,它们也是一个对象。

当你需要引用一个中间带减号的 CSS 属性时,DOM 要求你用驼峰命名法:element.style.fontFamily

DOM 属性 fontFamily 的值与 CSS 属性 font-family 的值是一样的。

不管 CSS 样式属性的名字里有多少个连字符,DOM 一律采用驼峰命名法来表示它们,因为 JavaScript 会把连字符看成减号,而减号和加号之类的操作符是保留字符,不允许用在函数或变量的名字里,即也不能用在方法或属性的名字里。

▉ 注意:style 属性只能返回内嵌样式,只有把 CSS style 属性插入到标记里,才可以用 DOM style 属性去查询那些信息。即 DOM style 属性不能用来检索在外部 CSS 文件里声明的样式。

☞ 解决方案:style 对象的各个属性都是可读写的,不仅可以通过某个元素的 style 属性去获取样式,还可以通过它去更新样式。

element.style.property = value

选择 CSS 还是 DOM 来设置样式?考虑两点:

  • 这个问题最简单的解决方案是什么;
  • 哪种解决方案会得到更多浏览器的支持。

className 属性

改变样式的方案:

  1. setAttribute

     elem.setAttribute('class', 'intro');
  2. style

     element.style.property = value
  3. className

     element.className = value

    把新的 class 设置值追加到 className 属性上去:

     elem.className += " intro"

    addClass 函数:

     function addClass(element, value) {
    if (!element.className) {
    element.className = value;
    } else {
    var newClassName = element.className;
    newClassName += ' ';
    newClassName += value;
    element.className = newClassName;
    }
    }

小结

style 属性的最大限制是它不支持获取外部的 CSS 设置的样式,但你仍可以利用 style 属性去改变各种 HTML 元素的呈现效果。

只要有可能,就应选择 className 属性,而不是去直接更新 style 对象的有关属性。

《JavaScript_DOM编程艺术第二版(中文)》整书笔记的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. Learning ROS for Robotics Programming - Second Edition(《ROS机器人编程学习-第二版》)

    Learning ROS for Robotics Programming - Second Edition <ROS机器人编程学习-第二版> ----Your one-stop guid ...

  8. 《python基础教程(第二版)》学习笔记 基础部分(第1章)

    <python基础教程(第二版)>学习笔记 基础部分(第1章)python常用的IDE:Windows: IDLE(gui), Eclipse+PyDev; Python(command ...

  9. 《python基础教程(第二版)》学习笔记 文件和素材(第11章)

    <python基础教程(第二版)>学习笔记 文件和素材(第11章) 打开文件:open(filename[,mode[,buffering]]) mode是读写文件的模式f=open(r' ...

随机推荐

  1. 【FPGA】相关介绍

    什么是 FPGA ? FPGA是Field Programmable Gate Array的缩写,即现场可编程门阵列,它是在PAL.GAL.EPLD等可编程器件的基础上进一步发展的产物.它是作为专用集 ...

  2. SpringMVC RequestMapping & 请求参数

    SpringMVC 概述 Spring 为展现层提供的基于 MVC 设计理念的优秀的Web 框架,是目前最主流的 MVC 框架之一 Spring3.0 后全面超越 Struts2,成为最优秀的 MVC ...

  3. 【PHP】分页条函数封装

    这两天在学习PHP 想做一个前端后台都包含的网站 看了一些视频发现大牛们都是将封装起来实现代码的重用性 本人技拙也写了个分页条函数的封装 分页条在用PHP网站开发中十分常用 通过封装代码来提高网站开发 ...

  4. keep the bar green to keep the code clean——Junit详解(二)

    测试用例&测试套件 举个栗子: 编写MyStack类模拟栈,并对其进行测试用例编写测试: 编写文件删除方法,并对其删除测试. 不再做演示,戳此获取代码 MyStack类: public cla ...

  5. C#按行读取文本并存放再数组内

    我只想说真的是日了狗的麻烦,代码就那么几行,但是根本看不懂在搞些什么东西,我现在还是一点都不知道getline函数到底是怎么用的,但是事实就是他确实能用. 期间在那该死的第一个char根本不知道为什么 ...

  6. atexit函数

    使用该函数注册的退出函数是在进程正常退出时,才会被调用.这里强调是进程正常退出,使用exit退出或使用main中最后的return语句退出.但如果是因为收到信号signal而导致程序退出,如kill ...

  7. vs2012 opencv 配置

    一直没有学习C++,以为该语言太过old,所以要学习新的咚咚.一番学习归来,在进行OpenCV的时候,还是要用到这个C++.几次琢磨,终于能够配置好相关的开发环境和问题初步处理,有些内容得赶快记录下来 ...

  8. Linux/Unix 线程同步技术之互斥量(1)

    众所周知,互斥量(mutex)是同步线程对共享资源访问的技术,用来防止下面这种情况:线程A试图访问某个共享资源时,线程B正在对其进行修改,从而造成资源状态不一致.与之相关的一个术语临界区(critic ...

  9. Python的平凡之路(19)

    一.Django请求生命周期   对于所有的web框架来说本质就是一个socket服务端,浏览器是socket客户端                                          ...

  10. 使用eclipse搭建maven项目

    一.安装插件 如果安装的eclipse 4.0及以上的版本或是MyEclipse就不用安装插件,可以在工具栏->windows->preferences里面搜索maven,看是否有搜索结果 ...