文章目录
DOM 重点核心
关于DOM操作,主要针对于元素的操作。主要有创建、增、删、改、查、属性操作、事件操作。
- 创建:document.write,inner HTML,createElement
- 增:appendChild,insertBefore
- 删:removeChild
- 改:主要修改dom的元素属性,如内容,属性值,表单的值等
- 查:
1、dom 提供的API方法:getElementById、getElementsByTagName
2、H5 提供的新方法:querySelector、querySelectorAll (推荐)
3、利用节点操作获取元素:父(parentNode)、子(children)、兄(previousElementSibling、nextElementSibling) - 属性操作:主要针对于自定义属性
1、setAttribute:设置 dom 的属性值
2、getAttribute:得到 dom 的属性值
3、removeAttribute 移除属性 - 事件操作:
1、给元素注册事件
DOM的节点层级
任何HTML或XML文档都可以用DOM表示为一个由节点构成的层级结构。节点分很多类型,每种类型对应着HTML文档中不同的信息和(或)标记。
每种节点都有自己不同的特性、数据和方法,而且与其他类型有某种关系(相当于把文档树比作家谱)。这些关系构成了层级,让标记可以表示为以一个特定节点为根的树形结构。
以以下的HTML为例:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="./a.css"/>
</head>
<body>
<p>hello word</p>
<script src="index.js"></script>
</body>
</html>
其DOM层级结构(DOM树)如下:
其中,Document 节点表示为每个文档的根节点。在这里,根节点的唯一子节点是 < html > 元素,称为文档元素。
并且 HTML 中的每段标记都可以表示为这个树形结构中的一个节点。元素节点表示 HTML 元素,属性节点表示属性,文档类型节点表示文档类型,注释节点表示注释。
DOM中总共有12种节点类型,这些类型都继承一种基本类型。
节点关系
- 文档中的所有节点都与其他节点有关系
- 这种关系可以形容为家族关系,相当于把文档树比作家谱
- 利用这些关系指针,几乎可以访问到文档树的任何节点
- 这种便利性是 childNodes 的最大亮点
- 下图形象的展示了这些关系:
Node类型
DOM Level 1 描述了名为 Node 的接口,这个接口是所有 DOM 节点类型都必须实现的。Node 接口在 JavaScript中被实现为 Node 类型。
在 JavaScript 中,所有节点类型都继承 Node 类型,因此所有类型都,共享相同的,基本属性和方法。
重点关心下面几个属性:
-
nodeType 节点类型
-
nodeName 节点名称
-
nodeValue 节点值
-
childNodes 获取所有的子节点(包括文档类型节点,甚至代码间的换行空白都被当作节点获取)
-
children 获取所有的元素子节点(不包含文档类型节点)
-
firstChild 获取第一个子节点 (不一定是元素节点)
- lastChild 获取最后一个子节点 -
nextSibling 获取下一个弟弟节点(不一定是元素节点)
-
previousSibling 获取上一个哥哥节点
-
parentNode 获取父亲节点
(注:子节点就是子节点,不包括孙节点)
以及下面几个方法:
-
appendChild 将节点添加为父元素的子节点中的最后一个
-
insertBefore 将节点添加到父元素的子节点中的某一节点的前面
-
replaceChild 替换某一节点
-
removeChild 移除某一节点
-
cloneNode 复制原有的节点,如果传递的值是 true,代表将所有后代元素一起复制;如果传递的是 false,代表只复制当前的元素本身(只有标签没有内容)
-
hasChildNodes 返回一个布尔值,表示当前节点是否包含有子节点
-
normalize
Node 的属性
-
nodeType
每个节点都有nodeType属性,表示该节点的类型。
在JS中常用的只有几个,元素节点,文本节点,注释节点,文档类型节点,他们对应的值是:节点类型 数字 nodeName的值 nodeValue的值 元素节点 1 大写的标签名 null 文本节点 3 #text 文本内容 注释节点 8 #comment 注释内容 document 9 #document null
在标准浏览器中会把空格,Enter 当作文本节点。
-
nodeName和nodeValue
nodeName 和 nodeValue 保存着有关节点的信息。这两个属性的值完全取决于节点类型。在使用这两个属性前,最好先检测节点类型。
对于元素节点nodeName中保存的始终都是元素的标签名,而nodeValue的值则始终为null。
if (someNode.nodeType == 1){
testNodeName = someNode.nodeName;
testNodeValue = someNode.nodeValue;
-
childNodes
-
每个节点都有一个 childNodes 属性,其中包含一个 NodeList实例。
-
NodeList 是一个类数组对象,用于存储按位置存取的有序节点。
注:虽然可以使用中括号访问 NodeList 里面的值,而且也有 length 属性,但它不是 Array 的实例。 -
下面的例子展示如何访问 NodeList 中的节点 — —可以通过item, 也可以通过中括号(推荐)
-
var ul = document.querySelector('ul');
var lis = document.querySelectorAll('li');
var lis_len = lis.length;
var first_child = lis[0]; // 推荐使用
var second_child = lis.item(1);
var last_child = lis[lis_len - 1];
Document类型
Document类型是 JavaScript 中表示文档节点的类型。document表示整个HTML页面。
定位(查找)元素
查看 Document 上的方法,最常用的就是查找元素的方法。
-
getElementById( )
在整个文档中,通过元素的ID获取这个元素,如果没有这个ID,则返回null。
需要注意的是:getElementById( )方法接收一个参数,即要获取元素的ID,且参数ID必须跟元素在页面中的ID属性值完全匹配,包括大小写。如果页面中存在多个具有相同ID的元素,则getElementById( )返回在文档中出现的第一个元素。
-
getElementsByTagName( )
这个方法接收一个参数,即要获取元素的标签名,返回包含零个或多个元素的 NodeList 。因此可用中括号或 item ( )方法取得特定的元素。
-
querySelector( )
这个方法通过不同的选择器获取元素。
-
querySelectorAll ( )
这个方法通过不同的选择器获取一组元素的结合。
文档子节点
DOM规范提供了以下两个访问子节点的快捷方式。虽然 document.childNodes 始终有 < html > 元素,但使用 documentElement 属性可以更快更直接地访问该元素。
- document.documentElement;//拿到 < html > 元素
- document.body;
文档信息
- document.title 设置文档的标题
- document.URL 获取或者设置完整的URL
- document.domain 获取或者设置域名
- document.referrer 取得来源页面的URL
Element类型
Element类型也是Web开发中最常用的类型。
HTML元素
所有HTML元素都通过HTMLElement类型表示。
每个HTML元素都存在下面的标准属性
-
id,元素在文档中的唯一标识符
-
title,包含元素的额外信息,通常以提示条形式展示
-
className,相当于class属性,用于指定元素的CSS类(没有将这个属性命名为class,是因为class是ECMAscript的保留字)
-
lang,元素内容的语言代码(很少用)
-
dir,语言的书写方向(很少用)
取得属性
与属性相关的DOM方法主要有3个,但习惯使用(.)的方法获取属性
- getAttribute( )
- setAttribute( )
- removeAttribute ( )
注:根据HTML5规范要求,自定义属性名前面应该前缀 data- 以方便验证。
创建元素
用 document.createElement( )方法创建新元素。这个方法接收一个参数,即要创建元素的标签名。
创建的元素属于游离状态,还没有被添加到文档树中,因此,新建的元素并不会马上看到,可以使用 appendChild( ),insertBefore ( ),replaceChild( )方法。
事件
javascript 与 HTML 的交互是通过事件实现的,事件意味着用户或浏览器执行的某种动作。
-
DOM 0级事件:
- 行内事件:在标签中写事件
- 元素.on事件名=函数
-
DOM 2级事件
- 只有一个:监听方法,有两个方法用来添加和移除事件处理程序:addEventListener()和removeEventListener()。
DOM事件流
事件流描述了页面接受事件的顺序。
DOM2 Events 规范规定事件流分为3个阶段:事件捕获、到达目标和事件冒泡。
以简单的 HTML 为例,点击 < DIV > 元素会以下图所示的顺序触发事件。
-
事件捕获
事件捕获的意思是最不具体的节点应该最先收到事件,而最具体的节点应该最后收到事件。事件捕获实际上是为了再事件到达最终目标前拦截事件。
例如:
<div class="father" style="width: 200px;height: 200px;background-color: pink;">
<div class="son" style="width: 100px;height: 100px;background-color:skyblue">son盒子</div>
</div>
<script>
var son = document.querySelector('.son');
son.addEventListener('click', function () {
alert('son');
}, true);
</script>
在这个例子中,给son盒子注册事件处理程序。点击son盒子后按照document -> html ->body -> father -> son的顺序开始接收(点击)事件,并且因为只有 son 有事件处理程序,因此只有点了 son 后才有警告框。
-
事件冒泡
事件冒泡被定义为从最具体的元素(文档树中最深的节点)开始触发,然后向上传播到没那么具体的元素(文档)。
-
事件委托 (事件冒泡的典型应用)
"过多事件处理程序"的解决方案是使用事件委托。事件委托利用事件冒泡,可以只使用一个事件处理程序来管理一种类型的事件。
例如:
<ul id='myLink'>
<li id='xxh'>徐鑫瀚</li>
<li id='lkw'>蓝康伟</li>
<li id='xlj'>肖琳峻</li>
</ul>
这里的html包含3个列表项,如果需求是点击每个列表项都执行想要的操作,通常的做法是为每个列表项添加事件处理程序。
var xxh = document.querySelector('#xxh');
var lkw = document.querySelector('#lkw');
var xlj = document.querySelector('#xlj');
xxh.addEventListener('click', function () {
alert('xxh');
})
lkw.addEventListener('click', function () {
alert('lkw');
})
xlj.addEventListener('click', function () {
alert('xlj');
})
因为对页面所有需要使用 onclick 的事件处理程序的元素都如法炮制,结果会出现大量雷同的代码。
使用事件委托,只要给所有元素共同的祖先元素添加一个事件处理程序,就可以解决问题。
var myLink = document.querySelector("#myLink");
myLink.addEventListener('click', function (event) {
var target = event.target;
switch (target.id) {
case "xxh":
alert('xxh');
break;
case "lkw":
alert('lkw');
break;
case "xlj":
alert('xlj');
break;
}
})
DOM事件处理程序
事件意味着用户或浏览器执行的某种动作,如单击(click)、加载(load)、鼠标悬停(mouseover),为响应事件而调用的函数被称为事件处理程序(或事件监听器)。
-
DOM 0 事件处理程序 ( 传统处理方式 )
DOM 0 事件处理程序是把一个函数赋值给 (DOM元素的)一个事件处理程序的属性。
删除:通过将事件处理程序属性的值设置为 null ,可以移除通过 DOM0 方式添加的事件处理程序。 -
DOM 2 事件处理程序
DOM 2 为事件处理程序的赋值和移除定义了 addEventListener( )和 removeEventListener ( )方法。它们接收相同的3个参数:事件名、事件处理程序数和一个布尔值,true 表示在捕获阶段调用事件处理程序,false ( 默认值 )表示在冒泡阶段调用事件处理程序。
注: JS代码只能执行捕获或者冒泡其中一个阶段。
下面的例子展示注册事件和删除注册事件的方式:
var btns = document.querySelectorAll('button');
//传统注册事件
btns[0].onclick = function () {
alert(11);
//传统注册事件的删除
btns[0].onclick = null;
//执行完第一次弹出警告后,执行注册事件删除,之后再点击不回弹出警告
}
//方法监听注册事件
btns[1].addEventListener('click', fn);
function fn() {
alert(22);
btns[1].removeEventListener('click', fn);
}
DOM 事件对象
在DOM发生事件时,所有相关信息都会被收集并存储在一个名为 event 的对象中。这个对象包含了一些基本信息,如导致事件的元素、发生事件的类型等。
不同的事件生成的事件对象会包含不同的属性和方法。不过,有些属性和方法所有事件对象都会包含,如 target 、preventDefault ( ),stopPropagation( )等。
- preventDefault( ):用于阻止特定事件的默认动作。如:链接的默认动作就是在被单击时导航到 href 属性指定的 url 。如果想阻止这个行为,可以在 onclick 事件处理程序中取消。(通常的做法是:href = javascript:;)
var a = document.zquerySelector('a');
a.onclick = function (event) {
event.preventDefault();
}
- stopPropagation( ):阻止事件冒泡。
- 在事件处理程序内部,this 对象始终等于 currentTarget 的值,而 target 只包含事件的实际目标。