文章目录
- document对象
- 1.DOM概述
- 一、Document属性分类:
- 二、使用document: 方法
- 1、document.querySelector('.myclass') 返回元素节点
- 2、document.querySelectorAll() 返回值是 NodeList对象
- 3、document.getElementsByTagName() 返回值是一个类似数组对象(HTMLCollection实例)
- 4、document.getElementsByClassName() 返回一个类似数组的对象, HTMLCollection实例
- 5、document.getElementById() 返回元素节点
- 6、document.createElement() 用来生成元素节点,并返回该节点
- 7、 document.createTextNode() 用来生成文本节点,并返回该节点
- 8、document.createAttribute() 用来生成属性节点,并返回该节点
- 三、document 的事件 ——EventTarget 接口
document对象
1.DOM概述
DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型”(Document Object Model)。它的作用是将网页转为一个 JavaScript 对象,从而可以用脚本进行各种操作(比如增删内容)。
浏览器会根据 DOM 模型,将结构化文档(比如 HTML 和 XML)解析成一系列的节点,再由这些节点组成一个树状结构(DOM Tree)。所有的节点和最终的树状结构,都有规范的对外接口。
DOM 只是一个接口规范,可以用各种语言实现。所以严格地说,DOM 不是 JavaScript 语法的一部分,但是 DOM 操作是 JavaScript 最常见的任务,离开了 DOM,JavaScript 就无法控制网页。另一方面,JavaScript 也是最常用于 DOM 操作的语言。后面介绍的就是 JavaScript 对 DOM 标准的实现和用法。
一、Document属性分类:
1.使用较多的属性有以下三类
- 第一类:
doctype,documentElement,body,head
, 用于返回文档内部的某个节点- 第二类:
documentURI,URL,domain,lastModified,location,title,readyState
, 用于返回文档指定的信息- 第三类 :
anchors,forms,images,links,scripts
, 用于返回文档内部特定节点的集合
2.节点
document节点是文档的根节点,每张网页都有自己的document节点。window.document属性就指向这个节点。也就是说,只要浏览器开始载入HTML文档,这个节点对象就存在了,可以直接调用。
DOM 的最小组成单位叫做节点(node)。文档的树形结构(DOM 树),就是由各种不同类型的节点组成。每个节点可以看作是文档树的一片叶子。
节点的类型有七种。
Document
:整个文档树的顶层节点DocumentType:doctype
标签(比如<!DOCTYPE html>
)Element
:网页的各种HTML标签(比如<body>、<a>
等)Attr:
网页元素的属性(比如class="right"
)Text
:标签之间或标签包含的文本Comment
:注释DocumentFragment
:文档的片段
浏览器提供一个原生的节点对象 Node
,上面这七种节点都继承了 Node
,因此具有一些共同的属性和方法。
document节点有不同的办法可以获取:
对于正常的网页,直接使用document
或window.document
。
对于iframe载入的网页,使用iframe
节点的contentDocument
属性。
对Ajax操作返回的文档,使用XMLHttpRequest
对象的responseXML
属性。
对于某个节点包含的文档,使用该节点的ownerDocument
属性。
document.firstChild通常就返回这个节点。
除了根节点,其他节点都有三种层级关系。
- 父节点关系(parentNode):直接的那个上级节点
- 子节点关系(childNodes):直接的下级节点
- 同级节点关系(sibling):拥有同一个父节点的节点
DOM 提供操作接口,用来获取这三种关系的节点。比如,子节点接口包括 firstChild
(第一个子节点)和 lastChild
(最后一个子节点)等属性,同级节点接口包括 nextSibling
(紧邻在后的那个同级节点)和 previousSibling
(紧邻在前的那个同级节点)属性。
3.Document节点属性:
document.title//设置文档标题,与HTNL中的title标签等价
document.bgColor//设置页面背景颜色
document.fgColor//设置页面前景色
document.fileCreateDate//文件建立日期,只读属性
document.fileModifiedDate//文件修改日期,只读属性
document.URL//可返回当前文档的URL
document.linkColor//未点击过的链接颜色
doucment.alinkColor//鼠标在此链接上的颜色
document.vlinkColor//已点击过的链接颜色
document.charset//设置字符集,简体中文为gb2312
document.fileSize//文件大小,只读属性
document.cookies//设置和读出cookie
二、使用document: 方法
document节点有很多属性,用得比较多的是下面这些。
1、document.querySelector(‘.myclass’) 返回元素节点
- document.querySelector()方法,接受 css选择器作为参数,返回匹配该选择器的元素节点。
- 如果多个节点满足匹配条件,返回 第一个匹配的元素节点
- 如果没有匹配的节点,返回 null
- 参数,可以是逗号分隔的多个 CSS 选择器,返回匹配其中一个选择器的元素节点。
( 即匹配多少个就返回多少个 )。 - 该方法除了定义在document对象上,还定义在元素节点上,即在元素节点上也可以调用
//html
<div id="one" class="one" name="one" >第一个div</div>
<div id="two" class="one" name="two" >第二个div</div>
// js
window.onload = function() {
var _ID = document.querySelector('#one'); // 返回id是one的元素节点
var _CLASS = document.querySelector('.one'); // 多个满足,返回满足的第一个元素节点
console.log(_ID, '_ID'); // <div id="one" class="one"name="one" >第一个div</div>
console.log(_CLASS, '_CLASS'); // <div id="one" class="one"name="one" >第一个div</div>
}
// document.querySelector() 以css选择器为参数,返回匹配的元素节点
// 如果多个匹配,则返回满足添加的第一个匹配的元素节点
// 没有匹配的节点,返回null
2、document.querySelectorAll() 返回值是 NodeList对象
NodeList对象,是一个类似数组的对象。可以通过数字下标属性获得属性的值。
( 类似数组的对象,可以通过Array.from()方法转换为真正的对象
)
document.querySelectorAll方法与querySelector用法类似,区别是返回一个NodeList对象,包含所有匹配给定选择器的节点。
- document.querySelectorAll() 方法接受一个css选择器为参数,返回一个 NodeList对象,包含所有匹配选择器的 元素节点
- 参数,可以是逗号分隔的多个 CSS 选择器,返回匹配其中一个选择器的元素节点。
( 即匹配多少个就返回多少个 )。 - 如果querySelectorAll方法的参数是 字符串 *,则会返回文档中的所有元素节点。另外,querySelectorAll的返回结果不是动态集合,不会实时反映元素节点的变化。
- 该方法除了定义在document对象上,还定义在元素节点上,即在元素节点上也可以调用。
var matches = document.querySelectorAll('div.note, div.alert');
// 选中 data-foo-bar 属性等于 someval 的元素
document.querySelectorAll('[data-foo-bar="someval"]');
// html
<div id="one" class="one"name="one" >第一个div</div>
<div id="two" class="one" >第二个div</div>
// js
window.onload = function() {
var _querySelectorAll = document.querySelectorAll('#two, #one'); // 参数是逗号分隔的多个选择器
console.log(_querySelectorAll, '_querySelectorAll');
}
// document.querySelector() 和 document.querySelectorAll()
// 两个的参数可以是以逗号分隔的多个css选择器,返回满足条件的 元素节点
// 匹配几个就返回几个
3、document.getElementsByTagName() 返回值是一个类似数组对象(HTMLCollection实例)
document.getElementsByTagName方法搜索 HTML 标签名,返回符合条件的元素。它的返回值是一个类似数组对象(HTMLCollection实例),可以实时反映 HTML 文档的变化。如果没有任何匹配的元素,就返回一个空集。
- document.getElementsByTagName() 参数是
标签名
,返回类似数组的对象
,通过下标取值
。 - HTML 标签名是大小写不敏感的,因此getElementsByTagName方法也是大小写不敏感的。
- 如果传入*,就可以返回文档中所有 HTML 元素。
- 这个方法不仅可以在document对象上调用,也可以在任何元素节点上调用。
var firstPara = document.getElementsByTagName('p')[0];
var spans = firstPara.getElementsByTagName('span');
// 注意这里一定要用下标选择类似数组的对象中的属性,
// 因为document.getElementsByTagName返回的是类似数组的对象,(HTMLCollection实例)
4、document.getElementsByClassName() 返回一个类似数组的对象, HTMLCollection实例
document.getElementsByClassName方法返回一个类似数组的对象(HTMLCollection实例),包括了所有class名字符合指定条件的元素,元素的变化实时反映在返回结果中。
- 参数可以是多个class,它们之间使用空格分隔。
- 与getElementsByTagName方法一样,getElementsByClassName方法不仅可以在document对象上调用,也可以在任何元素节点上调用。
var elements = document.getElementsByClassName('foo bar');
5、document.getElementById() 返回元素节点
- documenet.getElementById() 方法接受id为参数,返回元素节点。
- 注意,该方法的参数是大小写敏感。
- document.getElementById 和 document.querySelector 都能返回各自匹配的元素节点,但是document.getElementById()比document.querySelector()效率高得多。
- getElementById()方法只能在document对象上使用,不能在其他元素节点上使用。
var elem = document.getElementById('para1');
document.getElementById()方法与document.querySelector()方法都能获取元素节点,不同之处是document.querySelector()方法的参数使用 CSS 选择器语法,document.getElementById()方法的参数是元素的id属性。
但是document.getElementById()比document.querySelector()效率高得多。
document.getElementById('myElement')
document.querySelector('#myElement')
6、document.createElement() 用来生成元素节点,并返回该节点
document.createElement方法用来生成元素节点,并返回该节点。
var newDiv = document.createElement('div');
- createElement方法的参数为元素的标签名,即元素节点的tagName属性,对于 HTML 网页大小写不敏感,即参数为div或DIV返回的是同一种节点。如果参数里面包含尖括号(即<和>)会报错。
- 注意,document.createElement的参数可以是自定义的标签名
document.createElement('<div>');
// DOMException: The tag name provided ('<div>') is not a valid name
7、 document.createTextNode() 用来生成文本节点,并返回该节点
document.createTextNode方法用来生成文本节点(Text实例),并返回该节点。它的参数是文本节点的内容。
- 这个方法可以确保返回的节点,被浏览器当作文本渲染,而不是当作 HTML 代码渲染。因此,可以用来展示用户的输入,避免 XSS 攻击。
var newDiv = document.createElement('div'); // 生成元素节点
var newContent = document.createTextNode('Hello'); // 生成文本节点
newDiv.appendChild(newContent); // 把文本节点插入到元素节点
// 上面代码新建一个div节点和一个文本节点,然后将文本节点插入div节点。
// 这个方法可以确保返回的节点,被浏览器当作文本渲染,而不是当作 HTML 代码渲染。
// 因此,可以用来展示用户的输入,避免 XSS 攻击。
8、document.createAttribute() 用来生成属性节点,并返回该节点
-
document.createAttribute方法生成一个新的属性节点(Attr实例),并返回它。
-
document.createAttribute方法的参数name,是属性的名称
var node = document.getElementById('div1'); // 创建元素节点
var a = document.createAttribute('my_attrib'); // 创建属性节点
a.value = 'newVal'; // 属性的值
---------------------------------------------------------
node.setAttributeNode(a);
// 或者
node.setAttribute('my_attrib', 'newVal'); // Element.setAttribute()创建或者修改属性节点
三、document 的事件 ——EventTarget 接口
事件的本质是程序各个组成部分之间的一种通信方式,也是异步编程的一种实现。DOM 支持大量的事件,本章开始介绍 DOM 的事件编程。
概述
DOM 的事件操作(监听和触发),都定义在EventTarget接口。所有节点对象都部署了这个接口,其他一些需要事件通信的浏览器内置对象(比如,XMLHttpRequest、AudioNode、AudioContext)也部署了这个接口。
该接口主要提供三个实例方法。
-
addEventListener:绑定事件的监听函数
-
removeEventListener:移除事件的监听函数
-
dispatchEvent:触发事件
EventTarget.addEventListener()
EventTarget.addEventListener()用于在当前节点或对象上,定义一个特定事件的监听函数。一旦这个事件发生,就会执行监听函数。该方法没有返回值。
target.addEventListener(type, listener[, useCapture]);
该方法接受三个参数。
-
type:事件名称,大小写敏感。
-
listener:监听函数。事件发生时,会调用该监听函数。
-
useCapture:布尔值,表示监听函数是否在捕获阶段(capture)触发(参见后文《事件的传播》部分),默认为false(监听函数只在冒泡阶段被触发)。该参数可选。
下面是一个例子。
function hello() {
console.log('Hello world');
}
var button = document.getElementById('btn');
button.addEventListener('click', hello, false);
上面代码中,button节点的addEventListener方法绑定click事件的监听函数hello,该函数只在冒泡阶段触发。
关于参数,有两个地方需要注意。
首先,第二个参数除了监听函数,还可以是一个具有handleEvent方法的对象。
buttonElement.addEventListener('click', {
handleEvent: function (event) {
console.log('click');
}
});
上面代码中,addEventListener方法的第二个参数,就是一个具有handleEvent方法的对象。
其次,第三个参数除了布尔值useCapture,还可以是一个属性配置对象。该对象有以下属性。
- capture:布尔值,表示该事件是否在捕获阶段触发监听函数。
- once:布尔值,表示监听函数是否只触发一次,然后就自动移除。
- passive:布尔值,表示监听函数不会调用事件的preventDefault方法。如果监听函数调用了,浏览器将忽略这个要求,并在监控台输出一行警告。
如果希望事件监听函数只执行一次,可以打开属性配置对象的once属性。
addEventListener方法可以为针对当前对象的同一个事件,添加多个不同的监听函数。这些函数按照添加顺序触发,即先添加先触发。如果为同一个事件多次添加同一个监听函数,该函数只会执行一次,多余的添加将自动被去除(不必使用removeEventListener方法手动去除)。
function hello() {
console.log('Hello world');
}
document.addEventListener('click', hello, false);
document.addEventListener('click', hello, false);
执行上面代码,点击文档只会输出一行Hello world。
如果希望向监听函数传递参数,可以用匿名函数包装一下监听函数。
function print(x) {
console.log(x);
}
var el = document.getElementById('div1');
el.addEventListener('click', function () { print('Hello'); }, false);
上面代码通过匿名函数,向监听函数print传递了一个参数。
监听函数内部的this,指向当前事件所在的那个对象。
// HTML 代码如下
// <p id="para">Hello</p>
var para = document.getElementById('para');
para.addEventListener('click', function (e) {
console.log(this.nodeName); // "P"
}, false);
上面代码中,监听函数内部的this指向事件所在的对象para。
EventTarget.removeEventListener()
EventTarget.removeEventListener方法用来移除addEventListener方法添加的事件监听函数。该方法没有返回值。
div.addEventListener('click', listener, false);
div.removeEventListener('click', listener, false);
removeEventListener方法的参数,与addEventListener方法完全一致。它的第一个参数“事件类型”,大小写敏感。
注意,removeEventListener方法移除的监听函数,必须是addEventListener方法添加的那个监听函数,而且必须在同一个元素节点,否则无效。
div.addEventListener('click', function (e) {}, false);
div.removeEventListener('click', function (e) {}, false);
上面代码中,removeEventListener方法无效,因为监听函数不是同一个匿名函数。
element.addEventListener('mousedown', handleMouseDown, true);
element.removeEventListener("mousedown", handleMouseDown, false);
上面代码中,removeEventListener方法也是无效的,因为第三个参数不一样。
EventTarget.dispatchEvent()
EventTarget.dispatchEvent方法在当前节点上触发指定事件,从而触发监听函数的执行。该方法返回一个布尔值,只要有一个监听函数调用了Event.preventDefault(),则返回值为false,否则为true。
target.dispatchEvent(event)
dispatchEvent方法的参数是一个Event对象的实例(详见《Event 对象》章节)。
para.addEventListener('click', hello, false);
var event = new Event('click');
para.dispatchEvent(event);
上面代码在当前节点触发了click事件。
如果dispatchEvent方法的参数为空,或者不是一个有效的事件对象,将报错。
下面代码根据dispatchEvent方法的返回值,判断事件是否被取消了。
var canceled = !cb.dispatchEvent(event);
if (canceled) {
console.log('事件取消');
} else {
console.log('事件未取消');
}
原文链接:https://www.jianshu.com/p/fd478cfb81c2