Web API
Web API介绍
API的概念
API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,无需理解其内部工作机制细节,只需直接调用使用即可。
Web API的概念
Web API 是浏览器提供的一套操作浏览器功能和页面元素的 API ( BOM 和 DOM )。
此处的 Web API 特指浏览器提供的一系列API(很多函数或对象方法),即操作网页的一系列工具。例如:操作html标签、操作页面地址的方法。
DOM 介绍
什么是DOM
文档对象模型(Document Object Model,简称DOM),是 W3C 组织推荐的处理可扩展标记语言((html或者xhtml)的标准编程接口。
W3C 已经定义了一系列的 DOM 接口,通过这些 DOM 接口可以改变网页的内容、结构和样式。
DOM是W3C组织制定的一套处理 html和xml文档的规范,所有的浏览器都遵循了这套标准。
DOM树
DOM树 又称为文档树模型,把文档映射成树形结构,通过节点对象对其处理,处理的结果可以加入到当前的页面。
- 文档:一个页面就是一个文档,DOM中使用document表示
- 节点:网页中的所有内容,在文档树中都是节点(标签、属性、文本、注释等),使用node表示
- 标签节点:网页中的所有标签,通常称为元素节点,又简称为“元素”,使用element表示
- DOM把以上内容都看作是对象
获取元素
根据ID获取元素
- document.getElementById(‘id’)
根据标签名获取元素
- document.getElementsByTagName(‘标签名’)
H5新增获取元素的方式
- 根据类名返回元素对象集合
document.getElementsByClassName(‘类名’) - 根据指定选择器返回第一个元素对象
document.querySelector(‘选择器’) - 根据指定选择器返回,返回的是一个数组
document.querySelectorAll(‘选择器’)
**注意选择器不要遗漏符号 . 或者 # **
事件
事件概述
JavaScript 使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为。
简单理解: 触发— 响应机制。
事件三要素
- 事件源(谁):触发事件的元素
- 事件类型(什么事件): 例如 click 点击事件
- 事件处理程序(做啥):事件触发后要执行的代码(函数形式),事件处理函数
- 事件执行的步骤
- 获取事件源
- 注册事件(绑定事件)
- 添加事件处理程序(采取函数赋值形式)
<body>
<div>123</div>
<script>
// 执行事件步骤
// 点击div 控制台输出 我被选中了
// 1. 获取事件源
var div = document.querySelector('div');
// 2.绑定事件 注册事件
// div.onclick
// 3.添加事件处理程序
div.onclick = function() {
console.log('我被选中了');
}
</script>
</body>
常见的鼠标事件
注册事件
- 传统注册方式
btn.onclick = function(){}
特点:唯一性
同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数会将前面的处理函数覆盖掉。 - 监听注册方式
btn.addEventListener(事件类型,事件处理函数,标识)
btn.attachEvent()
特点:同一个元素同一个事件可以注册多个监听器,按注册顺序依次进行监听。
标识如果写false,或者不写,代表是注册冒泡阶段。如果写true,代表是注册捕获阶段。
注销事件
- 传统方式
btn.onclick = null; - 监听方式
btn.removeEventListener(事件类型,事件处理函数)
btn.detachEvent()
事件对象
什么是事件对象
事件对象就是一个容器,用来存储这一次事件相关的所有数据.
如何获取事件对象
事件对象是事件处理函数里面的形参,是系统传递给我们的,我们只需要在事件处理函数里面定义形参,接收就可以使用了。
事件对象的属性和方法
this和e.target的区别
- this 是事件绑定的元素(绑定这个事件处理函数的元素) 。
- e.target 是事件触发的元素。
常情况下terget 和 this是一致的,
但有一种情况不同,那就是在事件冒泡时(父子元素有相同事件,单击子元素,父元素的事件处理函数也会被触发执行),
这时候this指向的是父元素,因为它是绑定事件的元素对象, 而target指向的是子元素,因为他是触发事件的那个具体元素对象。
事件流
事件流描述的是从页面中接受事件的顺序。
DOM 事件流会经历3个阶段:
- 捕获阶段
- 当前目标阶段
- 冒泡阶段
事件发生时会在元素节点之间按照特点的顺序传播,这个传播过程即DOM事件流。
注意:
- JS代码中只能执行捕获或者冒泡其中一个阶段
- onclick和attachEvent只能得到冒泡阶段
- addEventListener第三个参数为true表示在事件捕获阶段调用事件处理函数程序,如果第三个参数是false(默认也是false )表示在事件冒泡阶段调用事件处理函数程序。
- 实际开发中很少使用事件捕获,更加关注事件冒泡。
- 有些事件是没有冒泡的,比如onblur,onfocus,mouseenter,mouseleave。
事件委托
本应该给子元素设置的点击事件,我们统一给父元素设置了,利用事件冒泡,每一个子元素一点单击就会冒泡给父元素,就能够统一进行处理。
作用:
- 我们只操作了一次 DOM ,提高了程序的性能。
- 动态新创建的子元素,也拥有事件。
<ul>
<li>知否知否,点我应有弹框在手!</li>
<li>知否知否,点我应有弹框在手!</li>
<li>知否知否,点我应有弹框在手!</li>
<li>知否知否,点我应有弹框在手!</li>
<li>知否知否,点我应有弹框在手!</li>
</ul>
<script>
// 事件委托的核心原理:给父节点添加侦听器, 利用事件冒泡影响每一个子节点
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e) {
// e.target 这个可以得到我们点击的对象
e.target.style.backgroundColor = 'pink';
})
</script>
键盘事件
排他思想
核心:干掉别人,留下自己。
思路:遍历数组,把数组里面的每一个元素去掉高亮显示,利用this代表当前元素,设置高亮。
// 1. 获取所有按钮元素
var btns = document.getElementsByTagName('button');
// btns得到的是伪数组 里面的每一个元素 btns[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) 然后才让当前的元素背景颜色为red 留下我自己
this.style.backgroundColor = 'red';
}
}
操作元素
innerText和innerHTML的区别
- 获取内容时的区别:
innerText会去除空格和换行,而innerHTML会保留空格和换行
- 设置内容时的区别:
innerText不会识别html,而innerHTML会识别
自定义属性
原生没有兼容性的方法
- 设置属性
element.setAttribute(属性名,属性值) - 获取属性
element.getAttribute(属性名) - 移出属性
element.removeAttribute(属性名)
H5新增的方法
建议自定义属性以 data- 开头,浏览器解析的时候会帮我们维护这类属性,维护在 dataset对象中。
- 获取:element.dataset.属性名
节点操作
父子关系的节点操作
-
获取父元素(父节点)
element.parentNode -
获取子元素(子节点)
element.children
element.childNode -
获取第一个子元素(子节点)
element.firstElementChild
element.firstChild -
获取最后一个子元素(子节点)
element.lastElementChild
element.lastChild
兄弟关系的节点操作
-
上一个兄弟节点(元素)
element.previousSibling
element.previousElementSibling -
下一个兄弟节点(元素)
element.nextSibling
element.nextElementSibling
创建节点的三种方式
-
document.write()
如果页面已经渲染完毕,再调用的话会导致页面重绘,覆盖当前页面。 -
element.innerHTML
创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂。 -
document.createElement
仅仅只是在内存中创建,页面还看不到,如果想要看到需要添加到DOM树。 -
三种创建节点方式效率对比
<script>
//innerHTML字符串拼接方式(效率低)
function fn() {
var d1 = +new Date();
var str = '';
for (var i = 0; i < 1000; i++) {
document.body.innerHTML += '<div style="width:100px; height:2px; border:1px solid blue;"></div>';
}
var d2 = +new Date();
console.log(d2 - d1);
}
fn();
</script>
<script>
//createElement方式(效率一般)
function fn() {
var d1 = +new Date();
for (var i = 0; i < 1000; i++) {
var div = document.createElement('div');
div.style.width = '100px';
div.style.height = '2px';
div.style.border = '1px solid red';
document.body.appendChild(div);
}
var d2 = +new Date();
console.log(d2 - d1);
}
fn();
</script>
<script>
//innerHTML数组方式(效率高)
function fn() {
var d1 = +new Date();
var array = [];
for (var i = 0; i < 1000; i++) {
array.push('<div style="width:100px; height:2px; border:1px solid blue;"></div>');
}
document.body.innerHTML = array.join('');
var d2 = +new Date();
console.log(d2 - d1);
}
fn();
</script>
添加节点
- parent.appendChild() 追加节点(默认追加到最后)
- parent.insertBefore(要插入的元素,参照元素)
插入在某一个元素前面
删除节点
- parent.removeChild() 删除子孩子
- element.remove() 删除自己
克隆节点
- element.cloneNode(参数)
参数如果是true,代表是深拷贝,既复制当前标签,又复制内容。
如果不写或者写false,代表是浅拷贝,只复制当前的标签。