document对象

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节点有不同的办法可以获取:

对于正常的网页,直接使用documentwindow.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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值