DOM
一、简介
文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标记语言的标准编程接口。
- 文档:一个网页就是一个文档,DOM中使用document表示;
- 元素:页面中的所有标签都是元素,DOM中使用element表示;
- 节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示;
二、获取页面中的元素
因为文档页面从上往下加载,所以先得有标签,所以我们script写到标签的下面。
console.dir()打印我们返回的元素对象,更好的查看里面的属性和方法。
1.根据ID获取
格式:document.getElementById(‘ID’)
注:返回的是一个元素对象。
var timer = document.getElementById('time');
console.log(timer);
console.log(typeof timer);
2.根据标签名获取
(1)document.getElementsByTagName(‘标签名’)
- 返回的是获取过来元素对象的集合,以伪数组的形式存储;
- 想要依次打印里面的元素对象我们可以采取遍历的方式;
(2)element.getElementsByTagName(‘标签名’)
<body>
<ul>
<li>1</li>
<li>1</li>
</ul>
<ol>
<li>2</li>
<li>2</li>
</ol>
<script>
var ulli = document.getElementsByTagName('li');
console.log(typeof ulli);
console.log(ulli);
console.log(ulli[0]);
var ol = document.getElementsByTagName('ol');
var olli = ol[0].getElementsByTagName('li');
console.log(typeof olli);
console.log(olli);
console.log(olli[0]);
</script>
</body>
3.通过HTML5新增方式获取
(1)getElementByClassName
根据类名获得某些元素集合;
(2)querySelector
返回指定选择器的第一个元素对象;
(3)querySelectorAll
返回指定选择器的所有元素对象集合;
<body>
<div class = 'box'>1</div>
<div class = 'box'>2</div>
<div id = 'box'>3</div>
<ul id = 'a'>
<li>1</li>
<li>2</li>
</ul>
<script>
var boxs = document.getElementsByClassName('box');
console.log(typeof boxs);
console.log(boxs);
var firstBox = document.querySelector('.box');
console.log(firstBox);
var a = document.querySelector('#box');
console.log(a);
var b = document.querySelector('li');
console.log(typeof b);
console.log(b);
var allBox = document.querySelectorAll('.box');
console.log(typeof allBox);
console.log(allBox);
var allLi = document.querySelectorAll('li');
console.log(typeof allLi);
console.log(allLi);
</script>
</body>
4.特殊元素的获取
(1)获取body元素
var bodyEle = document.body;
console.log(bodyEle);
console.dir(bidyEle);
(2)获取html元素
var htmlEle = document.documentElement;
console.log(htmlEle);
三、执行事件的步骤
事件是由三部分组成(事件三要素):事件源 事件类型 事件处理程序
事件源:事件被触发的对象
事件类型:如何触发?什么事件 如鼠标点击(onclick)
事件处理程序:通过函数赋值的方式完成
1.获取事件源
2.注册事件(绑定事件)
常见的鼠标事件:
鼠标事件 | 触发条件 |
---|
onclick | 鼠标点击左键触发 | onmouseover | 鼠标经过触发 | onmouseout | 鼠标离开触发 | onfocus | 获得鼠标焦点触发 | onblur | 失去鼠标焦点触发 | onmousemove | 鼠标移动触发 | onmouseup | 鼠标弹起触发 | onmousedown | 鼠标按下触发 |
3.添加事件处理程序(采取函数赋值形式)
四、操作页面中的元素
1.操作元素内容
element.innerText
从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去掉。
element.innerHTML
起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行。
<body>
<div></div>
<p>
我是文字
<span>123</span>
</p>
<script>
var div = document.querySelector('div');
div.innerHTML = '<strong>今天是:</strong>2019 ';
var p = document.querySelector('p');
console.log(p.innerText);
console.log(p.innerHTML);
</script>
</body>
2.操作元素样式属性
通过js修改元素的大小、颜色、位置等样式。
element.style (行内样式操作)
element.className (类名样式操作)
注:
- 如果样式修改较多,可以采取操作类名方式更改元素样式;
- class因为是个保留字,因此使用className来操作元素类名属性;
- className会直接更改元素的类名,会覆盖原先的类名;
<html lang="en">
<head>
<style>
div {
background-color: pink;
width: 100px;
height: 100px;
}
.change {
color:aliceblue;
background-color: pink;
width: 10px;
height: 10px;
}
</style>
</head>
<body>
<div class='one'></div>
<script>
var div = document.querySelector('div');
div.onclick = function() {
this.style.backgroundColor = 'blue';
this.style.width = '200px';
}
</script>
</body>
</html>
3.操作常见元素属性
src、href、title、alt等
4.操作元素表单属性
type、value、disabled等
5.操作自定义属性
1.H5自定义属性
自定义属性目的:为了保存使用数据,有些数据可以保存在页面中而不用保存到数据库中;
- 自定义属性获取是通过getAttribute(‘属性’)获取;
- H5规定自定义属性data-开头做为属性名并赋值;
- 如< div data-index=‘1’>< /div>或者使用js设置:element.setAttribute(‘data-index’,2)
2.获取属性值
element.属性
element.getAttribute(‘属性’);
区别:
- element.属性 获取内置属性值(元素本身自带的属性)
- element.getAttribute(‘属性’);主要获取自定义的属性(标准)
3.设置属性值
element.属性 = ‘值’
element.setAttribute(‘属性’, ‘值’);
区别:
- element.属性 设置内置属性值
- element.setAttribute(‘属性’); 主要设置自定义的属性(标准)
<body>
<div id="demo" data-index='1' data-list-name="111"></div>
<script>
var div = document.querySelector('div');
console.log(div.id);
console.log(div.getAttribute('id'));
console.log(div.getAttribute('data-index'));
console.log('===============');
div.id = 'test';
console.log(div.id);
div.className = 'navs';
console.log(div.className);
div.setAttribute('data-index',2);
console.log(div.getAttribute('data-index'));
div.setAttribute('class', 'footer');
console.log(div.getAttribute('class'));
div.removeAttribute('data-index');
console.log(div.dataset.listName);
console.log(div.dataset['listName']);
</script>
</body>
五、节点操作
为什么学节点操作:为了获取元素节点,相比DOM提供的方法获取元素,节点操作更简单。
1.节点概述
网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM中,节点使用node来表示。
HTML DOM数中的所有节点均可通过Js进行访问,所有HTML元素(节点)均可被修改,也可以创建或删除。
2.父级节点
node.parentNode
- parentNode属性可返回某节点的父节点,注意是最近的一个父节点
- 如果指定的节点没有父节点则返回null
<body>
<ul class="box">
<li></li>
<li></li>
<li></li>
</ul>
<div class="demo">
<span class="erweima">*</span>
</div>
<script>
var erweima = document.querySelector('.erweima');
var box = document.querySelector('.box');
console.log(erweima.parentNode);
console.log(box.parentNode);
</script>
</body>
3.子级节点
parentNode.childNodes (标准)
parentNode.childNodes返回包含指点节点的子节点的集合,该集合为即使更新的集合。
返回值里面包含了所有的子节点,包括元素节点,文本节点等。
parentNode.children (非标准)
parentNode.children是一个只读属性,返回所有的子元素节点。它只返回子元素节点,其余节点不返回(重点掌握)
<body>
<ul class="one">
<li></li>
<li></li>
<ul class="two">
<li></li>
<li></li>
</ul>
</ul>
<script>
var ul = document.querySelector('.one');
var lis = ul.querySelectorAll('li');
console.log(ul.childNodes);
console.log(ul.childNodes[0].nodeType);
console.log(ul.childNodes[1].nodeType);
console.log(ul.childNodes[2].nodeType);
console.log(ul.children);
</script>
</body>
parentNode.firstChild
parentNode.firstChild 返回第一个子节点(注意是子节点不是子元素节点),找不到则放回null
parentNode.lastChild
parentNode.lastChild 返回最后一个子节点(注意是子节点不是子元素节点),找不到则放回null
parentNode.firstElementChild
parentNode.firstElementChild 返回第一个子元素节点,找不到返回null
parentNode.lastElementChild
parentNode.firstElementChild 返回最后一个子元素节点,找不到返回null
<body>
<ol>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ol>
<script>
var ol = document.querySelector('ol');
console.log(ol.firstChild);
console.log(ol.lastChild);
console.log(ol.firstElementChild);
console.log(ol.lastElementChild);
console.log(ol.children[0]);
console.log(ol.children[ol.children.length - 1]);
</script>
</body>
4.兄弟节点
node.nextSibling
node.nextSibling 返回当前元素的下一个兄弟节点,找不到返回null,包含所有节点
node.previousSibling
node.previousSibling 返回当前元素的上一个兄弟节点,找不到返回null,包含所有节点
node.nextElementSibling
node.nextElementSibling 返回当前元素下一个兄弟元素节点,找不到返回null
node.previousElementSibling
node.previousElementSibling 返回当前元素上一个兄弟元素节点,找不到返回null
<body>
<div>我是div</div>
<span>我是span</span>
<script>
var div = document.querySelector('div');
console.log(div.nextSibling);
console.log(div.previousSibling);
console.log(div.nextElementSibling);
console.log(div.previousElementSibling);
</script>
</body>
5.创建节点
document.createElement(‘tagName’)
document.createElement(‘tagName’) 方法创建由tagName指定的HTML元素。因为这些元素原先不存在,是根据我们的需求动态生成的,所有我们也称为 动态创建元素节点。
6.添加节点
node.appendChild(child)
node.appendChild() 方法将一个子节点添加到指定父节点的子节点列表末尾。
node.insertBefore(child, 指定元素)
node.insertBefore(child, 指定元素) 方法将一个子节点添加到指定元素的前面。
<body>
<ul>
<li>123</li>
</ul>
<script>
var li = document.createElement('li');
var ul = document.querySelector('ul');
ul.appendChild(li);
var lili = document.createElement('li');
ul.insertBefore(lili, ul.children[0]);
</script>
</body>
7.删除节点
node.removeChild(child)
node.removeChild() 方法从DOM中删除一个子节点,返回删除的节点。
<body>
<button></button>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var ul = document.querySelector('ul');
var btn = document.querySelector('button');
btn.onclick = function(){
if(ul.children.length == 0){
this.disabled = true;
} else{
ul.removeChild(ul.children[0]);
}
}
</script>
</body>
8.复制节点
node.cloneNode()
node.cloneNode() 方法返回调用该方法的节点的一个副本,也称为克隆节点/拷贝节点
- 如果括号参数为空或false,则为浅拷贝,即只克隆复制节点本身,不克隆里面的子节点(如文本节点);
- 如果括号参数为true,则是深拷贝,会复制节点本身以及里面所有的子节点;
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var ul = document.querySelector('ul');
var lili = ul.children[0].cloneNode(true);
ul.appendChild(lili);
</script>
</body>
六、注册事件(绑定事件)
1.传统注册事件方式
- 利用on开头的事件onclick
- btn.onclick = function(){}
- 特点:注册事件的唯一性
- 同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数;
2.方法监听注册事件
- W3C 标准 推荐方式
- addEventListener()是一个方法
- IE9之前不支持此方法,可使用attachEvent()代替
- 特点:同一个元素同一个事件可以注册多个监听器
- 按注册顺序依次执行
eventTarget.addEventListener()
eventTarget.addEventListener(type,listener,[useCapture]) 方法将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,就会执行事件处理函数。
- type:事件类型字符串,比如click、mouseover等,注意这里不要带on
- listener:事件处理函数,事件发生时,会调用该监听函数
- useCapture:可选参数,是一个布尔值,默认flase。是否冒泡
<body>
<button>传统注册事件</button>
<button>方法监听注册事件</button>
<script>
var btns = document.querySelectorAll('button');
btns[0].onclick = function(){
alert('hi');
}
btns[0].onclick = function(){
alert('hi hi');
}
btns[1].addEventListener('click',function(){
alert(22);
})
btns[1].addEventListener('click',function(){
alert(33);
})
</script>
</body>
attachEvent()
eventTarget.attachEvent(eventNameWithon, callback) 方法将指定的监听器注册到eventTarget(目标对象)上,当对象触发指定的事件时,就会执行事件处理函数。
- eventNameWithon:事件类型字符串,比如onclick、onmouseover等,这里要带on
- callback:事件处理函数
七、删除事件(解绑事件)
1.传统删除事件
eventTarget.onclick = null;
2.方法监听删除事件
eventTarget.removeEventListener(type, listener, [useCapture]);
eventTarget.detachEvent(eventNameWithon, callback);
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<script>
var divs = document.querySelectorAll('div');
divs[0].onclick = function(){
alert(11);
divs[0].onclick = null;
}
divs[1].addEventListener('click',fn);
function fn(){
alert(22);
divs[1].removeEventListener('click',fn);
}
</script>
</body>
八、DOM事件流
事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。
DOM事件流分为3个阶段:
1.捕获阶段
2.当前阶段
3.冒泡阶段
注:
- js代码只能执行捕获或者冒泡其中的一个阶段。
- onclick和attachEvent只能得到冒泡阶段。
- eventTarget.addEventListener(type,listener,[useCapture]) 第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false,表示在事件冒泡阶段调用事件处理程序。
- 实际开发中很少使用事件捕获,更多关注事件冒泡。
- 有些事件没有冒泡,如onblur、onfocus、onmouseenter、onmouseleave。
- 事件冒泡有时会带来麻烦,有时候又会帮助很巧妙的做某些事件。
九、事件对象
eventTarget.onclik = function(event) {}
官方解释:event对象代表事件的状态,比如键盘按键的状态、鼠标的位置、鼠标按钮的状态。
简单解释:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象event,它有很多属性和方法。
<body>
<div></div>
<script>
var div = document.querySelector('div');
div.addEventListener('click',function(e){
console.log(e);
})
</script>
</body>
事件对象的常见属性和方法
事件对象属性方法 | 说明 |
---|
e.target | 返回触发事件的对象 标准 | e.srcElement | 返回触发事件的对象 非标准 ie6-8使用 | e.type | 返回事件类型 比如click 不带on | e.cancelBubble | 该属性阻止冒泡 非标准 ie6-8使用 | e.returnValue | 该属性阻止默认事件(默认行为)非标准 ie6-8使用 | e.preventDefaule() | 该属性阻止默认事件(默认行为)标准 比如不让链接跳转 | e.stopPropagation() | 阻止冒泡 标准 |
e.target
e.target 返回的是触发事件的对象(元素) this 返回的是绑定事件的对象(元素)
e.preventDefault()
<script>
var a = document.querySelector('a');
a.addEventListener('click',function(e){
e.preventDefault();
})
a.onclick = function(e){
return false;
}
</script>
e.stopPropagation()
<script>
var son = document.querySelector('.son');
son.addEventListener('click',function(e){
alert('son');
e.stopPropagation();
e.cancelBubble = true;
},false)
var father = document.querySelector('.father');
father.addEventListener('click',function(e){
alert(12);
},false)
document.addEventListener('click',function(e){
alert(12);
},false)
</script>
十、事件委托(代理、委派)
原理:不是每个子节点都单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。
案例:给ul注册点击事件,然后利用事件对象的target来找到当前点击的li,因为点击li,事件会冒泡到ul上,ul有注册事件,就会触发事件监听器。
作用:只操作了一次DOM,提高看程序的性能。
十一、常用鼠标事件及鼠标事件对象
1.常用鼠标事件
禁止鼠标右键菜单(contextmenu)
禁用鼠标选中(selectstart)
<body>
<script>
document.addEventListener('contextmenu',function(e){
e.preventDefault();
})
document.addEventListener('selectstart',function(e){
e.preventDefault();
})
</script>
</body>
2.鼠标事件对象
鼠标事件对象 | 说明 |
---|
e.clientX | 返回鼠标相对于浏览器窗口可视区的X坐标 | e.clientY | 返回鼠标相对于浏览器窗口可视区的Y坐标 | e.pageX | 返回鼠标相对于文档页面的X坐标 IE9+支持 | e.pageY | 返回鼠标相对于文档页面的Y坐标 IE9+支持 | e.screenX | 返回鼠标相对于电脑屏幕的X坐标 | e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
十二、常用键盘事件及键盘事件对象
1.常用键盘事件
键盘事件 | 触发条件 |
---|
onkeyup | 某个键盘按键被松开时触发 | onkeydown | 某个键盘按键被按下时触发 | onkeypress | 某个键盘按键被按下时触发 (不能识别功能键 比如:ctrl shift 箭头等) |
- 如果使用addEventListener不需要加on
- onkeypress和前面两个的区别时,它不识别功能键
- 三个事件的执行顺序:keydown -> keypress -> keyup
2.键盘事件对象
keyCode:返回该键的ASCII值
注:
- onkeydown和onkeyup不区分字母大小写,onkeypress区分字母大小写。
- 实际开发中,我们更多的使用keydown和keyup,它能识别所有的键(包括功能键)
- keypress不识别功能键,但是keyCode属性能区分大小写,返回不同的ASCII值
|