前端研习录(30)——JavaScript 事件讲解及示例分析
版权声明
- 本文原创作者:清风不渡
- 博客地址:https://blog.csdn.net/WXKKang
重拾前端记忆,记录学习笔记,现在进入JavaScript 事件部分
一、事件处理程序
事件处理程序分为以下三种:
- HTML事件处理
- DOM0级事件处理
- DOM2级事件处理
示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>清风不渡</title>
</head>
<body>
<button onclick="clickHandle()">HTML事件按钮</button>
<button id="btn">DOM0级按钮</button>
<button id="btn1">DOM2级按钮</button>
<script>
// HTML事件
function clickHandle() {
alert("点击了HTML事件按钮");
}
// DOM0级事件
var btn = document.getElementById("btn");
btn.onclick = function(){
alert("点击了DOM0级按钮A");
}
btn.onclick = function(){
alert("点击了DOM0级按钮B");
}
// DOM2级事件
var btn1 = document.getElementById("btn1")
btn1.addEventListener("click",click1);
btn1.addEventListener("click",click2);
btn1.removeEventListener("click",click3)
function click1() {
alert("第一次DOM2级事件");
}
function click2() {
alert("第二次DOM2级事件");
}
function click3() {
alert("第三次DOM2级事件");
}
</script>
</body>
</html>
效果如下,点击HTML事件按钮:
点击DOM0级按钮,可以看到“点击了DOM0级按钮A”提示并没有展示,如下:
点击DOM2级按钮,依次出现以下两种提示:
由此可以得出以下结论:
HTML事件的缺点:HTML与JS代码没有分开
DOM0级事件的优点:HTML与JS代码是分离的。缺点:存在多个事件会进行覆盖
DOM2级事件的优点:存在多个事件不会进行覆盖,会依次执行
二、鼠标事件
鼠标事件指与鼠标相关的事件,具体的事件列举如下:
- click:按下鼠标时触发
- dblclick:在同一个元素上双击鼠标时触发
- mousedown:按下鼠标键时触发
- mouseup:释放按下鼠标键时触发
- mousemove:当鼠标在节点内部移动时触发,当鼠标持续移动时,该事件会触发
- mouseenter:当鼠标进入一个节点时触发,进入子节点不会触发这个事件
- mouseleave:鼠标离开一个节点时触发,离开父节点不会触发这个事件
- mouseover:鼠标进入一个节点时触发,进入子节点时会再一次触发这个事件
- mouseout:鼠标离开一个节点时触发,离开父节点时也会触发这个事件
- wheel:滚动鼠标的滚轮时触发
注意:这些方法在使用的时候,除了DOM2级事件,都要添加on前缀
示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>清风不渡</title>
<style>
.box1{
width: 100px;
height: 100px;
background-color: aqua;
}
.box2{
width: 200px;
height: 200px;
background-color: antiquewhite;
margin-top: 30px;
}
</style>
</head>
<body>
<button id="btn1">单击</button>
<button id="btn2">双击</button>
<button id="btn3">按下</button>
<button id="btn4">释放</button>
<div id="box1" class="box1"></div>
<div id="root1" class="box2">
<div id="box2" class="box1"></div>
</div>
<div id="root2" class="box2">
<div id="box2" class="box1"></div>
</div>
<div id="root3" class="box2"></div>
<script>
var btn1 = document.getElementById("btn1");
var btn2 = document.getElementById("btn2");
var btn3 = document.getElementById("btn3");
var btn4 = document.getElementById("btn4");
var box1 = document.getElementById("box1");
var root1 = document.getElementById("root1");
var root2 = document.getElementById("root2");
var root3 = document.getElementById("root3");
btn1.onclick = function(){
console.log("鼠标单击打印");
}
btn2.ondblclick = function(){
console.log("鼠标双击打印");
}
btn3.onmousedown = function(){
console.log("鼠标按下打印");
}
btn4.onmouseup = function(){
console.log("鼠标释放打印");
}
box1.onmousemove = function(){
console.log("鼠标移动打印");
}
root1.addEventListener("mouseenter",enter1);
root1.addEventListener("mouseleave",leave1)
function enter1() {
console.log("鼠标进入打印A");
}
function leave1() {
console.log("鼠标离开打印A");
}
root2.addEventListener("mouseover",over1);
root2.addEventListener("mouseout",out1)
function over1() {
console.log("鼠标进入打印B");
}
function out1() {
console.log("鼠标离开打印B");
}
root3.onwheel = function(){
console.log("滑动滚轮");
}
</script>
</body>
</html>
三、Event事件对象
事件发生后,会产生一个事件对象,作为参数传递给监听函数,如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn1">单击按钮</button>
<script>
var btn1 = document.getElementById("btn1");
btn1.onclick = function(event){
console.log(event);
}
</script>
</body>
</html>
结果如下:
1、Event对象属性
(1)Event.target
Event.target 属性返回事件当前所在节点,示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn1">单击按钮</button>
<script>
var btn1 = document.getElementById("btn1");
btn1.onclick = function(event){
console.log(event.target);
}
</script>
</body>
</html>
结果如下:
(2)Event.type
Event.type属性返回一个字符串,表示事件类型,该属性只读,示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="btn1">单击按钮</button>
<script>
var btn1 = document.getElementById("btn1");
btn1.onclick = function(event){
console.log(event.type);
}
</script>
</body>
</html>
结果如下:
2、Event对象方法
(1)Event.preventDefault
Event.preventDefault 用于取消浏览器对当前事件的默认行为,示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<a href="https://www.baidu.com/" id="baidu">前往百度</a>
<script>
var baidu = document.getElementById("baidu");
baidu.onclick = function(event){
event.preventDefault();
console.log("点击了a标签");
}
</script>
</body>
</html>
结果如下,点击a标签不会进行页面跳转,且继续执行下面的js代码:
(2)Event.stopPropagation
Event.stopPropagation 方法用于阻止事件在DOM中继续传播,防止再触发定义在别的节点上的事件监听函数,但是不包括在当前节点其他的事件监听函数,示例如下:
如果没有使用Event.stopPropagation方法时:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.root{
width: 200px;
height: 200px;
background-color: bisque;
}
.box{
width: 100px;
height: 100px;
background-color: burlywood;
}
</style>
</head>
<body>
<div class="root" id="root">
<div class="box" id="box"></div>
</div>
<script>
var root = document.getElementById("root");
var box = document.getElementById("box");
root.onclick = function(){
console.log("点击了root");
}
box.onclick = function(){
console.log("点击了box");
}
</script>
</body>
</html>
结果如下,点击box会触发父节点root的监听函数:
使用Event.stopPropagation方法防止再触发定义在别的节点上的事件监听函数,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.root{
width: 200px;
height: 200px;
background-color: bisque;
}
.box{
width: 100px;
height: 100px;
background-color: burlywood;
}
</style>
</head>
<body>
<div class="root" id="root">
<div class="box" id="box"></div>
</div>
<script>
var root = document.getElementById("root");
var box = document.getElementById("box");
root.onclick = function(){
console.log("点击了root");
}
box.onclick = function(e){
e.stopPropagation();
console.log("点击了box");
}
</script>
</body>
</html>
结果如下,点击box只触发本节点的监听函数:
四、键盘事件
键盘事件由用户敲击键盘时触发,主要有一下三个事件:
- keydown 按下键盘时触发
- keypress 按下有值的键时触发
- keyup 松开键盘时触发
注意:对于keypress,按下Ctrl、Alt、Shift、Meta这样无值的键时不会触发;而对于有值的键,按下时先触发keydown事件,再触发这个事件
示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>清风不渡</title>
</head>
<body>
<input type="text" id="user">
<script>
var user = document.getElementById("user");
user.onkeydown = function (){
console.log("按下了键盘");
}
user.onkeypress = function(){
console.log("按下了有值的键");
}
user.onkeyup = function(e){
console.log("松开了键盘");
console.log("输入的内容是:"+e.target.value);
}
</script>
</body>
</html>
结果如下:
1、event对象
keyCode:唯一标识,可通过此属性判断按下了什么键,示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>清风不渡</title>
</head>
<body>
<input type="text" id="user">
<script>
var user = document.getElementById("user");
user.onkeydown = function (e){
console.log("按下了键盘");
if (e.keyCode === 13){
console.log("按下了回车");
}
}
</script>
</body>
</html>
在输入框敲击回车时,结果如下:
五、表单事件
表单事件是在使用表单元素及输入框元素可以监听的一系列事件
- input事件
- select事件
- Change事件
- reset事件
- submit事件
1、input事件
input事件 当<input>、<select>、<textarea>的值发生变化时触发。对于复选框<input type=“checkbox”>或单选框<input type=“radio”>,用户改变选项时,也会触发这个事件
input事件的一个特点就是可以连续触发,比如用户每按下一次按键,就会触发一次input事件
示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>清风不渡</title>
</head>
<body>
<input type="text" id="user">
<script>
var user = document.getElementById("user");
user.oninput = function (e) {
console.log(e.target.value);
}
</script>
</body>
</html>
结果如下:
2、select事件
select事件当在<input>、<textarea>里面选中文本时触发,示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>清风不渡</title>
</head>
<body>
<input type="text" id="user">
<script>
var user = document.getElementById("user");
user.onselect = function (e) {
console.log(e.target.value);
}
</script>
</body>
</html>
结果如下:
3、Change事件
Change事件 当<input>、<select>、<textarea>的值发生变化时触发。
它与input事件最大的不同,就是不会连续触发,只有当全部修改完成(失去焦点)时才会触发
示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>清风不渡</title>
</head>
<body>
<input type="text" id="user">
<script>
var user = document.getElementById("user");
user.onchange = function (e) {
console.log(e.target.value);
}
</script>
</body>
</html>
结果如下:
4、reset事件和submit事件
这两个事件发生在表单对象<form>上,而不是发生在表单成员上
reset事件当表单重置(所有表单成员变回默认值)时触发
submit事件当表单数据向服务器提交时触发。
注意:submit事件的发生对象是<form>元素,而不是<button>元素,因为提交的是表单,而不是按钮
示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>清风不渡</title>
</head>
<body>
<form id="myForm">
<input type="text" name="user">
<button id="resetBtn">重置</button>
<button>提交</button>
</form>
<script>
var myForm = document.getElementById("myForm");
var resetBtn = document.getElementById("resetBtn");
resetBtn.onclick = function (){
myForm.reset();
}
</script>
</body>
</html>
六、事件代理
由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理(delegation)
事件会在冒泡阶段向上传播到父节点,示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>清风不渡</title>
</head>
<body>
<ul id="list">
<li>列表一</li>
<li>列表二</li>
</ul>
<script>
var list = document.getElementById("list");
list.onclick = function(){
console.log("list点击事件");
}
</script>
</body>
</html>
结果如下,我们点击<li>标签时会触发父节点的点击事件:
所以如果当我们需要给父元素下的子元素添加监听函数时,可以利用这个特性,而不用一个个的去对子元素添加监听函数,示例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>清风不渡</title>
</head>
<body>
<ul id="list">
<li>列表一</li>
<li>列表二</li>
<p>p标签</p>
</ul>
<script>
var list = document.getElementById("list");
list.onclick = function(e){
if (e.target.tagName === "LI"){
console.log("点击了li标签");
}else{
console.log("点击的不是li标签");
}
}
</script>
</body>
</html>
结果如下:
也可以通过toLowerCase()转化为小写进行判断:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>清风不渡</title>
</head>
<body>
<ul id="list">
<li>列表一</li>
<li>列表二</li>
<p>p标签</p>
</ul>
<script>
var list = document.getElementById("list");
list.onclick = function(e){
if (e.target.tagName.toLowerCase() === "li"){
console.log(e.target.innerHTML);
console.log("点击了li标签");
}else{
console.log("点击的不是li标签");
}
}
</script>
</body>
</html>