目录
前言
本文关于DOM和DOM事件,自己的一些认识。希望可以得到一些新的看法和认识。
一、文档对象模型
DOM 是针对HTML和xml文档的一个API,描绘了一个层次化的节点树。它将任何HTML或XML文档描绘成一个由多层节点构成的结构。
NODE 最高一层节点,js中所有的节点类型都继承自node类型。
1.节点关系
document 是Document构造函数的实例
document.body是Element构造函数的实例
document.body.firstChild 是Comment构造函数的实例
属性 :其中有些常用,有些不常用。
nodeType 表示节点类型
Document-->1
Element--9
TextNode-->3
Comment--8
nodeName 取决于节点类型,如果是元素类型,值为元素的标签名
nodeValue 取决于节点类型,如果是元素类型,值有null
parentNode 指向文档树中的父节点。
previousSibling 兄弟节点中的前一个节点
nextSibling 兄弟节点中的下一个节点
firstChild childNodes列表中的第一个节点
lastChild childNodes列表中的最后一个节点
ownerDocument 指向表示整个文档的文档节点,任何节点都属于它所在的文档,任何节点都不能同时存在于两个或更多个文档中。
childNodes 保存一个NodeList对象(一种类数组对象用来保存一组有序的节点),是一个类数组,但不是数组,可以使用slice方法转换为数组,有属性length。
将类数组转换为数组:var newArr = Array.prototype.slice.call(dom.childNodes,0);
<script>
// window.onload就是页面加载完毕之后
window.onload = function() {
var dom = document.getElementById('first')
console.log(dom.childNodes);
// 类数组对象转数组
// 1、方法一
var newArr = Array.prototype.slice.call(dom.childNodes,0);
// 2、方法二 es6的数组API
//var newArr = Array.from(dom.childNodes)
console.log(newArr);
//遍历
var elements = newArr.filter(function(item) {
return item.nodeType == 3
})
console.log(elements);
}
</script>
<body>
hello text
<div class="box" id="first">
<p>hello Dom</p>
<span>行内元素</span>
<a href="">111</a>
html
<!-- 注释 -->
</div>
<!-- 注释信息 -->
</body>
可以将类数组转为数组。
2,Document类型
Document类型,是HTMLDocument的一个实例,表示整个HTML页面。document对象是window对象的一个属性,因此可以直接调用。
文档子节点 可以继承Node中所有的属性和方法。其中的有些我们用的很少。
documentElement 始终指向HTML页面中的<html>元素。
body 直接指向<body>元素
doctype 访问<!DOCTYPE>, 浏览器支持不一致,很少使用
title 获取文档的标题
URL 取得完整的URL
domain 取得域名,并且可以进行设置,在跨域访问中经常会用到。
referrer 取得链接到当前页面的那个页面的URL,即来源页面的URL
images 获取所有的img对象,返回HTMLCollection类数组对象
forms 获取所有的form对象,返回HTMLCollection类数组对象
links 获取文档中所有带href属性的<a>元素,如果a标签中没有带href属性,则不会被获取到
举个例子:
<script>
window.onload = function() {
//获取当前文件服务器所在地的域名
console.log(document.domain);
//获取跳转过来的页面的路径
// console.log(document.referrer);
//获取文档中所有img标签
console.log(document.images);
//获取文档中所有a标签,a标签中只有一个有href值,只,能获取到一个
console.log(document.links);
}
</script>
<body>
<img src="" alt="">
<img src="" alt="">
<a href=""></a>
<a></a>
</body>
links 获取文档中所有带href属性的<a>元素,代码中有一个没有href属性,所有结果中只取到一个元素。
查找元素
getElementById() 取得元素的ID值,id值是唯一标识,getElementById()没有加s
getElementsByTagName() 取得元素的标签名,可以返回一个或多个元素的NodeList
getElementsByName() 参数为元素的name值,返回符合条件的HTMLCollection
getElementsByClassName() 取得元素的class值。参数为一个字符串,可以由多个空格隔开的标识符组成。
在下面的例子中展示用法。
3,Element类型
所有的HTML元素都由HTMLElement类型表示,或者其子类型表示。每个元素都有一个或多个特性,可以通过属性访问到该属性对应的值,特性的名称是不区分大小写的。根据HTML5规范,自定义特性应该加上data-前缀,以便验证。
自定义属性 getAttribute()方法
这个方法的参数为实际元素的属性名,class,name,id,title,lang,dir一般只有在取得自定义
特性值的情况下,才会用该方法大多数直接使用属性进行访问,比如style,onclick。
<script>
function test(){
alert('点击函数')
}
window.onload = function() {
var dom = document.getElementById('first');
// 获取元素的某个属性
// .访问只能获取到dom节点的自有属性
// getAttribute()不仅能够获取dom的自有属性,还能获取它的自定义属性
console.log(dom.className);
console.log(dom.getAttribute('title'));
console.log(dom['data-test']);
console.log(dom.getAttribute('data-test'));
// 设置dom节点的某个属性
dom.className = 'newBox';
//修改了title的值 将hezi改为hello
dom.setAttribute('title','hello');
console.log(dom.getAttribute('title'));
//修改了自定义属性data-test的值
dom.setAttribute('data-test','editTest');
console.log(dom.getAttribute('data-test'));
// 删除某个属性
// dom.removeAttribute('id');
// 获取dom节点中特殊属性style/onclick
var inner = dom.children[0];
console.log(inner.onclick);
console.log(inner.getAttribute('onclick'));
}
</script>
<body>
<div class="box" id="first" title="hezi" data-test="test">
<div class="inner" onclick="test()">one</div>
<div class="inner"></div>
<div class="inner"></div>
</div>
</body>
4,Text类型和Comment类型
Text类型 文本节点,包含的是可以按照字面解释的存文本内容。
Comment类型 注释类型。
这两种类型一般用的少。
5,操作节点
appendChild() 向childNodes列表末尾添加一个节点。
insertBefore() 也是添加语句,想在哪儿插在哪儿插 (要插入的节点,作为参照的节点)
replaceChild() 也是输入两个参数,(要插入的节点,要替换的节点)
removeChild() 要移除的节点,移除的节点将作为方法的返回值。
cloneNode() 克隆节点,参数传递true表示深克隆,克隆节点内部的信息,不加参数或者参数为flase表示浅克隆,只克隆当前节点。克隆节点不会克隆节点的js属性,比如说点击事件之类的。
<script>
window.onload = function() {
//获取被操作的dom节点,如果在代码中class的值有多个相同的,可以在后面加[]来表示选择哪一个
var dom1 = document.getElementsByClassName('box')[0];
//创建新的dom节点
var newDom = document.createElement('p');
//可以自己新增内容,给新增dom节点添加内容
//用反引号添加HTML代码段,可以回车,正引号不能随便回车
newDom.innerHTML = `
<div class="inner">
新增
</div>
`
//将新加的dom节点追加到dom1后
dom1.appendChild(newDom);
//console.log(dom1);
var domInsert = dom1.children[1]; // 获取插入节点的参考位置
//克隆节点 参数传递true表示深克隆,不加参数或者参数为flase表示浅克隆
var domClone = dom1.children[1].cloneNode(true);
//克隆原有的内容添加
dom1.appendChild(domClone);
// 将新生成的dom节点插入到dom树中指定的位置
// dom1.insertBefore(newDom,domInsert);
// 替换某个dom节点,需要输入两个属性
// dom1.replaceChild(newDom,domInsert);
// 删除某个dom节点
// dom1.removeChild(domInsert);
}
</script>
<body>
<div class="box">
<div class="inner">one</div>
<div class="inner">two</div>
<div class="inner">three</div>
</div>
</body>
具体看一下注释吧。
二、DOM事件
JavaScript与HTML之间的交互是通过事件实现的。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。
事件绑定的基本方法
<script>
function myfun(){
alert('点击');
}
</script>
<div class="parent" id="parent" onclick="myfun()">
123
</div>
事件有三要素:
事件目标:与事件相关的对象
事件处理程序:处理事件的函数
事件对象:与特定事件相关且包含有关这个事件信息的对象
事件流
事件冒泡(从内往外,元素之间嵌套关系,绑定一个事件)
<script>
window.onload = function(){
//1 获取需要绑定事件的dom节点
var parent = document.getElementById('parent');
//2 给dom节点绑定事件
parent.onclick = function() {
//this指向执行函数的节点
console.log('this', this);
console.log('目标源元素', event.target);
console.log('当前触发事件元素', event.currentTarget);
console.log('-------------------');
}
}
</script>
点击事件在class="parent"上绑定,也就是在粉丝的区域绑定。点击粉色的区域,事件肯定会执行。第一次点击了第一个灰色小块<div class="child">,他也会执行点击事件。结果中,目标源元素就是我们点击的位置,点击的元素不同,触发事件元素相同,都是粉色的区域。
如果父元素和子元素中都绑定事件,我们只想执行子元素中的事件,可以运用event.stopPropagation();语句来阻止事件冒泡。
<script>
window.onload = function(){
//1 获取绑定事件的dom节点
var outer = document.getElementById('outer');
var inner = document.getElementById('inner');
//2 绑定点击事件
outer.onclick = function(event){
console.log(2);
}
inner.onclick = function(event){
//阻止事件冒泡
event.stopPropagation();
console.log(1);
}
}
</script>
<body>
<div id="outer">
outer
<div id="inner">
inner
</div>
</div>
</body>
不加这条语句,蓝色和灰色区域的点击事件都会执行,加入这条语句,如果点击蓝色区域,只会执行蓝色区域的绑定事件,灰色区域的事件不会执行。
事件捕获(由最外层向里层执行)
DOM事件流
事件捕获
处理目标(执行自己)
事件冒泡
事件绑定机制(三种事件绑定机制)
1 HTML事件处理程序绑定
2 DOM0级事件绑定
绑定目标元素定位准确
重新绑定事件时,之前的绑定事件被覆盖
事件解绑
dom.onclick = null;
3 DOM2级事件绑定
优点:在不影响之前绑定的事件基础上,继续绑定事件
<script>
window.onload = function(){
//1 获取绑定事件dom节点
var dom = document.getElementsByTagName('div')[0];
//2 绑定DOM0事件
dom.onclick = function(){
console.log(1);
}
//3 dom2级的事件绑定
var myfun = function (){
console.log(2);
}
var myfun1 = function (){
console.log(3);
}
//addEventListener添加一个事件监听器,在不影响之前绑定事件的基础上,继续绑定其他事件
//IE8级以下不支持
dom.addEventListener('click',myfun);
dom.addEventListener('click',myfun1);
//解绑事件
//DOM2级事件解绑只能解绑具名函数,匿名函数无法解绑
// dom.removeEventListener('click',myfun1);
}
</script>
<body>
<div class="box">
点击
</div>
</body>
DOM2级事件绑定可以在不影响之前绑定事件的基础上,继续绑定其他事件,在一个节点上绑定两个事件用完后也可以将事件解绑,但IE8及以下浏览器不支持。
事件对象
event.target 事件处理程序触发的源元素
event.currentTarget 事件处理程序执行的元素
event.stopProgation() 阻止事件冒泡
event.preventDefault() 阻止事件的默认行为
事件代理(底层逻辑:事件冒泡)
父元素代替子元素执行事件。
事件类型
UI事件
load :当页面完全加载后在window上触发
unload:当页面完全卸载后在window上触发
select:当用户选择文本框(<input>,<textarea>)中的一个或多个字符时
change:在select的下拉列表的选中的选项更改的时候触发。
等。有些事件我们也不常用。
焦点事件 blur(失去焦点时触发) focus(获得焦点时,不支持冒泡)
鼠标与滚轮事件 单击click或双击dbclick,还有滚轮的操作
键盘与文本事件 按下键盘和松开键盘,还有长按等
一般正常的操作好像就这些。
总结
DOM是针对XML和HTML文档的一个API,描绘了一个层次化的节点树。DOM事件就是文档或浏览器窗口中发生的一些特定的交互瞬间,在这些节点中进行JavaScript与HTML之间的交互。