DOM事件高级
注册事件(绑定事件)
注册事件概述
- 给元素添加事件,称为
注册事件
或者绑定事件
。 - 注册事件有两种方式∶
传统方式
和方法监听注册方式
addEventListener 事件监听方式
- addEventListener里面的
事件类型
是字符串, 必定加引号
,而且不必带on
- 同一个子元素,
同一个事件
可以添加多个侦听器
(事件处理程序) - 用法示例:
<body>
<button>传统注册事件</button>
<button>方法监听注册事件</button>
<script>
var btns = document.querySelectorAll('button');
// 1.传统注册事件
btns[0].onclick = function(){
alert('上山打老虎');
}
btns[0].onclick = function(){
alert('白日依山尽');
}//百日依山尽 传统注册事件只能绑定一个
// 2.事件侦听注册事件
// (1)addEventListener里面的事件类型是字符串 必定加引号,而且不必带on
// (2)同一个子元素,同一个事件可以添加多个侦听器(事件处理程序)
btns[1].addEventListener('click', function(){
alert('3333');
})
btns[1].addEventListener('click', function(){
alert('444');
})
btns[1].addEventListener('click', function(){
alert('5555');
})
</script>
</body>
删除事件(解绑事件)
传统注册方式
eventTarget.onclick =null;
方法监听注册方式
eventTarget.removeEventListener(type,listener [, useCapture] );
- 用法示例:
需求:点击div弹出2022,但点击一次后就不再弹出;所以此时需要解绑事件
示例代码:
<style>
div{
width: 100px;
height: 100px;
background-color: #bfa;
}
</style>
</head>
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<script>
var divs = document.querySelectorAll('div');
divs[0].onclick = function(){
alert('2022');
// 1.传统方式删除事件
divs[0].onclick = null;//点击一次就解除绑定
}
// 2.removeEventLister
divs[1].addEventListener('click', fn)//里面的fn不需要调用加小括号
function fn(){
alert('333');
divs[1].removeEventListener('click', fn)
}
</script>
</body>
DOM事件流(重点)
DOM事件流概念
事件流
描述的是从页面中接收事件的顺序。事件
发生时会在元素节点之间按照特定的
顺序传播,这个传播过程
即DOM事件流
。
- 事件流理解举例:
DOM事件流代码验证
- JS 代码中只能执行捕获或者冒泡其中的一个阶段。
- onclick只能得到冒泡阶段。
- addEventListener(type,listener[,useCapture])
第三个参数
如果是true
,表示在事件捕获阶段调用事件处理程序
;如果是false
(不写默认就是false ),表示在事件冒泡阶段调用事仲处理程序
。 实际开发中我们很少使用事件捕获,我们更关注事件冒泡
。- 有些事件是没有冒泡的,比如onblur、 onfocus、onmouseenter、onmouseleave。
(1)捕获阶段document->html->body-> father->son
此时点击son弹出:则先弹出document,再father,最后son
<style>
.father{
position: relative;
width: 400px;
height: 400px;
background-color: purple;
margin: 200px auto;
}
.son{
position: absolute;
top: 50%;
left: 50%;
width: 250px;
height: 250px;
background-color: #bfa;
margin-top: -125px;
margin-left: -125px;
}
</style>
</head>
<body>
<div class="father">
<div class="son">son</div>
</div>
<script>
// 捕获阶段:如果addEventListener第三个参数是true,则此时处于捕获阶段阶段
document->html->body-> father->son
var son = document.querySelector('.son');
son.addEventListener('click', function(){
alert('son');
},true);//son;只给son绑定事件 所以打印son
var father = document.querySelector('.father');
father.addEventListener('click', function(){
alert('father');
},true);//father son;当给father也绑定事件后,再点击son盒子则先弹出father再弹出son
document.addEventListener('click', function(){
alert('document');
},true);//document father son;最后给document也绑定事件后,则先弹出document,再father,最后son
</script>
</body>
(2)冒泡阶段son->father->body->html-> document
此时点击son弹出:则先弹出son再father,最后document
<style>
.father{
position: relative;
width: 400px;
height: 400px;
background-color: purple;
margin: 200px auto;
}
.son{
position: absolute;
top: 50%;
left: 50%;
width: 250px;
height: 250px;
background-color: #bfa;
margin-top: -125px;
margin-left: -125px;
}
</style>
</head>
<body>
<div class="father">
<div class="son">son</div>
</div>
<script>
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');
});//son father document;只点击son盒子,仍然会弹出father,document,因为事件有冒泡的过程
</script>
</body>
事件对象
什么是事件对象
事件对象的常见属性和方法
e.target和this的区别
e.target
返回的是触发事件
的对象
(元素)this
返回的是绑定事件
的对象
(元素)
代码示例:
-我们给ul绑定点击事件,因为事件处于冒泡阶段:点击li也会触发事件,此时e.target返回li,this则返回ul
<style>
ul{
width: 300px;
height: 300px;
background-color: #bfa;
}
ul li{
background-color: pink;
}
</style>
</head>
<body>
<ul>
<li>123</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click',function(e){
console.log(e.target);//li
console.log(this);//ul
})
</script>
</body>
阻止默认行为
- 利用事件对象里的e.preventDefault()方法;两种注册方式都可
- e.returnValue;//兼容ie6~8,ie
已弃用
不考虑此法 - return false:没有兼容性问题,但
只限于传统的注册方法
,且return后面的代码不执行
-总结:return false只能用于传统注册方式阻止行为,且有弊端;e.preventDfault都可用,它是方法要加()
代码示例:
<body>
<div>
<a href="https://www.baidu.com/">百度</a>
</div>
<script>
var a = document.querySelector('a');
// 阻止事件行为,比如让链接不跳转,按钮不提交
a.addEventListener('click', function(e){
// preventDefault()方法
e.preventDefault();//标准写法
</script>
阻止事件冒泡(重点)
- 事件冒泡∶开始时由最具体的元素接收,然后逐级向上传播到到DOM最顶层节点
- 事件冒泡本身的特性,会带来的坏处,也会带来的好处,需要我们灵活掌握,所以存在阻止事件冒泡这个需求
利用事件对象里面的stopPropagation ()方法
e.stopPropagation();
用法示例:
<script>
// 常见事件对象的属性和方法
// 阻止冒泡 stopPropagation()
var son = document.querySelector('.son');
son.addEventListener('click', function(e){
alert('son');
e.stopPropagation();//阻止事件冒泡
},false);//
var father = document.querySelector('.father');
father.addEventListener('click', function(){
alert('father');
},false);
document.addEventListener('click', function(){
alert('document');
});
</script>
事件委托
- 事件委托:事件委托也称为事件代理,在jQuery里面称为事件委派。
- 事件委托原理(面试点):
不给每个子节点单独设置事件监听器,而是将事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点
- 事件委托的作用:如下例:只操作了一次DOM,提高了程序的性能
用法示例::给ul注册点击事件,然后利用事件对象的target来找到当前点击的li,因为点击li,ul有注册事件,就会触发事件监听器。
<body>
<ul>
<li>飞流直下三千尺</li>
<li>飞流直下三千尺</li>
<li>飞流直下三千尺</li>
<li>飞流直下三千尺</li>
</ul>
<Script>
// 事件委托 原理:给父节点添加侦听器,利用事件冒泡影响每一个子节点
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e){
// alert('飞流直下三千尺');
// e.target这个可以得到我们点击的对象
e.target.style.backgroundColor = 'pink';
})
</Script>
</body>
常用的鼠标事件
- contextmenu 我们可以禁止鼠标右键菜单
- selectstart 禁止选中文字
用法示例:
<body>
我是一段不愿意分享的文字
<script>
// 1.contextmenu 我们可以禁止鼠标右键菜单
document.addEventListener('contextmenu', function(e){
e.preventDefault();
})
// 2.selectstart 禁止选中文字
document.addEventListener('selectstart', function(e){
e.preventDefault();
})
</script>
</body>
鼠标事件对象
event
对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要是用鼠标事件对象MouseEvent
和键盘事件对象KeyboardEvent
。
用法示例:
<script>
// 鼠标事件对象 MouseEvent
document.addEventListener('click', function(e){
// 1.client返回鼠标在可视区域的x和y坐标
console.log(e.clientX);
console.log(e.clientY);
console.log('---------------');
// 2.page鼠标在页面文档的x和y坐标(常用)
console.log(e.pageX);
console.log(e.pageY);
//3.screen 鼠标在电脑屏幕的x和y坐标
console.log(e.screenX);
console.log(e.screenY);
})
</script>
案例:移动的旺仔
案例需求:旺仔gif跟随鼠标移动
案例代码:
<style>
img{
width: 100px;
position: absolute;
}
</style>
</head>
<body>
<img src="../../images/mouse.gif" alt="">
<script>
var img = document.querySelector('img');
document.addEventListener('mousemove', function(e){
var X = e.pageX;
var Y = e.pageY;
img.style.top = Y - 50 +'px';
img.style.left = X - 50 +'px';
console.log(1);
})
</script>
常用的键盘事件
用法示例:
<script>
// 常用的键盘事件
// 1.keyup按键弹起的时候触发
// document.onkeyup = function(){
// alert('我弹起了');
// }
document.addEventListener('keyup', function(){
console.log('我弹起了');
})
// 2.keydown 按键按下的时候触发
document.addEventListener('keydown', function(){
console.log('我被摁下去了');
})
// 3.keypress 按键按下的时候触发:不能识别功能键,比如ctrl,shift,左右箭头
document.addEventListener('keypress', function(){
console.log('我按下了press');
})
// 4.三个事件执行顺序: keydown - keypress - keyup
</script>
key判断用户按下哪个键
<script>
// 键盘事件对象中的keyCode属性可以得到相应键的ASCII码值
//已废弃: 该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它。
document.addEventListener('keyup', function(e){
console.log(e.keyCode);
console.log(e.key);//返回用户按下的物理按键的值
})
</script>
案例:模拟京东按键输入内容
案例需求:按下s键,鼠标自动跳转至搜索框
案例代码:
<body>
<input type="text">
<Script>
// 当用户按下s键,光标就定位到搜索框
var search = document.querySelector('input');
document.addEventListener('keyup', function(e){
if(e.key === 's' || e.key === 'S'){
search.focus();
}
})
</Script>
</body>
模拟京东物流单号查询
案例需求:在文本框中输入内容时,文本框上面自动显示大号的内容
案例代码:
<style>
.search{
width: 200px;
margin: 150px;
position: relative;
}
.con{
position: absolute;
display: none;
top: -20px;
left: 0;
width: 190px;
height: 20px;
line-height: 20px;
font-size: 18px;
border: 1px solid rgba(0, 0, 0, .2);
color: #333;
}
</style>
</head>
<body>
<div class="search">
<div class="con"></div>
<input type="text" placeholder="请输入你的快递单号">
</div>
<script>
// 获取元素
var input = document.querySelector('input');
var con = document.querySelector('.con');
// 注册事件 输入内容则盒子显示
input.addEventListener('keyup', function(){
if(this.value !== ''){
con.style.display = 'block';
con.innerText = this.value;
}else{
con.style.display = '';
}
})
// 失去焦点时,盒子隐藏
input.addEventListener('blur', function(){
con.style.display = 'none';
})
// 获得焦点时,显示盒子
input.addEventListener('focus', function(){
if(this.value !== ''){
con.style.display = 'block';
}
})
</script>
</body>