DOM事件基础就要结束了,今天整理一下,发上来。做的小案例和练习,有的我没有放html和css,一般都是使用ul和li做的,大家可以自行搭建吧,主要是学习JavsScript的,但是也不能忘记前面学习的。
事件的注册和解绑
两种注册绑定事件的方式
<script>
// 给li注册点击事件
// 传统方式
var lis = document.querySelector('ul').querySelectorAll('li');
// for (var i = 0; i < lis.length; i++) {
// lis[i].onclick = function () {
// alert('li被点击了');
// }
// // lis[i].onclick = function () {
// // alert('传统方式的唯一性'); // 这个注册事件把上面一个事件给覆盖掉了
// // }
// }
// 监听方法注册事件
for (var i = 0; i < lis.length; i++) {
lis[i].addEventListener('click', fn);
}
function fn() {
alert('add点击实现li');
alert('可以注册多个事件');
}
</script>
两种解除事件绑定的方式
<script>
// 给li注册点击事件
// 传统方式
var lis = document.querySelector('ul').querySelectorAll('li');
var lilis = document.querySelector('.ul').querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
lis[i].onclick = function () {
alert('li被点击了');
// 解绑事件
// 传统方式的解绑
this.onclick = null;
}
// lis[i].onclick = function () {
// alert('传统方式的唯一性'); // 这个注册事件把上面一个事件给覆盖掉了
// }
}
// 监听方法注册事件
for (var i = 0; i < lilis.length; i++) {
lilis[i].addEventListener('click', fn);
}
for (var i = 0; i < lilis.length; i++) {
lilis[i].removeEventListener('click', fn);
}
function fn() {
alert('add点击实现li');
alert('可以注册多个事件');
}
</script>
DOM事件的事件流
代码中的注释有详细解释
其中包含阻止冒泡阶段
利用冒泡可以进行事件委托,就是不给子节点添加监听方法,给父节点添加监听方法来影响子节点。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
position: relative;
width: 400px;
height: 400px;
background-color: pink;
margin: 100px auto;
}
ul {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
width: 200px;
height: 200px;
background-color: purple;
}
</style>
</head>
<body>
<div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
</div>
<script>
// 事件流:事件的传播过程叫做事件流
// addEventListener(type, listener[, useCapture])
var div = document.querySelector('div');
var ul = document.querySelector('ul');
var lis = document.querySelectorAll('li');
// 捕获阶段:doucument-->html-->body-->div-->ul-->li
// 冒泡阶段:doucument<--html<--body<--div<--ul<--li
// 给li注册点击事件
for (var i = 0; i < lis.length; i++) {
lis[i].addEventListener('click', function (e) {
alert('方法监听实现li被点击');
// 阻止事件冒泡 给li使用方法阻止冒泡,div的事件就不会触发了
e.stopPropagation(); // div的事件就没有执行了 因为阻止了li的冒泡阶段
})
}
// 给div注册点击事件
// 先执行的是li的事件,然后冒泡得到div的事件 因为方法监听的第三个参数省略不写得到的是冒泡阶段
// 把第三个参数设为:true 得到的是捕获阶段:先得到div事件,再得到li的事件
// 为false或者省略不写 得到的是冒泡阶段 先得到li事件,再得到div的事件
div.addEventListener('click', function () {
alert('div被点击');
}, false)
</script>
</body>
</html>
事件对象
鼠标事件
实现案例:图片跟着鼠标移动。
<script>
// 常用事件对象的方法和属性
// preventDefault()方法 阻止默认事件
// target属性:返回的是触发事件的对象元素
// type属性:返回的是事件类型
// 常用的事件对象 鼠标事件和键盘事件
// 鼠标常用事件:contextmenu selectstart
// contextmenu 禁止鼠标右键 preventDefault方法 阻止默认行为
// selectstart 禁止文字被选中
var lis = document.querySelector('ul').querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
// 在li上鼠标是无法右键弹出菜单的
lis[i].addEventListener('contextmenu', function (e) {
e.preventDefault();
e.returnValue; //兼容ie678的写法
})
// li中的文字无法被选中
lis[i].addEventListener('selectstart', function (e) {
e.preventDefault();
})
}
// 鼠标事件对象中常用的属性 client系列:是鼠标位置距离可视窗口水平和垂直的距离
// page系列:是鼠标位置距离页面顶部(左上角)水平和垂直距离
document.addEventListener('click', function (e) {
console.log(e.clientX);
console.log(e.clientY);
console.log(e.pageX);
console.log(e.pageY);
})
// 鼠标事件对象的案例:图片跟随鼠标移动
var img = document.querySelector('img');
document.addEventListener('mousemove', function (e) {
// 坑:一定要加单位 px
var x = e.clientX;
var y = e.clientY;
img.style.top = y - 50 + 'px';
img.style.left = x - 40 + 'px';
})
</script>
键盘事件
案例:判断用户输入的字母是否为s,是的话表单自动获得焦点
<script>
// 键盘事件
// keyup:键盘弹起触发 文本不会录入文本框
// keydown:键盘按下触发 不识别字母大小写 文本会录入文本框
// keypress:键盘下触发
// keyCode 可以识别 返回的是字符对应的ASCII值
// 实现按下s键,搜索框自动获焦
var search = document.querySelector('input');
document.addEventListener('keyup', function (e) {
if (e.keyCode == 83) {
search.focus();
console.log(e.keyCode);
}
})
</script>
案例:查询快递单号
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.search {
position: relative;
width: 178px;
margin: 100px;
}
.con {
display: none;
position: absolute;
top: -40px;
width: 171px;
border: 1px solid rgba(0, 0, 0, .2);
box-shadow: 0 2px 4px rgba(0, 0, 0, .2);
padding: 5px 0;
font-size: 18px;
line-height: 20px;
color: #333;
}
.con::before {
content: '';
width: 0;
height: 0;
position: absolute;
top: 28px;
left: 18px;
border: 8px solid #000;
border-style: solid dashed dashed;
border-color: #fff transparent transparent;
}
</style>
</head>
<body>
<div class="search">
<div class="con">123</div>
<input type="text" placeholder="请输入您的快递单号" class="jd">
</div>
<script>
// 快递单号输入内容时, 上面的大号字体盒子(con)显示(这里面的字号更大)
// 表单检测用户输入: 给表单添加键盘事件
// 同时把快递单号里面的值(value)获取过来赋值给 con盒子(innerText)做为内容
// 如果快递单号里面内容为空,则隐藏大号字体盒子(con)盒子
var con = document.querySelector('.con');
var jd_input = document.querySelector('.jd');
jd_input.addEventListener('keyup', function () {
// console.log('输入内容啦');
if (this.value == '') {
con.style.display = 'none';
} else {
con.style.display = 'block';
con.innerText = this.value;
}
})
// 当我们失去焦点,就隐藏这个con盒子
jd_input.addEventListener('blur', function () {
con.style.display = 'none';
})
// 当我们获得焦点,就显示这个con盒子
jd_input.addEventListener('focus', function () {
if (this.value !== '') {
con.style.display = 'block';
}
})
</script>
</body>
</html>
效果
最后附上我的学习笔记。
DOM事件学习笔记
###注册事件的两种方式
传统方式:
事件源.事件类型 = 事件处理程序
方法监听注册:
1.使用addEventListener()方法 存在兼容性问题:支持ie9以上
事件源.addEventListener('type',listener)
addEventListener()方法有三个参数
type:事件类型
listener:处理函数,也叫监听器,就是事件处理程序的函数
这里的处理函数可以写在外面,添加监听时直接调用函数名即可
useCapture:判断是捕获还是冒泡过程,可选参数
2.使用attachEvent()方法 ie678支持,使用方法与addEventListener()相同两种方式的区别
1.传统方式注册事件,具有唯一性,简单来说就是同一元素同一个事件只能注册一次
方法监听注册可以同一元素同一事件可以注册多个监听器
2.传统方式的事件类型带 on,比如 onclick、onmouseover等
方法监听的事件类型不带 on,比如 click mouseover等###删除事件
传统方式:
事件源.事件类型 = null
方法监听方式:
事件源.removeEventListener('type',listener)###DOM事件流
概念:事件的传播过程就是DOM事件流
事件流的三个阶段
1.捕获阶段
事件从最顶层节点(document)往里层找当前目标
2.当前目标阶段
监听事件的元素
3.冒泡阶段
事件从当前目标往顶层节点找
方法监听的第三个参数:
useCapture:
true —— 捕获阶段
false\省略不写 —— 冒泡阶段
事件流注意点
JS代码只能获取捕获阶段或者冒泡阶段
有些事件是没有冒泡阶段的:onfocus、onblur、onmouseenter、onmouseleave
attachEvent()和onclick只能得到冒泡阶段###事件对象 addEventListener('click',function(e){})
常用事件一般包括的是鼠标事件和键盘事件
事件对象的解释
事件对象是事件的一系列相关数据的集合
事件对象只有事件存在,才会有事件对象
事件的处理函数中的一个参数(形参),就是事件对象event都可以
事件对象是系统自动创建的,不需要我们传输参数,直接使用。其中event是程序员可以自定义的evt、e都可以表示事件对象
ie678,通过window.event 获取事件对象,参数必须是event
常见事件对象的属性和方法
方法
e.preventDefault() 方法:阻止事件默认行为 比如说:让连接不跳转、按钮不能提交等
e.returnValue 是属性 阻止事件默认行为 为了兼容ie678
属性
e.target 返回的是触发事件的对象(元素) 谁触发事件,返回谁
与this区别:this是谁绑定事件(注册事件、添加监听)返回谁
e.type 返回的是事件类型###阻止事件冒泡
使用事件对象方法
e.stopPropagation() 方法
e.cancelBubble = true###事件委托
原理
不在每个子节点上添加监听器,而是在子节点的父节点上添加监听,利用冒泡原理影响设置每个子节点
作用
DOM操作次数减少,提高程序性能###常用的鼠标事件
禁止鼠标右键:contextmenu
ele.addEventListener('contextmenu',function(e){
e.preventDefault();
})
禁止选中文字:selectstart
ele.addEventListener('selectstart',function(e){
e.preventDefault();
}
###鼠标事件对象 MouseEvent中常用的属性
e.clientX 返回的是鼠标距离可视区域顶部的距离 可视区域就是眼睛看到的那一个矩形
e.clientY 返回的是鼠标距离可视区域左边的距离
e.pageX 返回的是鼠标距离页面顶部距离
e.pageY 返回的是鼠标距离页面左侧距离
实现一个案例:图片跟着鼠标移动 鼠标到哪图片跟着到哪。实质就是获取鼠标的位置,把位置数据复制给图片的top和left###常用键盘事件
keyup:键盘弹起,松开时触发事件
keydown:键盘按下,按键盘点击时触发事件
keypress:键盘按下触发事件
keydown和keypress的区别
keydown 不区别字母大小写;keypress不识别功能键,比如ctrl等
二者均是在按下按键触发事件,在执行时,keydown先于keypress执行
键盘事件对象常用的属性
e.keyCode 返回的是字符的ASCII字符编码
用此属性判断字母大小写
实例:检测用户输入的字符 s可以使搜索框自动获焦点 表单的focus()方法——获焦
keydown和keypress在文本框中的特点:
这两个事件触发的时候,文字还没有落入文本框。因为在按下的那一瞬间就触发了事件,文字还没来得及存入文本框
keyup事件触发是在松开时,这是文字已经落入文本框内