web前端练习28----Dom4,事件(事件对象,事件冒泡,事件委派,事件传播,事件绑定,事件移除及案例练习)
Posted zhaihaohao1
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了web前端练习28----Dom4,事件(事件对象,事件冒泡,事件委派,事件传播,事件绑定,事件移除及案例练习)相关的知识,希望对你有一定的参考价值。
一、事件对象 event
1.1概念:
事件处理函数可以附加在各种对象上,包括 DOM元素,window 对象等。
当事件发生时, event 对象就会被创建并依次传递给事件监听器。
在处理函数中,将event对象作为第一个参数,可以访问 DOM Event 接口。
event 对象里有很多事件相关的属性和方法,例如事件,被点击元素对象target,创建时间,事件类型,坐标,path等
1.2event的常用属性:
event.target 触发事件的元素对象(就是事件目标)
event.clientX,event.clientY 鼠标触发的可见横纵坐标
event.bubbles 事件是否冒泡
event.cancelBubble = true; 取消冒泡
event.eventPhase;1捕获,2目标,3冒泡
event.preventDefault(); 取消 addEventListener() 绑定事件的默认行为
event.type;被触发的事件的类型
event.wheelDelta 根据正负判断onmousewheel 事件向上还是向下滚动
event.detail 根据正负判断 DOMMouseScroll 事件向上还是向下滚动 (兼容火狐的)
键盘相关属性
event.key 获取按键
event.keyCode 获取按键的编码
event.altKey alt是否被按下
event.ctrlKey ctrl是否被按下
event.shiftKey shift是否被按下
代码示例:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="eventId">事件测试</div>
<script>
//事件处理函数可以附加在各种对象上,包括 DOM元素,window 对象等。
//当事件发生时, event 对象就会被创建并依次传递给事件监听器。
//在处理函数中,将event对象作为第一个参数,可以访问 DOM Event 接口。
//event 对象里有很多事件相关的属性和方法,例如事件,被点击元素对象target,创建时间,事件类型,坐标,path等
let eventId = document.getElementById('eventId');
eventId.onclick = function(event)
// ie8(及ie8以下)中拿到event要 window.event
// 兼容ie8
if (event)
console.log(event);
else
event = window.event;
console.log('ie8' + event);
// if...else...写法的另一种写法,三目表达式
// event = event ? event : window.event;
// console.log(event);
// if ...else...写法的另一种写法
// event = event || window.event;
// console.log(event);
</script>
</body>
</html>
二、事件冒泡:
2.1事件冒泡的概念:
事件冒泡(Bubble)
所谓事件冒泡,就是事件向上传导,当后代元素上的事件被触发时,
其祖先元素的相同事件也会被触发(不管事件是否写出来)
开发中大部分冒泡是有用的,如果不需要冒泡,可以取消冒泡 event.cancelBubble = true;
冒泡 span----div2----div1----body----html----document----window
冒泡示意图:
事件冒泡代码示例:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<!-- 事件的冒泡 -->
<body id="body">
<div id="div1" style="width: 300px;height: 300px; background-color: blue;">
<div id="div2" style="width: 200px;height: 200px; background-color: red;">
<span id="span" style="width: 100px;height: 100px; background-color: yellow;">我是span元素</span>
</div>
</div>
</body>
<script>
// 事件冒泡 参考文章 https://blog.csdn.net/caseywei/article/details/86071764
// 事件冒泡(Bubble)
// 所谓事件冒泡,就是事件向上传导,当后代元素上的事件被触发时,
// 其祖先元素的相同事件也会被触发(不管事件是否写出来)
// 开发中大部分冒泡是有用的,如果不需要冒泡,可以取消冒泡 event.cancelBubble = true;
// 冒泡 span----div2----div1----body----html----document----window
let body = document.getElementById('body');
let div1 = document.getElementById('div1');
let div2 = document.getElementById('div2');
let span = document.getElementById('span');
body.onclick = function(event)
console.log(" 产生事件的节点:" + event.target.id + " 当前节点:" + event.currentTarget.id);
div1.onclick = function(event)
console.log(" 产生事件的节点:" + event.target.id + " 当前节点:" + event.currentTarget.id);
div2.onclick = function(event)
console.log(" 产生事件的节点:" + event.target.id + " 当前节点:" + event.currentTarget.id);
span.onclick = function(event)
console.log(" 产生事件的节点:" + event.target.id + " 当前节点:" + event.currentTarget.id);
// 取消冒泡
event.cancelBubble = true;
</script>
</html>
三、事件委派(事件冒泡的应用)
3.1事件委派的概念:
事件委派:事件统一绑定给共同的父元素,子元素触发事件(不管事件是否写出来),会冒泡给父元素,
通过父元素的响应函数处理事件,根据 event.target,拿到子元素,判断处理逻辑
事件委派利用了事件冒泡,事件委派可以减少事件绑定的次数,提高程序性能
使用场景:父元素下面有多个子元素,都需要添加事件,我们通常需要一个一个添加(循环添加),而且新加的元素需要单独绑定事件
事件委派代码示例:
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<ul id="ulId">
<li id="li1" class="classLI">zhh1</li>
<li id="li2" class="classLI">zhh2</li>
<li id="li3" class="classLI">zhh3</li>
<li id="li4" class="classLI">zhh4</li>
<li id="li5" class="classLI">zhh5</li>
</ul>
<script>
// 事件的委派
// 父元素下面有多个子元素,都需要添加事件,我们通常需要一个一个添加(循环添加),而且新加的元素需要单独绑定事件
// 事件委派:事件统一绑定给共同的父元素,子元素触发事件(不管事件是否写出来),会冒泡给父元素,
// 通过父元素的响应函数处理事件,根据 event.target,拿到子元素,判断处理逻辑
// 事件委派利用了事件冒泡,事件委派可以减少事件绑定的次数,提高程序性能
let ulId = document.getElementById('ulId');
ulId.onclick = function(event)
//兼容ie8及以下
event = event || window.event;
// event.target 返回触发此事件的元素(事件的目标节点)。
// 这里返回的就是 li
if (event.target.nodeName == 'LI')
console.log(event.target.id);
</script>
</body>
</html>
四、事件传播
4.1事件传播的概念:
- 事件传播分成了三个阶段
1.捕获阶段:- 在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
2.目标阶段:- 事件捕获到目标元素,捕获结束开始在目标元素上触发事件
3.冒泡阶段:- 事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件
- 如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true
一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false
- IE8及以下的浏览器中没有捕获阶段(只有目标阶段和冒泡阶段)
事件传播示意图:
代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box1
width: 300px;
height: 300px;
background-color: yellowgreen;
#box2
width: 200px;
height: 200px;
background-color: yellow;
#box3
width: 150px;
height: 150px;
background-color: skyblue;
</style>
<script type="text/javascript">
// 事件的传播
window.onload = function()
/*
* 分别为三个div绑定单击响应函数
*/
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
var box3 = document.getElementById("box3");
/*
* 事件的传播
* - 事件传播分成了三个阶段
* 1.捕获阶段
* - 在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
* 2.目标阶段
* - 事件捕获到目标元素,捕获结束开始在目标元素上触发事件
* 3.冒泡阶段
* - 事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件
*
* - 如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true
* 一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false
*
* - IE8及以下的浏览器中没有捕获阶段(只有目标阶段和冒泡阶段)
*/
bind(box1, 'click', function()
alert('box1');
);
bind(box2, 'click', function()
alert('box2');
);
bind(box3, 'click', function()
alert('box3');
);
;
function bind(obj, eventStr, callback)
if (obj.addEventListener)
// 大部分浏览器兼容的方式
// 如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true
// 一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false
obj.addEventListener(eventStr, callback, true);
else
/*
* this是谁由调用方式决定
* callback.call(obj)
*/
//IE8及以下
obj.attachEvent("on" + eventStr, function()
//在匿名函数中调用回调函数
callback.call(obj);
);
</script>
</head>
<body>
<div id="box1">
<div id="box2">
<div id="box3"></div>
</div>
</div>
</body>
</html>
五、事件的绑定
5.1事件的两种绑定方式:
5.11只能绑定一个响应函数:
divId.onclick = function()
console.log('我是翟浩浩');
5.12绑定多个响应函数:
divId.addEventListener('click',function()
alert(1);
,false);
divId.addEventListener('click',function()
alert(2);
,false);
divId.addEventListener('click',function()
alert(3);
,false);
5.13绑定多个响应函数,兼容ie8及以下
绑定多个响应函数,和 addEventListener 不同的是,后绑定的先执行
divId.attachEvent('onclick', function()
alert(1);
);
divId.attachEvent('onclick', function()
alert(2);
);
divId.attachEvent('onclick', function()
alert(3);
);
绑定多个响应事件代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="divId">点击事件</div>
<script>
// 事件绑定封装兼容ie8的函数 myBind
var divId = document.getElementById('divId');
myBind(divId, 'click', function()
// 直接打印出来的是对象的类型
console.log(this);
console.log(111);
);
myBind(divId, 'click', function()
// 直接打印出来的是对象的类型
console.log(this);
console.log(222);
);
// 自己封装一个函数兼容,ie8以下,及别的浏览器
function myBind(obj, eventString, callBack)
if (obj.addEventListener)
// 其它其它浏览器
obj.addEventListener(eventString, callBack, false);
else
// ie8及以下浏览器,这个回调函数中的this,指向的是window,要使用call指向obj
obj.attachEvent('on' + eventString, function()
callBack.call(obj)
);
</script>
</body>
</html>
5.2取消事件默认行为的方法:
默认行为:比如
1.a元素的跳转行为,绑定点击事件后还能跳转 a.onclick
2.浏览器内容较大时,上下滚动行为 box1.onmousewheel
3.输入框显示输入内容的行为,input.onkeydown
5.21取消默认行为:aId.onclick = function() 只要 reurn false; 就可以取消
<body>
<a id="aId" href="https://www.baidu.com/">点击链接</a>
<script>
// 键盘事件
let aId = document.getElementById('aId');
aId.onclick = function ()
return false;
</script>
</body>
5.22取消默认行为:box1.addEventListener('DOMMouseScroll', fun, false); 需要 event.preventDefault(); 即可取消
<body>
<a id="aId" href="https://www.baidu.com/">点击链接</a>
<script>
// 键盘事件
let aId = document.getElementById('aId');
aId.addEventListener('click',function(event)
console.log('事件点击了');
event.preventDefault();
,false);
</script>
</body>
六、事件的移除:
对应:btn.onclick = function() 所有浏览器都可以
btn.οnclick=null;
对应:addEventListener 兼容ie9及以上
btn.removeEventListener('click', btnClick);
七、案例练习:
7.1 拖拽练习
onmousedown 鼠标按下, onmousemove 鼠标移动, onmouseup 鼠标放开
利用上面三个事件完成拖拽练习,效果图如下:
事件拖拽的坐标计算
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#box1
width: 100px;
height: 100px;
background-color: red;
position: absolute;
#box2
width: 100px;
height: 100px;
background-color: yellow;
position: absolute;
left: 300px;
</style>
</head>
<body>
<p>测试</p>
<div id="box1">方块1</div>
<div id="box2">方块2</div>
<script>
//拖拽练习3
var box1 = document.getElementById('box1');
var box2 = document.getElementById('box2');
drop(box1);
drop(box2);
// 自己封装的拖拽函数
function drop(obj)
// 绑定按下事件:
obj.onmousedown = function(event)
event = event || window.event;
console.log('onmousedown');
// 左边div偏移量 = 鼠标.clientX - 元素.offsetLeft;
// 上边div偏移量 = 鼠标.clientY - 元素.offsetTop;
var oLeft = event.clientX - obj.offsetLeft;
var oTop = event.clientY - obj.offsetTop;
// 鼠标滑动事件,给 document 绑定
document.onmousemove = function(event)
console.log('onmousemove');
// 兼容ie8
event = event || window.event;
var left = event.clientX - oLeft;
var top = event.clientY - oTop;
// 设置外边距
obj.style.left = left + 'px';
obj.style.top = top + 'px';
// 鼠标放开事件,给docment绑定
document.onmouseup = function()
console.log('onmouseup');
// 终止移动事件
document.onmousemove = null;
// 终止鼠标放开事件
document.onmouseup = null;
/*
* 当我们拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,
* 此时会导致拖拽功能的异常,这个是浏览器提供的默认行为,
* 如果不希望发生这个行为,则可以通过return false来取消默认行为
*
* 但是这招对IE8不起作用
*/
return false;
</script>
</body>
</html>
7.2滚轮练习,要求:鼠标滚轮滚动,改变方块的宽高
onmousewheel 监听鼠标滚轮事件
效果图:
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
*
margin: 0px;
padding: 0px;
#box1
width: 100px;
height: 100px;
background-color: red;
position: absolute;
</style>
</head>
<body style="height: 2000px;">
<!-- 滚轮练习 -->
<p>测试</p>
<div id="box1">方块1</div>
<script>
let box1 = document.getElementById('box1');
// 其他其他浏览器的滚轮事件
box1.onmousewheel = fun;
// 火狐浏览器的滚轮事件
box1.addEventListener('DOMMouseScroll', fun, false);
function fun(event)
// 兼容ie8
event = event || window.event;
console.log(event);
//event.wheelDelta 可以获取鼠标滚轮滚动的方向
//向上滚 120 向下滚 -120
//wheelDelta这个值我们不看大小,只看正负
// 兼容火狐
//在火狐中使用event.detail来获取滚动的方向
//向上滚 -3 向下滚 3
//event.detail 这个值我们不看大小,只看正负
if (event.wheelDelta > 0 || event.detail < 0)
let height = box1.clientHeight;
if (height > 30)
box1.style.height = box1.clientHeight - 10 + 'px';
else
box1.style.height = box1.clientHeight + 10 + 'px';
/*
* 使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false
* 需要使用event来取消默认行为event.preventDefault();
* 但是IE8不支持event.preventDefault();这个玩意,如果直接调用会报错
* 所以这里要判断
*/
if (event.preventDefault)
event.preventDefault();
/*
* 当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动,
* 这是浏览器的默认行为,如果不希望发生,则可以取消默认行为 return false;
*/
return false;
</script>
</body>
</html>
7.3键盘事件:
键盘事件最常用的就是 onkeydown 按键按下 onkeyup 按键松开
键盘事件一般都会绑定给一些可以获取到焦点(光标)的对象或者是document
比如说 input 绑定 onkeydown 输入框有光标时被才能被触发
键盘事件代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="text" name="zhh" id="inputId">
<script>
// 键盘事件
// 键盘事件最常用的就是 onkeydown 按键按下 onkeyup 按键松开
// 键盘事件一般都会绑定给一些可以获取到焦点(光标)的对象或者是document
// 比如说 input 绑定 onkeydown 输入框有光标时被才能被触发
let inputId = document.getElementById('inputId');
/*
* 可以通过keyCode来获取按键的编码
* 通过它可以判断哪个按键被按下
* 除了keyCode,事件对象中还提供了几个属性
* altKey
* ctrlKey
* shiftKey
* - 这个三个用来判断alt ctrl 和 shift是否被按下
* 如果按下则返回true,否则返回false
*/
// inputOnkeyDown();
docmentOnKeyDown();
function inputOnkeyDown()
// 给 input 绑定onkeydown事件
// input 绑定 onkeydown 输入框有光标时被才能被触发
inputId.onkeydown = function(event)
// 兼容ie8及以下
event = event || window.event;
console.log(event.keyCode);
// enter是13
if (event.keyCode === 13)
console.log('按键enter');
if (event.altKey)
console.log('按键alt');
if (event.ctrlKey)
console.log('按键ctrl');
if (event.shiftKey)
console.log('按键shift');
//判断enter和ctrl是否同时被按下
if (event.keyCode === 13 && event.ctrlKey)
console.log("ctrl和y都被按下了");
function docmentOnKeyDown()
// 给 docment 绑定onkeydown事件
// document 绑定 onkeydown 只要按键就能触发
document.onkeydown = function(event)
// 兼容ie8及以下
event = event || window.event;
console.log(event.keyCode);
//过滤掉数字
//数字 48 - 57
//使文本框中不能输入数字
if (event.keyCode >= 48 && event.keyCode <= 57)
//在文本框中输入内容,属于onkeydown的默认行为
//如果在onkeydown中取消了默认行为,则输入的内容,不会出现在文本框中
return false;
</script>
</body>
</html>
键盘事件 onkeydown onkeyup
键盘事件练习
按键键盘上的 上,下,左,右 实现方块的移动
效果图:
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
*
margin: 0px;
padding: 0px;
div
width: 100px;
height: 100px;
background-color: red;
position: absolute;
</style>
</head>
<body>
<div id="div">键盘事件</div>
<script>
// 练习 键盘移动 div
let div = document.getElementById('div');
// 设置一个加速器,减速器
let speed = 10;
document.onkeydown = function(event)
// 兼容ie8及以下
event = event || window.event;
// 按加号加速
if (event.keyCode == 187)
speed = 50;
// 按减号减速
if (event.keyCode == 189)
speed = 10;
// event.keyCode 37左 39右 38上40下
if (event.keyCode == 37)
div.style.left = div.offsetLeft - speed + 'px';
if (event.keyCode == 39)
div.style.left = div.offsetLeft + speed + 'px';
if (event.keyCode == 38)
div.style.top = div.offsetTop - speed + 'px';
if (event.keyCode == 40)
div.style.top = div.offsetTop + speed + 'px';
console.log(speed);
</script>
</body>
</html>
以上是关于web前端练习28----Dom4,事件(事件对象,事件冒泡,事件委派,事件传播,事件绑定,事件移除及案例练习)的主要内容,如果未能解决你的问题,请参考以下文章