Web API 的基本认知:
JavaScript分为 ECMAScript (JS基础语法) 和 Web APIs (DOM文档对象模型 + BOM浏览器对象模型),作用就是使用 JS 去操作html元素 (增删查改+样式+属性) 和浏览器 (窗口 存储)
1、DOM简介
1.1 什么是DOM
文档对象模型(Document Object Model,简称 DOM),是 W3C 组织推荐的处理 HTML 或者 XML 的标准编程接口。通过这些 DOM 接口可以改变网页的内容、结构和样式,比如开发网页内容特效和实现用户交互
1.2 DOM树
文档树直观的体现了标签与标签之间的关系(父子级、兄弟级)
文档 document:一个页面就是一个文档,DOM中使用doucument来表示
元素 element:页面中的所有标签都是元素,DOM中使用 element 表示
节点 node:网页中的所有内容都是节点(标签1,属性2,文本3,注释等)
1.3 DOM对象
DOM对象:浏览器根据html标签生成的 JS对象,DOM 把以上内容都看做是对象,所以操作对象使用点语法
- 所有的标签属性都可以在这个对象上面找到
- 修改这个对象的属性会自动映射到标签身上
DOM的核心思想 :把网页内容当做对象来处理
document 对象:是DOM顶级对象, 其提供的属性和方法都是用来访问和操作网页内容的
- 例:
document.write()
- 网页所有内容都在document里面
2、获取元素
2.1 如何获取页面元素
DOM在我们实际开发中主要用来操作元素。 获取页面中的元素可以使用以下几种方式:
- 根据 ID 获取
- 根据标签名获取
- 通过 HTML5 新增的方法获取
- 特殊元素获取
2.2 根据 ID 获取
doucument.getElementByld('id名')
使用 console.dir()
可以打印我们获取的元素对象,更好的查看对象里面的属性和方法。
2.3 根据标签名获取
getElementsByTagName('标签名')
方法可以返回带有 指定标签名 的对象的集合(伪数组)
-
返回的是获取过来元素对象的集合,以伪数组的形式存储
-
得到元素对象是动态的
-
即使该标签只有 1个 或 0 个,返回也是伪数组形式
-
还可以根据标签名获取某个元素(父元素)内部所有指定标签名的子元素
父元素必须是单个对象(必须指明是哪一个元素对象),获取的时候不包括父元素自己。 element.getElementsByTagName('标签名') ol.getElementsByTagName('li');
2.4通过 HTML5 新增的方法获取
① getElementsByClassName
根据类名返回元素对象合集 :document.getElementsByClassName('类名');
②document.querySelector
根据指定选择器返回 第一个 元素对象:document.querySelector('css选择器');
- 标签选择器 input
- 类选择器 .box
- id选择器 #nav
- 包含一个或多个有效的CSS选择器 字符串(如同css选中标签)
③document.querySelectorAll
根据指定选择器返回所有元素对象:document.querySelectorAll('css选择器');
哪怕只有1/0个元素,通过querySelectAll()
获取过来的也是一个伪数组
注意:querySelector
和 querySelectorAll
里面的选择器需要加符号, 比如: document.querySelector('#nav');
④例子
<script>
// 1. getElementsByClassName 根据类名获得某些元素集合
var boxs = document.getElementsByClassName('box');
console.log(boxs);
// 2. querySelector 返回指定选择器的第一个元素对象 切记 里面的选择器需要加符号 .box #nav
var firstBox = document.querySelector('.box');
console.log(firstBox);
var nav = document.querySelector('#nav');
console.log(nav);
var li = document.querySelector('li');
console.log(li);
// 3. querySelectorAll()返回指定选择器的所有元素对象集合
var allBox = document.querySelectorAll('.box');
console.log(allBox);
var lis = document.querySelectorAll('li');
console.log(lis);
</script>
2.5 获取特殊元素
- 获取body对象:
document.body;
- 获取html元素:
document.documentElement;
3、事件基础
3.1 事件概述
JavaScript 使我们有能力创建动态页面,而事件是可以被 JavaScript 侦测到的行为。
简单理解: 触发— 响应机制。网页中的每个元素都可以产生某些可以触发 JS的事件
例如,我们可以在用户点击某按钮时产生一个事件,然后去执行某些操作。
【案例:淘宝点击关闭二维码(父节点) / 随机点名 / 随机问答】
3.2 事件三要素
- 事件源(谁被触发了)
- 事件类型(什么事件)
- 事件处理程序(做啥)
3.3 执行事件的步骤
获取事件源
注册事件(绑定事件)
添加事件处理程序(采取函数赋值形式)
<script>
// 执行事件步骤
// 点击div 控制台输出 我被选中了
// 1. 获取事件源
var div = document.querySelector('div');
// 2.绑定事件 注册事件
// div.onclick
// 3.添加事件处理程序
div.onclick = function() {
console.log('我被选中了');
}
</script>
3.4 鼠标事件
鼠标事件 | 触发条件 |
---|---|
onclick | 鼠标点击左键触发 |
onmouseover 鼠标经过触发 | onmouseout 鼠标离开触发 |
onmouseenter 鼠标经过触发(无冒泡/推荐) | onmouseleave 鼠标离开触发(无冒泡/推荐) |
onmousemove | 鼠标移动触发 |
onmouseup 鼠标弹起触发 | onmousedown 鼠标按下触发 |
事件类型
鼠标事件 | 焦点事件 | 键盘事件 | 文本事件 |
---|---|---|---|
鼠标触发 | 表单获得光标 | 键盘触发 | 表单输入触发 |
mouseenter 鼠标经过 | onfocus 获得鼠标焦点触发 | Keydown 键盘按下触发 | input用户输入事件 |
mouseleave 鼠标离开 | onblur 失去鼠标焦点触发 | Keyup 键盘抬起触发 |
案例:
- 仿新浪微博下拉菜单 + 复选框全选/取消全选案例 + 购物车加减操作 - 鼠标事件
- 小米下拉菜单搜索框案例-焦点事件
- 微博输入字数案例-文本事件
- 京东搜索框快捷键-键盘事件
4、 操作元素
JavaScript 的 DOM 操作可以改变网页内容、结构和样式,我们可以利用 DOM 操作元素来改变元素里面的内容 、属性等。注意以下都是属性
4.1 设置/修改元素内容
① element.innerText
从起始位置到终止位置的内容,不解析html标签,也不保留空格和换行
② element.innerHTML
起始位置到终止位置的全部内容,解析HTML标签,并保留空格和换行
4.2、设置/修改元素属性
表单元素包含:input、textarea、select+option(下拉列表)、button(特殊,双标签,使用innerHTML获取内容)
【案例:点击眼睛明文显示密码】
【案例:表单全选/取消全选】
input.value = “xxx”;
input.type = “xxx”;
input.selected = true / false;
input.disabled = true / false;
input.checked = true / false; (是否被预选定,与 或 配合使用)
js checked 获取值是布尔值,即true 或者 false,而jQuery的获取值则是checked或者undefined
img.src = “xxx”;
img.title = “xxx”;
img.alt = “xxx”;
a.href = “xxx”;
4.3、设置/修改样式属性
我们可以通过 JS 修改元素的大小、颜色、位置等样式。
① 通过style属性
样式比较少 或者 功能简单的情况下使用,逐行更改单个样式: element.style
div.style.backgroundColor = 'pink';
div.style.width = '250px';
修改样式通过style属性引出
如果属性有-连接符,需要转换为小驼峰命名法
赋值的时候,需要的时候不要忘记加css单位
案例:页面刷新,页面随机更换背景图片(标签选择body)
② 通过类名className
可以通过 修改元素的 className 更改元素的样式 适合于样式较多或者功能复杂的情况
将要修改的样式定义为一个类,在JS里将类名修改为:element.className
class 因为是个保留字,因此使用 className 来操作元素类名属性
className 是使用新值换旧值, 如果需要添加一个类, 需要保留之前的类名
this.className = 'change';
this.className = 'first change'; //如果想要保留原先的类名,我们可以这么做 多类名选择器
③通过classList
为了解决className 容易覆盖以前的类名,我们可以通过classList方式追加和删除类名
element.classList.add('类名')
element.classList.remove('类名')
element.classList.toggle('类名')
4.4 总结
4.5 排他思想
如果有同一组元素 li,我们只想要某一个元素 li 实现某种样式,需要用到循环的排他思想算法:
所有元素全部清除样式(干掉其他人 使用for循环)
给当前元素设置样式 (复活我自己 通过this或者下标找到自己或对应元素)
注意顺序不能颠倒,首先干掉其他人,再设置自己
【案例: Tab栏切换】
<script>
// 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) 然后才让当前的元素背景颜色为pink 留下我自己
this.style.backgroundColor = 'pink';
</script>
4.6 自定义属性
目的:保存并保存数据,有些数据可以保存到页面中而不用保存到数据库中
有些自定义属性很容易引起歧义,不容易判断到底是内置属性还是自定义的,所以H5有了规定自定义属性以data-
开头
4.6.1 获取属性值
获取内置属性值(元素本身自带的属性):element.属性;
获取自定义的属性:element.getAttribute('属性');
4.6.2 设置属性值
设置内置属性值:element.属性 = '值';
主要设置自定义的属性:element.setAttribute('属性','值');
4.6.3 移除属性
element.removeAttribute('属性');
<div id="demo" index="1" class="nav"></div>
<script>
var div = document.querySelector('div');
// 1. 获取元素的属性值
// (1) element.属性
console.log(div.id);
//(2) element.getAttribute('属性') get得到获取 attribute 属性的意思 我们程序员自己添加的属性我们称为自定义属性 index
console.log(div.getAttribute('id'));
console.log(div.getAttribute('index'));
// 2. 设置元素属性值
// (1) element.属性= '值'
div.id = 'test';
div.className = 'navs';
// (2) element.setAttribute('属性', '值'); 主要针对于自定义属性
div.setAttribute('index', 2);
div.setAttribute('class', 'footer'); // class 特殊 这里面写的就是class 不是className
// 3 移除属性 removeAttribute(属性)
div.removeAttribute('index');
</script>
4.7、H5自定义属性
自定义属性目的:
4.7.1 设置H5自定义属性
H5规定自定义属性 data-
开头作为属性名并赋值
<div data-index = "1"></> //HTML行内设置
div.setAttribute('data-index',1); // 或者使用JavaScript设置
兼容性获取: element.getAttribute('data-index')
H5新增的:element.dataset.index 或element.dataset['index'] IE11才开始支持
<div getTime="20" data-index="2" data-list-name="andy"></div>
<script>
var div = document.querySelector('div');
console.log(div.getAttribute('getTime'));
div.setAttribute('data-time', 20);
console.log(div.getAttribute('data-index'));
console.log(div.getAttribute('data-list-name'));
// h5新增的获取自定义属性的方法 它只能获取data-开头的
// dataset 是一个集合里面存放了所有以data开头的自定义属性
console.log(div.dataset);
console.log(div.dataset.index);
console.log(div.dataset['index']);
// 如果自定义属性里面有多个-链接的单词,我们获取的时候采取 驼峰命名法
console.log(div.dataset.listName);
console.log(div.dataset['listName']);
</script>
5、节点操作
获取元素通常使用两种方式:这两种方式都可以获取元素节点,我们后面都会使用,但是节点操作更简单
利用DOM提供的方法获取元素 | 利用节点层级关系获取元素 |
---|---|
document.getElementById() | 利用父子兄节点关系获取元素 |
document.getElementsByTagName() | 逻辑性强,但是兼容性较差 |
document.querySelector 等 | 逻辑性不强,繁琐 |
5.1 节点概述
网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM 中,节点使用 node 来表示。
HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除。
利用 DOM 树可以把节点划分为不同的层级关系,常见的是父、子、兄、层级关系。
我们在实际开发中,节点操作主要操作的是元素节点
一般的,节点至少拥有nodeType
(节点类型)、nodeName
(节点名称)和 nodeValue
(节点值)这三个基本属性。
元素节点:nodeType 为1
属性节点:nodeType 为2
文本节点:nodeType 为3 (文本节点包括文字、空格、换行等)
【案例:学成在线案例渲染——按照数据渲染页面】
5.2 父节点
node.parentNode
:parentNode属性可以返回某节点的父结点,注意是最近的一个父结点,如果指定的节点没有父结点则返回null
5.3 子结点
parentNode.childNodes
:返回包含指定节点的子节点的集合,该集合为即时更新的集合【标准】
返回值包含了所有的子结点,包括元素节点,文本节点等;如果只想要获得里面的元素节点,则需要专门处理。所以我们一般不提倡使用childNodes
parentNode.children
(非标准):是一个只读属性,返回所有的子元素节点,它只返回子元素节点,其余节点不返回 (这个是我们重点掌握的),虽然 children 是一个非标准,但是得到了各个浏览器的支持,因此我们可以放心使用
parentNode.firstChild:
第一个子结点,找不到则返回null,同样,也是包含所有的节点
parentNode.lastChild:
返回最后一个子节点,找不到则返回null,同样,也是包含所有的节点
parentNode.firstElementChild:
第一个子结点(兼容性),找不到则返回null,有兼容性问题,IE9以上才支持
parentNode.lastElementChild
:返回最后一个子节点,找不到则返回null,有兼容性问题,IE9以上才支持
5.4 兄弟节点
node.nextSibling
:返回当前元素的下一个兄弟元素节点,找不到则返回null,同样,也是包含所有的节点
previousSibling
:返回当前元素上一个兄弟元素节点,找不到则返回null,同样,也是包含所有的节点
nextElementSibling
: 返回当前元素下一个兄弟元素节点,找不到则返回null,有兼容性问题,IE9才支持
previousElementSibling
: 返回当前元素上一个兄弟元素节点,找不到则返回null,有兼容性问题,IE9才支持
5.5 创建节点
document.createElement('tagName');
方法创建由 tagName 指定的HTML 元素
因为这些元素原先不存在,是根据我们的需求动态生成的,所以我们也称为动态创建元素节点
5.6 添加节点
node.appendChild(child)
方法将一个节点添加到指定父节点的子节点列表末尾。类似于 CSS 里面的 after 伪元素。node.insertBefore(child,指定元素)
方法将一个节点添加到父节点的指定子节点前面。类似于 CSS 里面的 before 伪元素。
5.7 删除节点
node.removeChild(child)
方法从 DOM 中删除一个子节点,返回删除的节点,在JS原生DOM中,删除元素必须通过父元素删除
5.8 复制节点(克隆节点)
node.cloneNode()
方法返回调用该方法的节点的一个副本。 也称为克隆节点/拷贝节点
如果括号false(默认) ,则是浅拷贝,即只克隆复制节点本身,不克隆里面的子节点
如果括号参数为 true ,则是深度拷贝,会复制节点本身以及里面所有的子节点
5.9 面试题
三种动态创建元素的区别
doucument.write() //永远都只是追加操作,且只能追加到
element.innerHTML
document.createElement()
区别:
document.write() 当文档流执行完毕,再将内容追加到页面的内容流前面的位置,会导致页面全部重绘
innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘
innerHTML 创建多个元素效率更高(不要拼接字符串,采取数组形式拼接),结构稍微复杂
createElement()创建多个元素效率稍低一点点,但是结构更清晰
总结:不同浏览器下, innerHTML 效率要比 createElement 高
6、DOM核心
对于DOM操作,我们主要针对元素的操作,主要有:创建3、增3、删1、改3、查2、属性操作3、事件操作
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提供的API方法:getElementById
、getElementsByTagName
(古老用法,不推荐)
H5提供的新方法:querySelector
、querySelectorAll
(提倡)
利用节点操作获取元素:父(parentNode
)、子(children
)、兄(previousElementSibling
、nextElementSibling
) 提倡
6.6、属性操作
主要针对于自定义属性
setAttribute
:设置dom的属性值
getAttribute
:得到dom的属性值
removeAttribute
:移除属性
7、事件高级
7.1 注册事件(绑定事件)
给元素添加事件,称为注册事件或者绑定事件。注册事件有两种方式:传统方式和事件监听注册方式
传统注册on(L0) | 事件监听注册(L2) |
---|---|
利用 on 开头的事件 onclick | w3c 标准推荐方式 |
<button onclick = "alert("hi")"></button> | addEventListener() 它是一个方法 |
btn.onclick = function() {} | IE9 之前的 IE 不支持此方法,可使用 attachEvent() 代替 |
特点:注册事件的唯一性 | 特点:同一个元素同一个事件可以注册多个监听器 |
同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数 | 按注册顺序依次执行 |
addEventListener 事件监听方式
eventTarget.addEventListener(type,listener[,useCapture])
方法将指定的监听器注册到 eventTarget(目标对象)上
当该对象触发指定的事件时,就会执行事件处理函数,该方法接收三个参数:
type:事件类型字符串,比如click,mouseover,注意这里不要带on
listener:事件处理函数,事件发生时,会调用该监听函数
useCapture:可选参数,是一个布尔值,默认是 false(冒泡)。
<script>
var btns = document.querySelectorAll('button');
// 1. 传统方式注册事件
btns[0].onclick = function() {
alert('hi');}
btns[0].onclick = function() {
alert('hao a u');}
// 2. 事件监听注册事件 addEventListener
// (1) 里面的事件类型是字符串 所以加引号 而且不带on
// (2) 同一个元素 同一个事件可以添加多个侦听器(事件处理程序)
btns[1].addEventListener('click', function() {
alert(22);})
btns[1].addEventListener('click', function() {
alert(33);})
// 3. attachEvent ie9以前的版本支持
btns[2].attachEvent('onclick', function() {
alert(11);})
</script>
7.2 删除事件(解绑事件)
removeEventListener
eventTarget.removeEventListener(type,listener[,useCapture])
:删除事件方式,该方法接收三个参数:
type:事件类型字符串,比如click,mouseover,注意这里不要带on
listener:事件处理函数,事件发生时,会调用该监听函数
useCapture:可选参数,是一个布尔值,默认是 false。学完 DOM 事件流后,我们再进一步学习
eventTarget.onclick = null
:传统事件删除方式,可以实现事件解绑
7.3 DOM事件流
事件流描述的是从页面中接收事件的顺序,事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流
事件冒泡: IE 最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点的过程。
事件捕获: 网景最早提出,由 DOM 最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程。
加深理解:我们向水里面扔一块石头,首先它会有一个下降的过程,这个过程就可以理解为从最顶层向事件发生的最具体元素(目标点)的捕获过程;之后会产生泡泡,会在最低点( 最具体元素)之后漂浮到水面上,这个过程相当于事件冒泡。
7.3.1捕获阶段
需求:两个盒子嵌套,一个父盒子一个子盒子,我们的需求是当点击父盒子时弹出 father ,当点击子盒子时弹出 son
document -> html -> body -> father -> son
但是因为DOM流的影响,我们点击子盒子,会先弹出 father,之后再弹出 son,这是因为捕获阶段由 DOM 最顶层节点开始,然后逐级向下传播到到最具体的元素接收
7.3.2冒泡阶段
son -> father ->body -> html -> document
我们点击子盒子,会弹出 son、father、document,这是因为冒泡阶段开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点
事件冒泡:
-
当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为事件冒泡
-
简单理解:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件
-
事件冒泡是默认存在的,若想把事件就限制在当前元素内,就需要阻止事件流动,阻止事件流动需要拿到事件对象
标准写法:e.stopPropagation();
非标准写法: IE6-8 利用对象事件 cancelBubble属性:e.cancelBubble = true;
//阻止事件冒泡
<div class="father">
<div class="son">son盒子</div>
</div>
<script>
// 如果addEventListener 第三个参数是 false 或者 省略 那么则处于冒泡阶段
// son -> father ->body -> html -> document
var son = document.querySelector('.son');
son.addEventListener('click', function() {
alert('son');}, false);
var father = document.querySelector('.father');
father.addEventListener('click', function() {
alert('father');}, false);
document.addEventListener('click', function() {
alert('document');})
</script>
小结
1. JS 代码中只能执行捕获或者冒泡其中的一个阶段
2. onclick 和 attachEvent只能得到冒泡阶段
3. addEventListener(type,listener[,useCapture])第三个参数如果是:
true :表示在事件捕获阶段调用事件处理程序;
false (不写/默认):表示在事件冒泡阶段调用事件处理程序
4. 实际开发中我们很少使用事件捕获,我们更关注事件冒泡
5. 有些事件是没有冒泡的,比如 onblur、onfocus、onmouseenter、onmouseleave
7.4 事件对象
// 这个 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 的区别:
this
是事件绑定的元素, 这个函数的调用者(绑定这个事件的元素),返回ul;console.log(e.currentTarget);
//ul
e.target
是事件触发的元素,返回li
<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>
7.5 事件委托[面试]
事件委托也称为事件代理,在 jQuery 里面称为事件委派
原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
以上案例:给 ul 注册点击事件,然后利用事件对象的 target 来找到当前点击的 li,因为点击 li,事件会冒泡到 ul 上, ul 有注册事件,就会触发事件监听器。
【案例:渲染学生毕业薪资表格案例】
【案例:动态增加留言板,需要显示第几楼】 需要得到当前数据的索引号,可以在添加 对应元素的时候,将索引号给id属性,然后通过e.target.id 获取
7.6 鼠标事件对象
event对象
代表事件的状态,跟事件相关的一系列信息的集合,现阶段我们主要是用鼠标事件对象 MouseEvent 和键盘事件对象 KeyboardEvent。
【案例:跟随鼠标的天使】
鼠标事件对象 | 说明 |
---|---|
e.clientX | 返回鼠标相对于浏览器窗口可视区的X坐标 |
e.clientY | 返回鼠标相对于浏览器窗口可视区的Y坐标 |
e.pageX(重点) | 返回鼠标相对于文档页面的X坐标 IE9+ 支持 |
e.pageY(重点) | 返回鼠标相对于文档页面的Y坐标 IE9+ 支持 |
e.screenX | 返回鼠标相对于电脑屏幕的X坐标 |
e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
【禁止鼠标右键与鼠标选中案例】
contextmenu
:主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单
selectstart
:禁止鼠标选中
7.7 键盘事件/对象
如果使用addEventListener 不需要加 on
三个事件的执行顺序是: keydown – keypress — keyup
键盘事件 | 触发条件 | 使用场景 |
---|---|---|
onkeyup | 某个键盘按键被松开时触发,最常用,识别所有的键(包括功能键),不区分字母大小写 | 快捷键触发 |
onkeydown | 某个键盘按键被按下时触发,识别所有的键(包括功能键),不区分字母大小写 | 游戏子弹发射 |
onkeypress | 某个键盘按键被按下时触发,但是它不识别功能键,比如 ctrl shift 箭头 退格 等,区分字母大小写 |
键盘对象属性keyCode
:返回该键值的ASCII值
<script>
// 键盘事件对象中的keyCode属性可以得到相应键的ASCII码值
// 我们可以利用keycode返回的ASCII码值来判断用户按下了那个键
// 1. 我们的keyup 和keydown事件不区分字母大小写 a 和 A 得到的都是65
// 2. 我们的keypress 事件 区分字母大小写
document.addEventListener('keyup', function(e) {
console.log('up:' + e.keyCode); // a 和 A 得到的都是 65
if (e.keyCode === 65) {
alert('您按下的a键');
} else {
alert('您没有按下a键')}})
document.addEventListener('keypress', function(e) {
console.log('press:' + e.keyCode); // a 97 和 A 得到的是 65
})
</script>
keydown | 某个键盘按键被按下时触发,识别所有的键(包括功能键),不区分字母大小写 | 游戏子弹发射 |
| onkeypress | 某个键盘按键被按下时触发,但是它不识别功能键,比如 ctrl shift 箭头 退格 等,区分字母大小写 | |
键盘对象属性keyCode
:返回该键值的ASCII值
<script>
// 键盘事件对象中的keyCode属性可以得到相应键的ASCII码值
// 我们可以利用keycode返回的ASCII码值来判断用户按下了那个键
// 1. 我们的keyup 和keydown事件不区分字母大小写 a 和 A 得到的都是65
// 2. 我们的keypress 事件 区分字母大小写
document.addEventListener('keyup', function(e) {
console.log('up:' + e.keyCode); // a 和 A 得到的都是 65
if (e.keyCode === 65) {
alert('您按下的a键');
} else {
alert('您没有按下a键')}})
document.addEventListener('keypress', function(e) {
console.log('press:' + e.keyCode); // a 97 和 A 得到的是 65
})
</script>