全栈工程师开发手册 (作者:栾鹏)

快捷链接:
js系列教程1-数组操作全解
js系列教程2-对象和属性全解
js系列教程3-字符串和正则全解
js系列教程4-函数与参数全解
js系列教程5-容器和算法全解
js系列教程6-BOM操作全解
js系列教程7-DOM操作全解
js系列教程8-事件全解
js系列教程9-表单元素全解
js系列教程10-canvas绘图全解
js系列教程11-json、ajax、comet全解
js系列教程12-离线应用与存储全解
js系列教程13-原型、原型链、作用链、闭包全解

js中的DOM操作全解

上一篇文章,我们已经了解了js中的BOM和DOM的关系,这里简单说一下。最好参考js系列教程6-BOM操作全解来了解两者的关系,和BOM的知识体系。

JavaScript的实现包括以下3个部分:

1)核心(ECMAScript):描述了JS的语法和基本对象。
2)文档对象模型 (DOM):处理网页内容的方法和接口
3)浏览器对象模型(BOM):与浏览器交互的方法和接口

BOM包含:window
Window对象包含属性:document、location、navigator、screen、history、frames
Document根节点包含子节点:forms、location、anchors、images、links
从window.document已然可以看出,DOM的最根本的对象是BOM的window对象的子对象。

今天我们就来具体了解一下DOM的知识体系。

文档对象模型(DOM)

DOM节点树模型(以HTML DOM树为例)

这里写图片描述

DOM模型将整个文档(XML文档和HTML文档)看成一个树形结构,
在DOM中,HTML文档的层次结构被表示为一个树形结构。并用document对象表示该文档,树的每个子节点表示HTML文档中的不同内容。
每个载入浏览器的 HTML 文档都会成为Document对象,Document是探索DOM的入口,利用全局变量document可以访问Document对象

2.1认识DOM

先看下面代码

这里写图片描述

将HTML代码分解为DOM节点层次图:

这里写图片描述

DOM通过创建树来表示文档,描述了处理网页内容的方法和接口,从而使开发者对文档的内容和结构具有空前的控制力,用DOM API可以轻松地删除、添加和替换节点。
1)节点类型

DOM规定文档中的每个成分都是一个节点(Node),HTML文档可以说由节点构成的集合,DOM节点有:
1)元素节点(Element):上图中<html>、<body>、<p>等都是元素节点,即标签。
2)文本节点(Text):向用户展示的内容,如<li>...</li>中的JavaScript、DOM、CSS等文本。
3)属性节点(Attr):元素属性,元素才有属性,如<a>标签的链接属性href="http://www.baidu.com"

1) DOM节点三大属性(XML DOM)

1)nodeName:元素节点、属性节点、文本节点分别返回元素的名称、属性的名称和#text的字符串。
2)nodeType:元素节点、属性节点、文本节点的nodeType值分别为1、2、3.、
3)nodeValue:元素节点、属性节点、文本节点的返回值分别为null、属性值和文本节点内容。

2.2 DOM常见操作

Node为所有节点的父接口,其定义了一组公共的属性和方法,如下:

这里写图片描述

1)获取节点

① 获取元素节点:
通过document对象的三个方法获取。

document.getElementById("ID")
document.getElementByName("name")
document.getElementsByTagName("p");

② 获取属性节点:
属性节点附属于元素节点,可通过元素节点的getAttributeNode(attrName)方法获取属性节点,也可通过getAttribute(attrName)直接获取属性值。(与之相对的是Element接口的setAttribute(attrName , attrValue)方法,如果属性不存在,则直接添加到元素节点上)

③ 获取文本节点:
文本节点为元素节点的子节点,可通过元素节点(Element接口)提供的childnodes()[index] 方法获得。

