目录

第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. flex 添加svn插件

    http://blog.csdn.net/gangan1345/article/details/7926848

  2. DynamicJson

    json字符串解析成Dynamic对象,开源地址http://dynamicjson.codeplex.com/,访问比较慢.使用方法摘录如下: Project Descriptiondynamic ...

  3. Strategy pattern策略模式

    在Java的集合框架中,经常需要通过构造方法传入一个比较器Comparator,或者创建比较器传入Collections的静态方法中作为方法参数,进行比较排序等,使用的是策略模式. 一.策略模式的定义 ...

  4. [开发笔记]-未找到与约束ContractName Microsoft.VisualStudio.Text.ITextDocumentFactoryService...匹配的导出【转载自:酷小孩】

    原文地址:http://www.cnblogs.com/babycool/p/3199158.html 今天打算用VisualStudio2012做一个js效果页面测试的时候,打开VS2012新建项目 ...

  5. Android studio 提示:Can't use Subversion command line client: svn Probably the path to Subversion executable is wrong. Fix it.

    1.参考来源:http://my.oschina.net/fyyy/blog/519353 按照下图,svn相关选项不要选.

  6. 通过Navicat for MySQL远程连接的时候报错mysql 1130

    1130 重装数据库 解决这个问题

  7. 说一说windows原生docker及windows Server Container , Hyper Container 之间的关系(学习总结)

    前一段时间学习netcore的时候解除到了docker,感觉真是不错的技术.百度了不少教程.因为我用windows就下载安装了一下试试.但是没有安装成功,才发现 需要安装virtualbox虚拟机,与 ...

  8. AWS-CDH5.5安装-安装

    1.安装MySQL [root@ip---- mysql]# rpm -ivh MySQL-server--.el6.x86_64.rpm MySQL-client--.el6.x86_64.rpm ...

  9. Java中main函数只能调用同类中的静态方法?

    如果想调用本类中的非静态方法可以这么来写: public class TT{ public static void main(String[] args){ TT t = new TT(); t.fu ...

  10. hibernate整合spring开发的时候遇到的一些小问题

    1 在spring整合hibernate开发的时候,在数据源里面配置show_sql为true,但是在实际查询的时候并没有打印sql语句,正确的解决方案为: 把<prop key="s ...