前言
- JS是前端三件套之一,也是核心,本人将会更新JS基础、JS对象、DOM、BOM、ES6等知识点,这篇是DOM;
- 这篇文章是本人大一学习前端的笔记;
- 欢迎点赞 + 收藏 + 关注,本人将会持续更新。
文章目录
DOM
DOM简介
1.1、什么是DOM
文档对象模型
1.2、DOM树
- 文档:一个页面就是一个文档,document
- 元素:页面中的所有标签都是元素,element
- 节点:网页中的所有内容都是节点,node
获取元素
2.1、获取页面中的元素
- 根据ID获取
- 根据标签名获取
- 通过HTML5新增的方法获取
- 特殊元素获取
2.2、根据ID获取
H5新加了通过类名获取
js
document.getElementById('id名')
<div id = "time"> 2019 </div>
var timer = document.getElementById('time'); //id是大小写铭感的字符串
console.log(timer);
console.log(typeof timer) //返回对象
//用console.dir 打印我们元素对象,更好查看里的属性和方法
console.dir(timer);
- 先有标签后有script,因为js是从上到下写
- 返回的是一个元素对象,万物皆对象
2.3、根据标签名获取
js
document.getElementByTagName('标签名');
- 得到的是一个对象的集合,所以想操作里面的元素就要遍历
- 返回的对象集合是以伪数组的新式储存
- 如果获取不到该元素,就返回空的伪数组
html
<ul>
<li>知否知否,应是绿肥红瘦</li>
<li>知否知否,应是绿肥红瘦</li>
<li>知否知否,应是绿肥红瘦</li>
<li>知否知否,应是绿肥红瘦</li>
</ul>
<script>
//1.获取元素
var lis = document.getElementByTagName('li');
//2.依次打印,遍历
for(var i = 0;i < lis.length;i++){
console.log(lis[i]);
}
</script>
2.4、根据标签名获取(某一个元素的父元素)
注意点:父元素必须是单个对象(必须指明是哪一个元素对象)。获取的时候不包括父元素自己
html
<script>
var ol = document.getElementById('ol'); //指明父元素
console.log(ol.getElementByTagName('li'));
</script>
2.5、通过H5新增方法获取
- document.getElementByClassName('类名')
- 根据类名返回元素对象集合
- document.querySelector('选择器')
- 根据指定选择器返回第一个元素对象
- document.querySelectorAll('选择器')
- 根据指定选择器返回所以元素对象,并且能够输出详细信息
2.6、获取特殊元素
- 获取body元素
- 返回body元素对象
- 获取HTML元素
- 返回html元素对象
js
//1.获取body元素
document.body;
//2.
document.documentElement;
事件基础
3.1、事件概述
简单理解:触发--响应机制
3.2、事件三要素
- 事件源(谁)
- 事件类型(什么事件)
- 事件处理程序(做啥)
html
<button>
唐伯虎
</button>
<script>
//1.获取元素 事件源
var btn = document.querySelector('button');
//2.注册事件 事件类型 事件处理程序
btn.onclick = function() {
alert('点秋香');
}
</script>
3.3、执行事件的步骤
- 获取事件源
- 注册事件(绑定事件)
- 添加事件处理程序(采用函数赋值新式)
3.4、鼠标事件
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获得鼠标焦点触发 |
onblur | 失去鼠标焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousedown | 鼠标按下触发 |
4、操作元素
js的DOM可以操作可以改变网页内容、结构和样式,我们可以利用DOM操作改变元素里面内容、属性等。
4.1、改变元素内容
js
//1.从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会换掉
element.innerText
//2. 起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行
element.innerHTML
4.2、改变元素属性
js
//img.属性
img.src = "xxx";
img.title = "xxx";
//表单属性,表单元素不同
input.value = "xxx";
input.type = "xxx";
input.checked = "xxx";
input.selected = true / false;
input.disabled = true / false;
4.3、改变样式属性
通过js修改元素的大小、颜色、位置等。
- 行内样式
- div.style.backgroundColor
- 类名样式操作
- element.className
注意:
- js里面的样式采取驼峰命名法,比如:fontSize
- js修改style样式操作,产生的是行内样式,css权重比较高
- 如果修改样式多,可以采取操作类名方式更改元素样式
- class因为是个保留字,因此使用className来操作元素类名属性
- className会直接更改元素的类名,会覆盖
html
<script>
//3.
this.className = 'change';
</script>
4.4、总结
4.5、排他思想
如果有同一组元素,我们想要某一个元素实现某一种样式,需要用到循环的排他思想
- 所有元素全部清空样式(干掉他人)
- 给当前元素设置样式(留下我自己)
- 注意顺序不能颠倒,首先干掉其他人,在设置自己
html
<body>
<button>
按钮1
</button>
<button>
按钮2
</button>
<button>
按钮3
</button>
<button>
按钮4
</button>
<script>
//1.获取元素
var btn = document.getElementsByTagName('button');
//执行元素
for(var i = 0;i < btn.length;i++){
btn[i].onclick = function() {
for(var i = 0; i < btn.length;i++) {
btn[i].style.backgroundColor = '';
}
this.style.backgroundColor = 'pink';
}
}
</script>
</body>
4.6、自定义属性
4.6.1、获取属性值
- 获取内置属性值(元素本身自带的属性)
- 获取自定义的属性
js
//1.
element.属性
//2.
element.getAttribute('属性')
4.6.2、设置属性值
- 设置内置属性值
- 主要设置自定义的属
js
//1.
element.属性 = '值';
//2.
element.setAttribute('属性','值');
4.6.3、移除属性
4.7、H5自定义属性
- 保存数据,有些数据可以保存到页面中而不用保存到数据库中
- 有些自定义属性很容易引起歧义,不容易判断到底是内置属性还是自定义的,所有H5有了规定
4.7.1、设置H5自定义属性
js
// 义data- 开头作为属性名并赋值
<div data-index = "1">
div.setAttribute('data-index',1);
4.7.2、获取H5自定义属性
-
兼容性获取 element.getAttribute('data-index')
-
H5新增的:element.dataset.index 或 element.dataset['index']
5、节点操作
1.利用DOM提供的方法获取元素 | 2.利用节点层级关系获取元素 |
---|---|
document.getElementById() | 利用父子兄弟节点关系获取元素 |
document.getElementByTagName() | 逻辑性强,但是兼容性较差 |
document.querySelector等 | |
逻辑不强 |
5.1、节点概述
-
节点基本三属性
- nodeType(节点类型)
- nodeName(节点名称)
- node Value(节点值)
-
元素节点:nodeType为1
-
属性节点:nodeType为2
-
文本节点:nodeType为3
5.2、父级节点
js
node.parentNode
//parentNode属性可以返回某节点的父节点,注意的是最近的一个父节点
//如果指定的节点没有父节点则返回null
5.3、子节点
js
parentNode.childNodes(标准)
parentNode.children(非标准)
- parentNode.children是一个只读属性,返回所有的子元素节点
- children是一个非标准,但是得到了各个浏览器的支持
js
console.log(ul.childNodes[0].nodeType);
//获取所有子元素
console.log(ul.children);
5.3.1、第一个/最后一个子节点
js
parentNode.firstChild
parentNode.lastChild
- 找不到则返回null
5.3.2、第一个/最后一个子节点(有兼容性)
js
parentNode.firstElementChild
parentNode.lastElementChild
- 找不到返回null
- IE9以上才支持
5.3.3、解决方案
- 如果想要第一个子元素节点,可以使用parentNode.children[0]
- 如果想要最后一个子元素节点,可以使用
5.4、兄弟节点
5.4.1、下一个兄弟节点
js
node.nextSibling
node.previousSibling
//有兼容性
node.nextElementSibling
node.previousElementSibing
5.5、创建节点
js
//1.创造节点
document.createElement('tagName');
//2.添加节点
node.appendChild(child);
node.insertBefore(child,指定元素);
5.5.1、删除节点
node.removeChild(child)
5.5.2、复制节点
node.cloneNode()
- 如果括号里面是空或者false,则是浅拷贝
- 如果括号里面是true,则是深拷贝
html
<script>
var ul = document.querySelector('ul');
//创造节点
var lili = ul.chilren[0].cloneNode(true);
//添加节点
ul.appendChild(lili);
</script>
5.5.3、面试题(重点)
三种动态创建元素的区别
- document.write( )
- element.innerHTML
- document.createElement( )
区别:
- docum.write( )是直接将内容写入页面的内容流,但是文档流执行完毕,则它会导致页面重绘
- innerHTML是将内容写入某个DOM节点,则不会导致页面重绘、
- innerHTML创建效率更高(不要拼接字符串,采取数组形势拼接),结构稍微复杂
- createElement()创建多个元素效率稍低一点点,但是结构更清晰
6、DOM核心
主要有:
- 创建、
- 增
- 删
- 改
- 查
- 属性操作
- 时间操作
6.1、创建
- document.write
- innerHTML\
- createElement
6.2、增
- appendChild
- insertBefore
6.3、删
- removeChild()
6.4、改
- 主要修改dom元素的属性,dom元素的内容、属性、表单的值等
- 修改元素的属性:src 、href、title等
- 修改普通元素内容:innerHTML、innerText
- 修改表单元素:value、type、disabled
- 修改元素样式:style、className
6.5、查
- 主要获取 查询dom的元素
- DOM提供的app方法:getElementById、getElementByTagName(古老方法)
- H5新增的方法:querySelector\querySelectorAll(提倡)
- 利用节点操作获取元素:父(parentNode)、子(children)、兄(previousElementSibling\nextElementSibling)提倡
6.6、属性操作
- 主要针对自定义属性
- setAttribute: 设置dom的属性值
- getAttribute: 得到dom的属性值
- removeAttribute: 移除属性
7、事件高级
7.1、注册事件(绑定事件)
给元素添加事件,称为注册事件 或者绑定事件
注册事件有两种方式:传统方式和方法监听注册方式
传统注册方式 | 方法监听注册方式 |
---|---|
利用on开头的事件onclick | w3c标准推荐方式 |
<button onclick = "alert("hi")"> | addEventListener()它是一个方法 |
btn.onclick = function() {} | IE9之前的IE不支持此方法 |
特点:注册事件的唯一性 | 特点:同一元素同意事件可以注册多个监听器 |
同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数 | 按注册顺序依次执行 |
addEventListener事件监听方式
- eventTarget.addEventListener()方法将指定的监听器注册到eventTargrt(目标对象)上
- 当该对象触发指定的事件时,就会执行事件处理函数
js
eventTarget.addEventListener(type,listener[,useCapture])
- type:事件类型字符串,比如click,mouseover,注意这里不要带on
- listener:事件处理函数,事件发生时,会调用该监听函数
- useCapture:可选参数,是一个布尔值,默认是false。
attachEvent事件监听方式(兼容)
- eventTarget.attachEvent()方法将指定的监听器注册到eventTarget(目标对象)上
- 当该对象触发指定的事件时,指定的回调函数就会执行
js
eventTarget.attachEvent(eventNameWithOn,callback)
- eventNameWithOn:事件类型字符串,比如:onclick,这里要带on
- callback:事件处理函数,当目标触发事件时回调函数被调用
7.2、删除事件(解绑事件)
7.2.1、removeEventListener删除事件方式
js
eventTarget.removeEventListener(type,listener[,useCapture]);
- 意义同addEventListener
7.2.2、datachEvent删除事件方式(兼容)
js
eventTarget.datachEvent(eventNameWithOh,callback);
- 同上
7.2.3、传统事件删除方式
eventTarget.onclick = null;
7.3、DOM事件流
- 事件流描述的是从页面中接收事件的顺序
- 事件发生时会在元素节点之间按照特定的顺序传播
- 事件冒泡:事件开始由最具体的元素接收,然后逐级向上传播到DOM最顶层节点的过程。
- 事件捕获:由DOM最顶层节点开始,然后逐级向下传播到最具体的元素接受的过程。
7.3.1、捕获过程
- document -> html -> body -> father -> son
- 先看 document 的事件,没有;再看 html 的事件,没有;再看 body 的事件,没有;再看 father 的事件,有就先执行;再看 son 的事件,再执行。
7.3.2、冒泡阶段
- son -> father ->body -> html -> document
7.3.3、小结
- js代码中只能执行捕获或者冒泡其中的一个阶段
- onclick和attachEvent只能得到冒泡阶段
- addEventLIster(type,listener[,useCapture])第三个参数如果是true,表示在事件捕获阶段调用事件处理程序;如果是false(不写默认就是false),表示在事件冒泡阶段调用事件处理程序
- 实际开发中跟关注事件冒泡
7.4、事件对象
html
<script>
eventTarget.onclick = function(event) {
// event 就是事件对象,还可以写出e / evt
}
eventTarget.addEventListener('click',function(event) {
// event 就是事件对象,还可以写出e / evt
})
</script>
7.4.1、事件对象的兼容性方案
e = e || window.event;
7.4.2、事件对象常见属性和方法
事件对象属性方法 | 说明 |
---|---|
e.target | 返回触发事件的对象 标准 |
e.srcElement | 返回触发事件的对象 非标准 |
e.type | 返回事件的类型(不带on) |
e.cancelBubble | 该属性阻止冒泡,非标准 |
e.returnValue | 该属性阻止默认行为 非标准 |
e.preventDefault() | 该方法阻止默认行为 标准 ,如:不让链接转跳 |
e.stopPropagation() | 阻止冒泡 标准 |
e.target 和 this的区别:
- this是事件绑定的元素
- e.target是事件触发的元素
7.6、阻止事件冒泡
事件冒泡:
js
//标准写法
e.stopPropagation();
//非标准 : IE6-8
e.cancelBubble = true;
7.7、事件委托
- 事件委托也称为事件代理
- 事件委托原理
- 不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后在利用冒泡原理影响设置的每个子节点
html
<ul>
<li>点我</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click',function(e) {
e.target.style.backgroundColor = 'pink';
})
</script>
7.8、常见的鼠标事件
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开触发 |
onfocus | 获得鼠标焦点触发 |
onblur | 失去鼠标焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousedown | 鼠标按下触发 |
7.8.1、禁止鼠标右键与鼠标选中
- contextmenu主要控制何时显示上下文菜单,主要用于程序员取消默认的上下文菜单
- selectstart禁止鼠标选中
html
<script>
document.addEventListener('selectstart',funcyion(e){
e.preventDefauly();
})
</script>
7.8.2、鼠标事件对象
- 现阶段常用
鼠标事件对象 | 说明 |
---|---|
e.clientX | 返回鼠标相对于浏览器窗口可视区的X坐标 |
e.clientY | 返回鼠标相对于浏览器窗口可视区的Y坐标 |
e.pageX(重点) | 返回鼠标相对于文档页面的X坐标 IE9+ 支持 |
e.page(重点) | 返回鼠标相对于文档页面的Y坐标 IE9+ 支持 |
e.screenX | 返回鼠标相对于电脑屏幕的X坐标 |
e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
7.9、常用键盘事件
键盘事件 | 触发条件 |
---|---|
onkeyup | 某个键盘按键被松开时触发 |
onkeydown | 某个键盘按键被按下时触发 |
onkeypress | 某个键盘按键被按下时触发,但是它不识别功能键,比如 ctrl shift 箭头等 |
- 顺序:onkeyup - onkeypress - onkeydown
7.9.1、键盘对象 属性
键盘事件对象 属性 | 说明 |
---|---|
keyCode | 返回该键值的ASCII值 |
onkeydown
和onkeyup
不区分字母大小写,onkeypress
区分字母大小写
html
<script>
document.addEventListener('keypress',function(e) {
console.log('press' + e.keyCode);
})
</script>