childNodes //NodeList,所有子节点的列表
firstChild //Node,指向在childNodes列表中的第一个节点  
lastChild //Node,指向在childNodes列表中的最后一个节点  
parentNode //Node,指向父节点  
previousSibling /Node,/指向前一个兄弟节点:如果这个节点就是第一个节点,那么该值为 null
nextSibling //Node,指向后一个兄弟节点:如果这个节点就是最后一个节点,那么该值为null
hasChildNodes()` //Boolean,当childNodes包含一个或多个节点时,返回真值

2)改变节点

(1)改变属性节点的值:可以通过属性节点的nodeValue直接修改属性值,也可通过元素节点的setAttribute()方法改变。
(2)改变文本节点的值:通过文本节点的nodeValue直接修改。
在HTML DOM中,获取和改变元素内容最简单方法是使用元素的innerHTML属性(innerText属性返回去掉标签的innerHTML)

拓展:

innerText、innerHTML、outerHTML、outerText
innerText: 表示起始标签和结束标签之间的文本
innerHTML: 表示元素的所有元素和文本的HTML代码
如:<div><b>Hello</b> world</div>的innerText为Hello world,innerHTML为Hello world
outerText: 与前者的区别是替换的是整个目标节点,问题返回和innerText一样的内容
outerHTML: 与前者的区别是替换的是整个目标节点,返回元素完整的HTML代码,包括元素本身

一张图了解outerHTML和innerText、innerHTML:
这里写图片描述

改变HTML样式(style属性):element.style.color =“red”;

3)删除节点

① 删除元素节点:要想删除元素节点A,需获得A的父节点B,父节点可通过17.1.1中的方法获得,也可以直接通过A的parentNode属性获得(推荐)。调用B的removeChild(A)即可删除A节点。

② 删除属性节点:可通过属性节点所属的元素节点的removeAttribute(attrName)或removeAttributeNode(node)删除。

③ 清空文本节点:最简单也是最常用的方法就是直接设置文本节点的nameNode属性为空串:textNode.nodeValue =””。

混淆点:

<p id="example" title="texts">
  这是一段文本
  <span></span>
</p>

var p = document.getElementById(‘example’);
p.nodeValue //null,p是元素节点,所以nodeValue为null

p.getAttributeNode(‘id’).nodeValue //example,这里获取到p的id属性的属性节点,nodeValue就是它的属性值

p.childNodes[0].nodeValue //这是一段文本,
p是含有两个子节点的,插入的文本虽然没有标签,但它依然是一个节点。
其类型是是文本节点,其nodeValue是就是写入在其中的字符串,包含换行和缩进

p.innerHTML//这是一段文本 <span></span>"
这里innerHTML返回了p所包含的全部的节点的所包含的各种值了,以字符串的形式。

4)创建和添加节点

① 创建节点:通过document对象的createElement(eleName)、createTextNode(nodeValue)方法可分别创建元素节点和文本节点。属性节点也有自己的create方法,但是用的少,直接用元素节点的setAttribute()方法即可添加属性。

② 添加节点:两个重要的方法:appendChild()和insertBefore(),具体见Node接口中的方法。
扩展:上面的两个方法都是在已知父节点时用到的,也可以直接在兄弟节点后添加新节点:x.insertBefore(newNode)和x.appendChild(newNode)都可以向x后追加一个新的子节点。

5)替换节点

主要掌握replaceChild(newNode , oldNode) 替换元素节点。(属性节点和文本节点有更简单的方法)

2.3 DOM事件

DOM同时两种事件模型:冒泡型事件和捕获型事件
冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标的顺序触发

<body onclick="handleClick()">
  <div onclick="handleClick()">Click Me</div>
</body>

触发的顺序是:div、body、html(IE 6.0和Mozilla 1.0)、document、window(Mozilla 1.0)

捕获型事件:与冒泡事件相反的过程,事件从最不精确的对象开始触发,然后到最精确
上面例子触发的顺序是:document、div
DOM事件模型最独特的性质是,文本节点也触发事件(在IE中不会)。
1)事件处理函数/监听函数

在JavaScript中:

var oDiv = document.getElementById("div1");
oDiv.onclick = function(){ //onclick只能用小写
   alert("Clicked!");
}
或者
var elem =document.getElementById(“id”)
elem.onmouseover=handleMouseOver  //handleMouseOver  是函数名
Function handleMouseOve(e){...}
 

在HTML中:

<div onclick="javascript: alert("Clicked!")"></div> //onclick大小写任意

扩展:

IE事件处理程序attachEvent()和detachEvent()
在IE中,每个元素和window对象都有两个方法:attachEvent()和detachEvent(),这两个方法接受两个相同的参数,事件处理程序名称和事件处理程序函数,如:

[object].attachEvent("name_of_event_handler","function_to_attach")
[object].detachEvent("name_of_event_handler","function_to_remove")
var fnClick = function(){
  alert("Clicked!");
}
oDiv.attachEvent("onclick", fnClick); //添加事件处理函数
oDiv.attachEvent("onclick", fnClickAnother); // 可以添加多个事件处理函数
oDiv.detachEvent("onclick", fnClick); //移除事件处理函数

在使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,因此this等于window。

2)跨浏览器的事件处理程序

addHandler()和removeHandler()
addHandler()方法属于一个叫EventUntil()的对象,这两个方法均接受三个相同的参数,要操作的元素,事件名称和事件处理程序函数。

3)事件类型

鼠标事件:click、dbclick、mousedown、mouseup、mouseover、mouseout、mousemove
键盘事件:keydown、keypress、keyup
HTML事件:load、unload、abort、error、select、change、submit、reset、resize、scroll、focus、blur

4)事件处理器

执行JavaScript 代码的程序在事件发生时会对事件做出响应。为了响应一个特定事件
而被执行的代码称为事件处理器。
在HTML标签中使用事件处理器的语法是:
<HTML标签 事件处理器="JavaScript代码’'>

5)事件处理程序

事件就是用户或浏览器自身执行的某种动作。比如click,mouseup,keydown,mouseover等都是事件的名字。而响应某个事件的函数就叫事件处理程序(事件监听器),事件处理程序以on开头,因此click的事件处理程序就是onclick

6)DOM 0级事件处理程序

DOM 0级事件处理程序:把一个函数赋值给一个事件的处理程序属性

<input type="button" value="按钮2" id="ben2"/>
     var btn2=document.getElementById('btn2');获得btn2按钮对象
     btn2.onclick      //给btn2添加onclick属性,属性又触发了一个事件处理程序
 
btn2.onclick=function(){
}                    //添加匿名函数
 
btn2.onclick=null      //删除onclick属性

7)DOM 2级事件处理程序

DOM 2级事件定义了两个方法,用于指定和删除事件处理程序的操作。addEventListener()和removeEventListener()

addEventListener()和removeEventListener()
在DOM中,addEventListener()和removeEventListener()用来分配和移除事件处理函数,与IE不同的是,这些方法需要三个参数:事件名称,要分配的函数和处理函数是用于冒泡阶段(false)还是捕获阶段(true),默认为冒泡阶段false

[object].addEventListener("name_of_event",fnhander,bcapture)
[object].removeEventListener("name_of_event",fnhander,bcapture)
var fnClick = function(){
  alert("Clicked!");
}
oDiv.addEventListener("onclick", fnClick, false); //添加事件处理函数
oDiv.addEventListener("onclick", fnClickAnother, false); // 与IE一样,可以添加多个事件处理函数
 
oDiv.removeEventListener("onclick", fnClick, false); //移除事件处理函数
如果使用addEventListener()将事件处理函数加入到捕获阶段,则必须在removeEventListener()中指明是捕获阶段,才能正确地将这个事件处理函数删除
oDiv.onclick = fnClick;
oDiv.onclick = fnClickAnother; //使用直接赋值,后续的事件处理函数会覆盖前面的处理函数
oDiv.onclick = fnClick;
oDiv.addEventListener("onclick", fnClickAnother, false); //会按顺序进行调用,不会覆盖

3.6 Document对象

1)对象属性

document.body				//提供对 <body>元素的直接访问。
document.cookie 			//返回与当前文档有关的所有 cookie。
document.title 				//返回文档标题等价于HTML的title标签
document.domain 			//返回当前文档的域名。
document.bgColor 			//返回页面背景色
document.fgColor 			//返回前景色(文本颜色)
document.linkColor 			//未点击过的链接颜色
document.alinkColor 		//激活链接(焦点在此链接上)的颜色
document.vlinkColor 		//已点击过的链接颜色
document.URL 				//设置URL属性从而在同一窗口打开另一网页
document.fileCreatedDate 	//文件建立日期,只读属性
document.fileModifiedDate 	//文件修改日期,只读属性
document.lastModified 		//返回文档被最后修改的日期和时间。
document.fileSize 			//文件大小,只读属性
document.cookie 			//设置和读出cookie
document.charset 			//返回字符集 简体中文:gb2312
document.URL 				//返回当前文档的 URL。
document.referrer 			//返回载入当前文档的文档的 URL。
document.styleSheets 		//返回样式表的集合,返回值CSSStyleSheet[]
document.styleSheets[0].cssRules.style.paddingTop="10px" //设置样式,样式名去掉连字符,

2)常用对象方法

document.write() 					//动态向页面写入内容
document.writeln() 					//等同于 write() 方法,之后写一个换行符。
document.createElement(<Tag>) 		//用指定标签类型创建一个新的element对象
document.getElementById(ID) 		//获得指定ID值的对象
document.getElementsByName(Name) 	//获得指定Name值的对象
document.getElementsByTagName() 	//返回带有指定标签名的对象集合。

———————————————————————
3)body-主体子对象

document.body 					//指定文档主体的开始和结束
document.body.bgColor 			//设置或获取对象后面的背景颜色
document.body.link 				//未点击过的链接颜色
document.body.alink 			//激活链接(焦点在此链接上)的颜色
document.body.vlink 			//已点击过的链接颜色
document.body.text 				//文本色
document.body.innerText 		//设置<body>…</body>之间的文本
document.body.innerHTML 		//设置<body>…</body>之间的HTML代码
document.body.topMargin 		//页面上边距
document.body.leftMargin 		//页面左边距
document.body.rightMargin 		//页面右边距
document.body.bottomMargin 		//页面下边距
document.body.background 		//背景图片
document.body.appendChild(oTag) 	//动态生成一个HTML对象
document.body.onclick="func()"		//鼠标指针单击对象是触发
document.body.onmouseover="func()"	//鼠标指针移到对象时触发
document.body.onmouseout="func()"	//鼠标指针移出对象时触发

———————————————————————
5)selection-选区子对象
document.selection
6)forms集合(页面中的表单)

a)通过集合引用

document.forms 					//对应页面上的form标签
document.forms.length 			//对应页面上/formform标签的个数
document.forms[0] 				//第1个/formform标签
document.forms[i] 				//第i-1个/formform标签
document.forms[i].length 		//第i-1个/formform中的控件数
document.forms[i].elements[j] 	//第i-1个/formform中第j-1个控件

b)通过标签name属性直接引用

<form name="Myform">input name="myctrl"/></form>
document.Myform.myctrl 		//document.表单名.控件名

c)访问表单的属性

document.forms[i].name 				//对应form name>属性
document.forms[i].action 			//对应/formform action>属性
document.forms[i].encoding 			//对应/formform enctype>属性
document.forms[i].target 			//对应/formform target>属性
document.forms[i].appendChild(oTag) //动态插入一个控件
document.all.oDiv 					//引用图层oDiv
document.all.oDiv.style.display=” 	//图层设置为可视
document.all.oDiv.style.display=”none”//图层设置为隐藏
document.getElementId(”oDiv”) 		//通过getElementId引用对象
document.getElementId(”oDiv”).style=”
document.getElementId(”oDiv”).display=”none”
/*document.all表示document中所有对象的集合
只有ie支持此属性,因此也用来判断浏览器的种类*/

3.7 HTMLElement对象

HTML DOM 节点

在 HTML DOM (文档对象模型)中,每个部分都是节点:
1.文档本身是文档节点
2.所有 HTML元素是元素节点
3.所有 HTML属性是属性节点
4.HTML 元素内的文本是文本节点
5.注释是注释节点

Element 对象

在 HTML DOM 中,Element对象表示HTML元素。
Element 对象可以拥有类型为元素节点、文本节点、注释节点的子节点。
NodeList 对象表示节点列表,比如 HTML元素的子节点集合。
元素也可以拥有属性。属性是属性节点

获取

document.getElementById(ID) 			//获得指定ID值的对象
document.getElementsByName(Name) 		//获得指定Name值的对象
getElementsByTagName() 					//返回带有指定标签名的对象集合。

属性和方法

方法里有a,b的参数仅仅是为了加深说明,其他元素没有a,b不代表是无参方法

Element.add(<class>)		给元素添加指定的类
element.accessKey 			设置或返回元素的快捷键。
element.appendChild() 		向元素添加新的子节点,作为最后一个子节点。
element.attributes 			返回元素属性的集合。
element.childNodes 			返回元素子节点的 NodeList。
element.className 			设置或返回元素的 class 属性。
element.clientHeight 		返回元素的可见高度。
element.clientWidth 		返回元素的可见宽度。
element.cloneNode() 		克隆元素。
element.compareDocumentPosition() 比较两个元素的文档位置。
element.contentEditable 	设置或返回元素的文本方向。
element.dir 				设置或返回元素的文本方向。
element.firstChild 			返回元素的首个子。
element.getAttribute() 		返回元素节点的指定属性值。
element.getAttributeNode() 	返回指定的属性节点。
element.getElementsByTagName() 返回拥有指定标签名的所有子元素的集合。
element.getFeature() 		返回实现了指定特性的 API 的某个对象。
element.getUserData() 		返回关联元素上键的对象。
Element.hidden				获取或设置hidden属性的存在状态
element.hasAttribute() 		如果元素拥有指定属性,则返回true,否则返回false。
element.hasAttributes() 	如果元素拥有属性,则返回 true,否则返回false。
element.hasChildNodes() 	如果元素拥有子节点,则返回 true,否则false。
element.id 					设置或返回元素的 id。
element.innerHTML 			设置或返回元素的内容。
element.insertBefore(<a>,<b>) 在指定的已有的子节点之前插入新节点。A插到b前
element.isContentEditable 	设置或返回元素的内容。
element.isDefaultNamespace()如果指定的 namespaceURI是默认的,则返回true,否则返回false。
element.isEqualNode(<a>) 	检查a元素是否与当前元素相等。
element.isSameNode(a) 		检查指定元素是否就是当前元素.
element.isSupported() 		如果元素支持指定特性,则返回 true。
element.lang 				设置或返回元素的语言代码。
element.lastChild 			返回元素的最后一个子元素。
element.namespaceURI 		返回元素的 namespace URI。
element.nextSibling 		返回当前元素之后的兄弟元素
element.nodeName 			返回元素的名称。
element.nodeType 			返回元素的节点类型。
element.nodeValue 			设置或返回元素值。
element.normalize() 		合并元素中相邻的文本节点,并移除空的文本节点。
element.offsetHeight 		返回元素的高度。
element.offsetWidth 		返回元素的宽度。
element.offsetLeft 			返回元素的水平偏移位置。
element.offsetParent 		返回元素的偏移容器。
element.offsetTop 			返回元素的垂直偏移位置。
element.ownerDocument 		返回元素的根元素(文档对象)。
element.parentNode 			返回元素的父节点。
element.previousSibling 	返回当前元素之前的兄弟元素
Element.remove(<class>) 	从元素移除指定的类
element.removeAttribute() 	从元素中移除指定属性。
element.removeAttributeNode() 移除指定的属性节点,并返回被移除的节点。
element.removeChild(a) 		从元素中移除子节点。
element.replaceChild(a,b) 	替换元素中的子节点。
element.scrollHeight 		返回元素的整体高度。
element.scrollLeft 			返回元素左边缘与视图之间的距离。
element.scrollTop 			返回元素上边缘与视图之间的距离。
element.scrollWidth 		返回元素的整体宽度。
element.setAttribute() 		把指定属性设置或更改为指定值。
element.setAttributeNode() 	设置或更改指定属性节点。
element.setIdAttribute()
element.setIdAttributeNode()
element.setUserData() 		把对象关联到元素上的键。
element.style 				设置或返回元素的 style 属性。
Element.toggle(<class>)		如果类不存在就添加它存在就移除它
element.tabIndex 			设置或返回元素的 tab 键控制次序。
element.tagName 			返回元素的标签名。
element.textContent 		设置或返回节点及其后代的文本内容。
element.title 				设置或返回元素的 title 属性。
element.toString() 			把元素转换为字符串。
nodelist.item() 			返回 NodeList 中位于指定下标的节点。
nodelist.length 			返回 NodeList 中的节点数。

element.addEventListener(event, function, useCapture)
参数      			描述
event       		必须。字符串,指定事件名。
					注意: 不要使用"on"前缀。 例如,使用"click" ,而不是使用"onclick"。
					提示: 所有 HTML DOM 事件,可以查看我们完整的HTML DOM Event对象参考手册。
function			必须。指定要事件触发时执行的函数。
					当事件对象会作为第一个参数传入函数。 事件对象的类型取决于特定的事件。例如, "click" 事件属于 MouseEvent(鼠标事件)对象。
 
useCapture			可选。布尔值,指定事件是否在捕获或冒泡阶段执行。
					可能值:
					true - 事件句柄在捕获阶段执行
					false- false- 默认。事件句柄在冒泡阶段执行

1)Table 对象

这里写图片描述

这里写图片描述

rows 集合返回表格中所有行(TableRow对象)的一个数组,该集合包括、和中定义的所有行
TableRow 对象
TableRow 对象代表一个HTML表格行。
在 HTML 文档中 标签每出现一次,一个 TableRow对象就会被创建。
TableCell 对象代表一个HTML 表格单元格。
在一个 HTML 文档中 标签每出现一次,一个 TableCell对象就会被创建

3.8 Event对象

1)Event对象的常用属性

名称        			说明						返回

target				事件指向的元素				HTMLElement

1. type:事件的类型,如onlick中的click;

2. srcElement/target:事件源,就是发生事件的元素;

3. button:声明被按下的鼠标键,整数,1代表左键,2代表右键,4代表中键,如果按下多个键,酒把这些值加起来,所以3就代表左右键同时按下;(firefox中 0代表左键,1代表中间键,2代表右键)

4. clientX/clientY:事件发生的时候,鼠标相对于浏览器窗口可视文档区域的左上角的位置;(在DOM标准中,这两个属性值都不考虑文档的滚动情况,也就是说,无论文档滚动到哪里,只要事件发生在窗口左上角,clientX和clientY都是 0,所以在IE中,要想得到事件发生的坐标相对于文档开头的位置,要加上
document.body.scrollLeft和 document.body.scrollTop)

5. offsetX,offsetY/layerX,layerY:事件发生的时候,鼠标相对于源元素左上角的位置;

6. x,y/pageX,pageY:检索相对于父要素鼠标水平坐标的整数;

7. altKey,ctrlKey,shiftKey等:返回一个布尔值;

8. keyCode:返回keydown何keyup事件发生的时候按键的代码,以及keypress 事件的Unicode字符;(firefox2不支持 event.keycode,可以用 event.which替代 )

9. fromElement,toElement:前者是指代mouseover事件中鼠标移动过的文档元素,后者指代mouseout事件中鼠标移动到的文档元素;

10. cancelBubble:一个布尔属性,把它设置为true的时候,将停止事件进一步起泡到包容层次的元素;(e.cancelBubble = true; 相当于 e.stopPropagation();)

11. returnValue:一个布尔属性,设置为false的时候可以组织浏览器执行默认的事件动作;(e.returnValue = false; 相当于 e.preventDefault();)

12. attachEvent(),detachEvent()/addEventListener(),removeEventListener:为制定 DOM对象事件类型注册多个事件处理函数的方法,它们有两个参数,第一个是事件类型,第二个是事件处理函数。在
attachEvent()事件执行的时候,this关键字指向的是window对象,而不是发生事件的那个元素;

13. screenX、screenY:鼠标指针相对于显示器左上角的位置,如果你想打开新的窗口,这两个属性很重要;

2)Window 事件属性

针对 window 对象触发的事件(应用到<body>标签):

onafterprint    文档打印之后运行的脚本。
onbeforeprint 文档打印之前运行的脚本。
onbeforeunload 文档卸载之前运行的脚本。
onerror 在错误发生时运行的脚本。
onhaschange 当文档已改变时运行的脚本。
onload 页面结束加载之后触发。
onmessage 在消息被触发时运行的脚本。
可以使用调用 postMessage ()向主线程发送消息,在某些场景下,业务调用方可能需要主动跟定位组件通信,可以通过html5 postMessage的方式主动与定位组件发起通信
onoffline 当文档离线时运行的脚本。
ononline 当文档上线时运行的脚本。
onpagehide 当窗口隐藏时运行的脚本。
onpageshow 当窗口成为可见时运行的脚本。
onpopstate 当窗口历史记录改变时运行的脚本。
onredo 当文档执行撤销(redo)时运行的脚本。
onresize 当浏览器窗口被调整大小时触发。
onstorage 在 Web Storage 区域更新后运行的脚本。
onundo 在文档执行 undo 时运行的脚本。
onunload 一旦页面已下载时触发(或者浏览器窗口已被关闭)。

3)Form 事件

由 HTML 表单内的动作触发的事件(应用到几乎所有HTML元素,但最常用在form元素中):
属性
onblur 元素失去焦点时运行的脚本。
onchange在元素值被改变时运行的脚本。
oncontextmenu 当上下文菜单被触发时运行的脚本。
onfocus 当元素失去焦点时运行的脚本。
onformchange 在表单改变时运行的脚本。
onforminput 当表单获得用户输入时运行的脚本。
oninput 当元素获得用户输入时运行的脚本。
oninvalid 当元素无效时运行的脚本。
onreset 当表单中的重置按钮被点击时触发。HTML5中不支持。
onselect 在元素中文本被选中后触发。
onsubmit 在提交表单时触发。

4)oninput,onpropertychange,onchange的用法

oninput:
oninput 事件在用户输入时触发。
该事件在 或元素的值发生改变时触发。
提示: 该事件类似于 onchange 事件。不同之处在于oninput事件在元素值发生变化是立即触发,onchange在元素失去焦点时触发。另外一点不同是onchange事件也可以作用于和元素。
onchange
onchange 事件会在域的内容改变时发生。
onchange 事件也可用于单选框与复选框改变后触发的事件。

onchange触发事件必须满足两个条件:
a)当前对象属性改变,并且是由键盘或鼠标事件激发的(脚本触发无效)
b)当前对象失去焦点(onblur);
onpropertychange的话,只要当前对象属性发生改变,都会触发事件,但是它是IE专属的;
oninput是onpropertychange的非IE浏览器版本,支持firefox和opera等浏览器,但有一点不同,它绑定于对象时,并非该对象所有属性改变都能触发事件,它只在对象value值发生改变时奏效。
在textarea中,如果想捕获用户的键盘输入,用onkeyup检查事件就可以了,但是onkeyup并不支持复制和粘贴,因此需要动态监测textarea中值的变化,这就需要onpropertychange(用在IE浏览器)和oninput(非IE浏览器)结合在一起使用了。

5)移动端 触摸事件

ontouchstart、ontouchmove、ontouchend、ontouchcancel

1、Touch事件简介

pc上的web页面鼠 标会产生onmousedown、onmouseup、onmouseout、onmouseover、onmousemove的事件,但是在移动终端如iphone、ipod Touch、ipad上的web页面触屏时会产生ontouchstart、ontouchmove、ontouchend、ontouchcancel事件,分别对应了触屏开始、拖拽及完成触屏事件和取消。
当按下手指时,触发ontouchstart;
当移动手指时,触发ontouchmove;
当移走手指时,触发ontouchend。
当一些更高级别的事件发生的时候(如电话接入或者弹出信息)会取消当前的touch操作,即触发ontouchcancel。一般会在ontouchcancel时暂停游戏、存档等操作。

2、Touch事件与Mouse事件的出发关系

在触屏操作后,手指提起的一刹那(即发生ontouchend后),系统会判断接收到事件的element的内容是否被改变,如果内容被改变,接下来的事 件都不会触发,如果没有改变,会按照mousedown,mouseup,click的顺序触发事件。特别需要提到的是,只有再触发一个触屏事件时,才会 触发上一个事件的mouseout事件。

  1. DOM基本操作思维导图

这里写图片描述

代码示例:



console.log("===========DOM文档信息===========");
var docinf={};
docinf["html"]=document.documentElement;        //document表示对文件的引用。
docinf["title"]=document.title;                 //获取标题节点,可设置标题
docinf["body"]=document.body;                    //获取body节点
docinf["url"]=document.URL;                      //网址
docinf["domain"]=document.domain;               //域名,可设置
docinf["referrer"]=document.referrer;           //来源页面的url
console.log(JSON.stringify(docinf));
//writeln写入h5代码并添加换行。document.write在文件加载期间写入内容,在文件加载后写入会重写全部文件。
document.write("<script type='text/javascript' src='index3.js'>"+"</script>");  //write写入h5代码(动态加载js代码index3.js,若在<script>添加内部<script><\/script>)



console.log("===========DOM元素节点信息===========");
var elementinfo={};
var hint =  document.getElementById("hint2");
elementinfo["tagName"] =hint.tagName;                //元素标签名,nodename也是获取节点标签名
elementinfo["id"] =hint.id;                          //唯一标识符,可修改,修改透明
elementinfo["className"] =hint.className;           //特性名称,可修改,修改立即可见
elementinfo["title"] =hint.title;                   //元素说明,可修改,鼠标经过可见
elementinfo["lang"] =hint.lang;                     //语言,可修改,修改透明
elementinfo["dir"] =hint.dir;                       //方向,可修改,属性重写可见
hint.setAttribute("myname",hint.dataset.myname);    //setAttribute设置或创建属性。自带属性也可以直接赋值hint.id="xxxx"。dataset元素的数据属性
elementinfo["myname"] =hint.getAttribute("myname"); //getAttribute获取自定义属性,也可以获取自带属性
console.log(JSON.stringify(elementinfo));
hint.removeAttribute("myatt");                      //删除属性



console.log("===========DOM元素节点操作===========");  //元素是一种节点。注意区分
//动态创建布局元素
hint3 = document.createElement("label");            //创建元素,传入标签名,元素节点类型值为1
//label = document.createElement("<label class='hintclass' style='background-color: #123456;' id='hint3' name='tity'></label>");  		//创建元素,传入h5代码
//label = document.getElementById("hint2").cloneNode("true");//也可以使用cloneNode复制节点,参数为true表示深层复制,即复制节点内部子节点,false表示浅复制
hint3.id = "hint3";
hint3.className = "hintclass";
hint3.setAttribute("name","tity");
hint3.style.background="#123456";//
var computedstyle = document.defaultView.getComputedStyle(hint3,null);//获取元素计算后样式,只读对象,不能通过此对象进行设置
console.log(JSON.stringify(computedstyle));              //包含了所有样式属性
console.log(hint3.style.cssText);                        //style是通过style设置的,cssText样式的字符串表示,length样式属性的长度,[index]或者item(index)给定位置的样式属性名,getPropertyValue(propertyName)给定属性名的属性值,removeProperty删除属性
//appendChild在父元素内部末尾添加子元素,insertBefore在指定子元素前添加子元素,replaceChild替换子元素
if(!hintdiv.contains(hint3))                        //contains判断元素是否包含子元素
    hintdiv.appendChild(hint3);                     //在末尾添加子节点
//子节点可能是元素,文本节点,注释或者处理指令,不同的浏览器看待不同
hint3 =hintdiv.removeChild(hintdiv.lastChild);      //removeChild删除子节点,lastChild最后一个子节点,firstChild第一个子节点
var hint1=hintdiv.children[1];                      //childNodes父节点的子节点集合,parentNode获取节点的父节点。children表示子元素集合
var hint2=hint1.nextElementSibling;                 //nextSibling获取下一个兄弟节点,previousSBiling获得上一个兄弟节点,nextElementSibling下一个同辈元素,previousElementSibling前一个同辈元素
label = hintdiv.insertBefore(hint3,hint2.nextElementSibling);//hint2.nextSibling为空,因为最后一个子节点的下一个兄弟节点和第一个节点的上一个兄弟节点均为空。参数为空,表示在末尾插入节点。

//动态加载脚本文件和内嵌脚本
var script = document.createElement("script");
script.type="text/javascript";
script.src = "index4.js";
//script.text = "function sayHi(){printf('动态加载内嵌脚本';)}"
document.body.appendChild(script);


//动态创建样式文件
var link = document.createElement("link");
link.rel = "stylesheet";
link.type="text/css";
link.href="index.css";
//script.text = "function sayHi(){printf('动态加载内嵌脚本';)}"
document.head.appendChild(link);                    //样式文件是添加到head中,不是body中
//动态添加内嵌样式
var style = document.createElement("style");
style.type = "text/css";
try{
  style.appendChild(document.createTextNode("body{background:red}"));  //非IE浏览器
}catch (err){
  style.stylesheet.cssText  ="body{background:red}";//IE浏览器
}
document.head.appendChild(style);                       //document.head在chrome和safari5中包含。属于后添加的css样式,会覆盖重复样式



console.log("===========DOM文本节点等===========");       //另外还有注释节点、属性节点、文档类型、CDATA区域和文档片段等一系列,不是只有元素才是节点
//文本节点(类型为3)父节点为元素,没有子节点。元素、文本都是节点的一种。文本节点的节点类型值为3
var textnode = document.createTextNode("<strong>hello</strong>world\r\n");//可以是h5格式的文本,也可以直接为字符串
hint2 = document.getElementById("hint2");
hint2.appendChild(textnode);                             //将本文节点添加到元素中
textnode.appendData(textnode.nodeValue);                //nodeValue文本节点所包含的文本,appendData添加文本。deleteData(offset,count)删除,insertData(offset,text)插入,replaceData(offset,count,text)替换,splitText分割文本节点



console.log("===========DOM扩展===========");
var body = document.querySelector("body");              //取得标签类别获取元素
var mydiv = document.querySelector("#hintdiv");         //根据id获取元素
var hint2 = document.querySelector(".hintclass");       //根据类class获取匹配的第一个元素。通过文档document查询,在整个文档范围内查询。
hint2 = mydiv.querySelector("label.hintclass");         //根据元素类别和类名获取元素。通过元素Element查询,在元素之后查询。
var hintarr = document.querySelectorAll("div label");   //querySelectorAll查询匹配的全部元素。获得div中的label元素
if(hint2==hintarr[2])
    console.log("同一个元素");

hint2.classList.toggle("user");                           //classList元素样式类控制,add添加样式,contain是否包含,remove去除,toggle添加或删除。也可以通过className设置类字符串
hint2.focus();//focus使元素获取节点。document.actuveElement获取当前聚焦元素,文档加载完毕后,聚焦元素由null转为body,hasFocus判断元素是否聚焦。浏览器会自动滚动至聚焦元素
console.log(hintdiv.outerHTML.replace(hintdiv.innerHTML,"")); //outerHTML获取和设置元素及其所有子元素字符串表示//innerHTML获取和设置元素的所有子元素字符串表示,innerText用于获取元素中的夹杂文本,outerText用于替换子元素成文本节点。不是标准的h5
hintdiv.insertAdjacentHTML("beforeend","<strong>hello</strong> world");//添加了三个节点,<strong>元素、hello、world两个文本节点。
//insertAdjacentHTML插入元素。beforebegin在元素前插入一个兄弟元素,afterbegin在元素下首部插入子元素,beforeend在元素下尾部插入子元素,afterend在元素后插入兄弟元素
hintdiv1.scrollIntoView();                                  //使元素滚动至视口中,不传参数或传入true,保持顶部对齐,传入false保持底部对齐。


console.log("===========DOM2  DOM3===========");
style = document.getElementsByTagName("style")[0];          //获取第一个style元素
var sheet = style.sheet||style.styleSheet;                  //通过link或style元素获取样式对象。IE浏览器支持styleSheet获取样式表,其他浏览器支持sheet获取样式表CSSStyleSheet对象
if(document.styleSheets[document.styleSheets.length-2]==sheet);  //document.styleSheets应用到文档的所有样式表,css文件中每个样式算一个样式表,h5中每个style元素算一个样式表。
    console.log(JSON.stringify(sheet));

var rules = sheet.cssRules || sheet.rules;                  //根据样式表,获取规则列表。因为一个样式表可能有多个规则。
var rule = rules[1];//获取第2个规则。即hint1的样式,每个规则有多个样式属性
console.log(rule.style.cssText);                             //与元素的style.cssText类似,不过规则cssText不能重写
rule.style.color = "black";                                  //修改样式规则,添加样式属性
sheet.insertRule("#hint{color: #883456}",0);                 //动态添加样式规则,第一个参数为规则为字符串,第二个参数为规则数组索引,IE使用addRule。删除规则使用deleteRule或removeRule
console.log(hint2.scrollWidth);                              //即html的包含滚动内容的大小,元素属性//scrollHeight、scrollWidth包含滚动内容的大小,scrollTop滚动高度,scrollLeft滚动左偏移,属性可读取和设置
console.log(hint2.clientHeight);                             //clientWidth和clientHeight包括内边距,但不包括边框
console.log(hint2.offsetHeight);                             //offsetLeft、offsetTop、offsetHeight(包括边框,内边距)、offsetWidth、offsetParent
console.log(JSON.stringify(hint2.getBoundingClientRect()));  //返回元素的位置矩阵,包含left、top、right、bottom属性


console.log("===========遍历===========");
if(document.implementation.hasFeature("Traversal","2.0"))   //检查浏览器某项功能能力
{
    var filter = function(node){                            //设置查询过滤器
        return node.tagName.toLowerCase()=="label"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP;   //在TreeWalker中还有NodeFilter.FILTER_REJECT表示跳过该节点及该节点的子节点
    };
    var iterator = document.createNodeIterator(hintdiv,NodeFilter.SHOW_ELEMENT,filter,false);  //创建NodeIterator迭代器。参数:查询根节点,查询节点,过滤器。NodeFilter.SHOW_ELEMENT为查询节点类型为元素节点,可以使用|包含多种查询节点类型,
    var node = iterator.nextNode();                         //第一个节点,
    while(node!=null){                                      //最后一个节点的后续节点为null,第一个节点的前序节点为null
        console.log(node.id);
        node = iterator.nextNode();                         //向后迭代,previousNode向前迭代
    }
    iterator = document.createTreeWalker(hintdiv,NodeFilter.SHOW_ELEMENT,filter,false);  //创建TreeWalker迭代器,迭代器包含nextNode、previousNode、parentNode、firstChild、lastChild、nextSibling、previousSibling等方法
}
//范围
var range = document.createRange();                              //创建一个节点范围
range.selectNodeContents(hintdiv);                               //selectNode方法包含节点和子节点,selectNodeContents只包含子节点
console.log(range.startContainer.id);                            //startContainer范围中首节点的父节点,startOffset首节点在父节点中的偏移,endContainer尾节点的父节点,endOffset尾节点在父节点中的偏移。
range.setStart(hintdiv,0);                                       //也可以通过setStart和setEnd设置范围。setStart的参数为startContainer和startOffset
range.setStartBefore(hintdiv.lastChild);                         //也可以通过setStartBefore,setStartAfter,setEndBefore、setEndAfter设置。这里获取hintdiv的最后一个节点,即上面代码添加的world文本节点
console.log(range.toString());                                   //打印范围的字符串表示 world
var fragment = range.extractContents();                          //提取范围成文档片段,range.deleteContents删除文档,range.cloneContents复制文档
hintdiv.appendChild(fragment);                                   //添加文档片段。
range.detach();range=null;                                       //清理DOM范围,var newRange = range.cloneRange可以复制DOM范围

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