目录
一、什么是Web API
APl:应用程序编程接口,是一些预先定义函数,目的是实现某些功能,并且无需知晓其内部的实现细节。
简单的来说,想要用好API,只需要了解这个API接口是对什么东西干什么的事情以及返回什么就可以
WebAPI是浏览器提供的一套用于操作网页的接口,可以让用户非常轻易地操作页面的元素以及浏览器的一些功能。
Web APIs = DOM文档对象模型(改变网页的内容、结构和样式) + BOM浏览器对象模型(独立于内容与浏览器窗口进行交互)
这里主要介绍DOM文档对象模型
二、DOM
DOM树:将HTML文档以树状结构直观的表现出来,称之为文档树或者DOM树。文档树直观的体现了标签与标签之间的关系。
DOM对象
DOM对象:浏览器根据html标签生成的 JS对象,将DOM树中内容全部看成对象。
文档 :一个页面就是一个文档,DOM中使用doucument来表示
元素 :页面中的所有标签都是元素,DOM中使用 element 表示
节点 :网页中的所有内容都是节点(标签,属性,文本,注释等),DOM中使用 node表示
特点
1、所有的标签属性都可以在这个对象上面找到
2、修改这个对象的属性会自动映射到标签身上
三、DOM元素获取
获取方式 | 语法 | 参数 | 返回 |
---|---|---|---|
根据id获取 | doucument.getElementByld() | id名 | 元素对象 |
根据标签名获取 | doucument.getElementsByTagName() | 标签名 | 元素对象的集合,以伪数组的形式存储,若不存在,返回一个长度为0的伪数组 |
HTML5 新增的方法获取 | ①document.getElementsByClassName() ② document.querySelector() ③document.querySelectorAll() | ①类名 ② css选择器 ③ css选择器 | ①元素对象的集合,以伪数组的形式存储 ② CSS选择器匹配的第一个元素,一个HTMLElement对象,如果没有匹配到,则返回null ③CSS选择器匹配的NodeList对象集合,是一个伪数组 |
获取特殊元素:
获取body对象:document.body;
获取html元素:document.documentElement;
四、操作元素
4.1、修改元素内容
document.write()
1、只能将文本内容追加到前面的位置(创建)
2、文本包含的标签会被解析
元素的innerText属性
1、将文本内容添加或者更新到任意标签的位置
2、文本包含的标签不会被解析,不保留空格和换行
元素的innerHTML属性
1、将文本内容添加/更新到任意标签位置
2、文本包含的标签会被解析,并保留空格和换行
代码示例:
<body>
<P>段落一</P>
<p id="pp">段落二</p>
<script>
document.write('好好学习,天天向上');
// 里面的标签会被解析
document.write('<h2>学习令人兴奋</h2>');
var one=document.querySelector('p')
one.onclick=function(){
one.innerText='<h1>段落 三</h1>'
}
var two=document.getElementById('pp')
two.onclick=function(){
two.innerHTML='<h1>段落 三</h1>'
}
</script>
</body>
效果:
4.2、设置/修改元素属性
小案例:显示/隐藏 密码 的输入
效果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>demo</title>
<style>
.box {
position: relative;
width: 200px;
border-bottom: 1px solid #ccc;
margin: 100px auto;
}
.box input {
width: 370px;
height: 30px;
border: 0;
outline: none;
}
.box img {
position: absolute;
top: 10px;
right: 30px;
width: 24px;
}
</style>
</head>
<div class="box">
<label for=""><img src="图片地址" id="eye"> </label>
<input type="password" name="" id="pwd">
</div>
<script>
var eye = document.getElementById('eye');
var pwd = document.getElementById('pwd');
var flag = 0;
eye.onclick = function () {
if (flag == 0) {
pwd.type = 'text';
eye.src = '';
flag = 1;
} else {
pwd.type = 'password';
eye.src = '';
flag = 0;
}
}
</script>
</body>
</html>
各标签元素的属性可以通过 “ . ” 的方式访问得到
4.3、设置/修改样式属性
我们可以通过 JS 修改元素的大小、颜色、位置等样式。
方法 | 例子 |
通过style属性 | div.style.backgroundColor = 'pink'; div.style.width = '250px'; |
通过类名className | .change{ width:30px; height:30px; } //保留原类名 |
通过classList | //为了解决className 容易覆盖以前的类名,我们可以通过classList方式追加和删除类名 element.classList.add('类名') //追加 |
小案例:实现输入框文本提示功能
<input type="text" value="请输入账号" style="width: 200px; height:30px; outline: none; color: rgb(201, 189, 189);;">
<script>
var inp = document.querySelector('input');
inp.onfocus = function () {
if (this.value == '请输入账号') {
this.value = '';
this.style.color = 'black'
}
}
inp.onblur = function () {
if (this.value == '') {
this.value = '请输入账号'
this.style.color = 'rgb(201, 189, 189)'
}
}
</script>
排他思想
如果有一组样式,我们想要某一个元素实现某种样式,需要用到循环的排他思想算法:
1.所有的元素全部清除样式(干掉其他人)
2.给当前元素设置样式(留下我自己)
3.注意顺序不能颠倒,先干掉其他人,再留下我自己
</head>
<button>11</button>
<button>22</button>
<button>33</button>
<script>
//1.获取所有的元素
var btns = document.getElementsByTagName('button');
//btns得到的是伪数组,里面的每一个元素btn[i]
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function () {
//1.我们先把所有按钮的背景颜色去掉,干掉其他人
for (var i = 0; i < btns.length; i++) {
btns[i].style.backgroundColor = '';
}
//2.然后才让当前元素的颜为pink留下我自己
this.style.backgroundColor = 'pink';
}
}
</script>
</body>
</html>
4.4、自定义属性
目的:保存并保存数据,有些数据可以保存到页面中而不用保存到数据库中
有些自定义属性很容易引起歧义,不容易判断到底是内置属性还是自定义的,所以H5有了规定自定义属性以 data-
开头
获取属性值
获取内置属性值(元素本身自带的属性):element.属性;
获取自定义的属性:element.getAttribute('属性');
设置属性值
设置内置属性值:element.属性 = '值';
主要设置自定义的属性:element.setAttribute('属性','值');
五、节点node
网页中的所有内容都是节点node(标签、属性、文本、注释等),利用 DOM 树可以把节点划分为不同的层级关系,常见的是父、子、兄、层级关系。 在实际开发中,节点操作主要操作的是元素节点,相对简单,逻辑性强,但是兼容性稍差。
一般的,节点至少拥有nodeType
(节点类型)、nodeName
(节点名称)和 nodeValue
(节点值)这三个基本属性。
5.1、父子节点:
//父节点
node.parentNode
:返回某节点的父结点,注意是最近的一个父结点,如果指定的节点没有父结点则返回null// 子节点
parentNode.children:是一个只读属性,返回所有子元素节点,其余节点不返回 ,(重要)(非标准--但使用广泛)
parentNode.firstChild:返回第一个子节点,不管是文本节点还是元素节点,无则返回null
parentNode.lastChild:返回最后一个子节点,不管是文本节点还是元素节点,无则返回null
parentNode.firstElementChild:是一个只读属性,只返回第一个子节点,无则返回null,IE9以上才支持
parentNode.lastElementChild:是一个只读属性,只返回最后一个子节点,无则返回null,IE9以上才支持
//实际开发中的写法,既没有兼容性问题,又可以返回元素
parentNode.children[0]
parentNode.children[parentNode.children.length-1]
什么是只读属性:
举个例子:如果html页面中的<div> <!--a--><img src='' ''> </div>
parentNode.firstElementChild 返回的是 <img src='' ''>
parentNode.firstChild 返回的是 <!--a--> ,因为 文本节点,注释节点也被算入子节点中
5.2、兄弟节点
nextSibling 返回当前元素的下一个兄弟元素节点,包含元素节点、文本节点,找不到则返回null。
previousSibling 返回当前元素上一个兄弟元素节点,包含元素节点、文本节点,找不到则返回null
nextElementSibling 返回当前元素下一个兄弟元素节点,找不到则返回null。兼容性,IE 9+
previousElementSibling 返回当前元素上一个兄弟元素节点,找不到则返回null。兼容性,IE 9+
5.3、节点的创建、添加、删除、复制
页面添加一个新的元素,需要先创建元素再进行添加
1. 创建节点
document.createElement('tagName')
因为这些元素原先不存在,是根据需求动态产生的,所有也称为动态创建元素节点
2. 添加节点
node.appendChild(child) 方法将一个节点添加到指定父节点的子节点列表末尾。类似于 CSS 里面的 after 伪元素。
node.insertBefore(child,指定元素) 方法将一个节点添加到父节点的指定子节点前面。类似于 CSS 里面的 before 伪元素。3.删除节点
node.removeChild(child) 方法从 DOM 中删除一个子节点,返回删除的节点
4.复制节点
node.cloneNode() 方法返回调用该方法的节点的一个副本。
如果括号false(默认),则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点
如果括号参数为 true ,则是深度拷贝,会复制节点本身以及里面所有的子节点
三种动态创建元素区别
1.document.write()
document.write('<div>123</div>')
直接将内容写入页面的内容流,但是文档流执行完毕,所以会导致页面全部重绘,也就是说,如果页面文档流加载完毕,原来的就没有了
2.element.innerHTML
element.innerHTML = '<a> 创建标签 </a>'
特点:
(1)innerHTML 是将内容写入某个DOM节点,**不会导致页面重绘**
(2)innerHTML 创建多个元素效率更高(但是不要采取拼接字符串的形式,要采用数组拼接才效率高)
3.document.createElement()
特点:大量创建时,效率低一点点,但是结构更清晰
六、事件
事件是可以被 JavaScript 侦测到的行为,如键盘操作、鼠标操作。 简单理解:触发— 响应机制
6.1、事件三要素:
事件源 :事件被触发的对象 谁 按钮
事件类型 如何触发,什么事件,比如鼠标点击,还是鼠标经过
事件处理程序:通过一个函数赋值的方式完成
6.2、执行事件的步骤
- 获取事件源
- 注册事件(绑定事件)
- 添加事件处理程序(采取函数赋值形式)
6.3、注册事件
1、注册方式
给元素添加事件,称为注册事件或者绑定事件。注册事件有两种方式:传统方式和事件监听注册方式
传统方式
btn.onclick = function() { }
特点:注册事件的唯一性
同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数。
事件监听注册方式-------w3c推荐方式,同一个元素同一个事件可以注册多个监听器,按注册顺序依次执行。
1.eventTarget.addEventListener(type,listener[,useCapture])
- type:事件类型字符串,比如click,mouseover,注意这里不要带on
- listener:事件处理函数,事件发生时,会调用该监听函数
- useCapture:可选参数,是一个布尔值,默认是 false。看完 DOM 事件流后,再进一步了解
2.eventTarget.attachEvent(eventNameWithOn, callback)
- eventNameWithOn:事件类字符串,onclick,onmouseover,这里带on
- callback:事件处理函数,当目标接触事件时回调函数被调用。
2、删除事件(解绑事件)
传统方式
eventTarget.onclick = null
事件监听方式
- eventTarget.removeEventListener(type,listener[,useCapture]);
- eventTarget.detachEvent(eventNameWithOn, callback); 和attachEvent 配套使用
6.4、DOM事件流
事件流描述的是从页面中接收事件的顺序,事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流
事件冒泡: IE 最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点的过程。 从下往上
事件捕获: 网景最早提出,由 DOM 最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程。 从上往下
事件冒泡:
1、当一个元素的事件被触发时,同样的事件(同名事件)将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒泡。
2、事件冒泡是默认存在的,若想把事件就限制在当前元素内,就需要阻止事件流动,阻止事件流动需要拿到事件对象。注意:
- js中只能执行捕获或冒泡中的一个阶段
- onclick 和 attachEvent只能得到冒泡阶段
- addEventListener(type,listener[,useCapture])第三个参数如果是 true:表示在事件捕获阶段调用事件处理程序; false (不写/默认):表示在事件冒泡阶段调用事件处理程序
阻止冒泡
e.stopPropagation();
e.cancelBubble = true;
如果子元素了阻止事件冒泡,父元素和祖父元素不会有反应,但此时,如果父元素触发了事件,祖父元素还是会有反应的
6.5、事件对象
// 这个 event 就是事件对象,我们还喜欢的写成 e 或者 evt
eventTarget.onclick = function(event) {}
1. event 就是一个事件对象 事件绑定的回调函数的第一个参数就是 事件对象
2. 事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数
3. 事件对象 是 我们事件的一系列相关数据的集合 跟事件相关的 比如鼠标点击里面就包含了鼠标的相关信息,鼠标坐标啊,如果是键盘事件里面就包含的键盘事件的信息 比如 判断用户按下了那个键
4. 这个事件对象我们可以自己命名 比如 event 、 evt、 e
5. 事件对象也有兼容性问题 ie678 通过 window.event 兼容性的写法 e = e || window.event;
官方解释:event 对象代表事件的状态,比如键盘按键的状态、鼠标的位置、鼠标按钮的状态
简单理解:事件发生后,跟事件相关的一系列事件触发时的相关信息集合都放到这个事件对象event里;它有很多属性和方法
事件对象的常见属性和方法
事件对象属性方法 | 说明 |
---|---|
e.target | 返回触发事件的对象 标准 |
e.type | 返回事件的类型 比如click mouseover 不带on |
e.preventDefault() | 该方法阻止默认行为 标准 比如不让链接跳转 |
e.stopPropagation() | 阻止冒泡 标准 |
利用 return false 也能阻止默认行为 | return 后面的代码不执行了, 只限于传统的注册方式, 没有兼容性问题 |
e.target和this区别
e.target 返回的是触发事件的对象(元素) this 返回的是绑定事件的对象(元素)
<div>123</div>
<ul>
<li>abc</li>
<li>abc</li>
<li>abc</li>
</ul>
<script>
// 常见事件对象的属性和方法
// 1. e.target 返回的是触发事件的对象(元素) this 返回的是绑定事件的对象(元素)
// 区别:e.target 点击了那个元素,就返回那个元素 this 那个元素绑定了这个点击事件,那么就返回谁
var div = document.querySelector('div');
div.addEventListener('click', function(e) {
console.log(e.target); //div
console.log(this); //div
})
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e) {
// 我们给ul 绑定了事件 那么this 就指向ul
console.log(this); //ul
console.log(e.currentTarget); //ul
// e.target 指向我们点击的那个对象 谁触发了这个事件 我们点击的是li e.target 指向的就是li
console.log(e.target); //li
})
</script>
6.6、事件委托
原理:事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
作用:我们只操作了一次DOM,提高了程序的性能
6.5案例中:给ul注册点击事件,然后点击里面的li的时候,当前的li可以用event.target得到,并且点击li,事件会冒泡到ul上, ul有注册事件,就会触发事件监听器。
6.7、事件类型
鼠标事件 | 焦点事件 | 键盘事件 | 文本事件 |
---|---|---|---|
鼠标触发 | 表单获得光标 | 键盘触发 | 表单输入触发 |
6.7.1 鼠标事件及其对象
鼠标事件 | 说明 |
onclick | 鼠标点击左键触发 |
onmouseover / onmouseout | 鼠标 经过/离开 触发 |
onmouseenter / onmouseleave(无冒泡/推荐) | 鼠标 经过/离开 触发( 无冒泡/推荐) |
onmousemove | 鼠标移动触发 |
onmouseup / onmousedown | 鼠标 弹起/按下 触发 |
mouseover和mouseenter 的区别:当在某个节点触发时,只要鼠标还在节点内mouseover事件会多次触发,而mouseenter事件只会触发一次 |
应用案例:
禁止鼠标选中 | document.addEventListener('contextmenu',function(e{e.preventDefault();}) |
禁止鼠标右键 | document.addEventListener('selectstart', function(e){e.preventDefault();}) |
6.7.2 键盘事件及其对象
键盘事件 | 触发条件 |
---|---|
onkeyup | 某个键盘按键被松开时触发,最常用,识别所有的键(包括功能键),不区分字母大小写 |
onkeydown | 某个键盘按键被按下时触发,识别所有的键(包括功能键),不区分字母大小写 |
onkeypress | 某个键盘按键被按下时触发,但是它不识别功能键,比如 ctrl shift 箭头 退格 等,区分字母大小写 |
三个事件的执行顺序是:keydown–keypress–keyup
键盘对象属性keyCode:返回该键值的ASCII值,我们可以利用keycode返回的ASCII码值来判断用户按下了那个键
七、DOM小结
关于DOM,主要针对的是页面的元素操作,主要有创建,增,删,改,查,属性操作,事件操作
创建 |
|
增 | 1、appendChild 2、insertBefore |
删 | 1、removeChild |
改 | 主要修改dom的元素属性,dom元素的内容、属性、表单的值等 修改元素属性:src、href、title 等 修改普通元素内容:innerHTML、innerText 修改表单元素:value、type、disabled 修改元素样式:style、className |
查 | 主要获取查询dom的元素 DOM提供的API方法:getElementById、getElementsByTagName (古老用法,不推荐) H5提供的新方法:querySelector、querySelectorAll (提倡) 利用节点操作获取元素:父(parentNode)、子(children)、兄(previousElementSibling、nextElementSibling) 提倡 |
属性操作 | 主要针对于自定义属性 setAttribute:设置dom的属性值 getAttribute:得到dom的属性值 removeAttribute:移除属性 |
事件操作 | 事件注册、事件流、事件对象 |