JavaScript 高级事件学习案例
Posted GoldenaArcher
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript 高级事件学习案例相关的知识,希望对你有一定的参考价值。
javascript 高级事件学习案例
JavaScript 基础语法-dom-bom-js es6 新语法-jQuery-数据可视化 echarts 黑马程序员 pink 老师前端入门视频教程(500 多集课程) p247-262 的内容,包含了以下案例:
- 两种注册事件的方法
- 两种解绑事件的方法
- DOM 事件流
- 捕获事件
- 冒泡事件
- 阻止事件冒泡
- 事件委托
- 鼠标事件
- 键盘事件
案例 1 注册事件
以两个方法为主:element.oneventname = fn(){}
, eventTarget.addEventListener(type, listenerp, useCapture]);
, 还有一个 element.attachEvent()
作为兼容性的辅助方法,了解使用即可
源码:
<!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>传统注册时间</button><button>方法监听注册时间</button>
<script>
const btns = document.querySelectorAll("button");
btns[0].onclick = function () {
console.log("hi");
};
btns[0].onclick = function () {
console.log("how are u");
};
btns[1].addEventListener("click", function () {
console.log("hello it't me");
});
btns[1].addEventListener("click", function () {
console.log("hello from the other side");
});
</script>
</body>
</html>
案例 2 解绑事件
onevent
的解绑事件比较简单,在操作完成后将其设置为 null
即可。addEventListener
稍微麻烦一些,需要将方法提抽离出来,在方法体内用 removeEventListener
进行解绑。
效果图:
注意多次点击元素,控制台上只有一行输出,证明事件被激发了一次。
代码:
<!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>
div {
margin: 20px auto;
width: 50px;
height: 50px;
background-color: #eee;
}
</style>
</head>
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<script>
const divs = document.querySelectorAll("div");
divs[0].onclick = function () {
console.log("divs[0] registered once");
divs[0].onclick = null;
};
function fn() {
console.log("divs[1] registered once");
divs[1].removeEventListener("click", fn);
}
// 调用不需要加小括号
divs[1].addEventListener("click", fn);
</script>
</body>
</html>
案例 3 DOM 事件流
捕获阶段
从父元素向子元素流动的过程:
代码:
<!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>
.father {
box-sizing: border-box;
margin: 50px auto;
padding: 50px;
width: 200px;
height: 200px;
background-color: #aaa;
}
.child {
width: 100px;
height: 100px;
background-color: #eee;
}
</style>
</head>
<body>
<div class="father">
<div class="child"></div>
</div>
<script>
const child = document.querySelector(".child");
const father = document.querySelector(".father");
// 捕获阶段
child.addEventListener(
"click",
function () {
console.log("child");
},
true
);
// 捕获阶段2
father.addEventListener(
"click",
function () {
console.log("father");
},
true
);
</script>
</body>
</html>
冒泡阶段
从子元素向父元素流动的过程:
代码:
// 其余部分与上文一致,仅修改 JS 部分
// 冒泡阶段
child.addEventListener(
"click",
function (e) {
console.log("child");
},
false
);
// 冒泡阶段2
father.addEventListener(
"click",
function () {
console.log("father");
},
false
);
document.addEventListener(
"click",
function () {
console.log("document");
},
false
);
阻止事件冒泡
使用 event.strpPropagation
去阻止冒泡事件:
比起上面的冒泡时间只多了一行代码:
// 其他部分一样
child.addEventListener(
"click",
function (e) {
console.log("child");
// 阻止冒泡事件
e.stopPropagation();
},
false
);
// 其他部分一样
案例 4 事件委托
事件委托通俗意义上来说,就是利用事件冒泡,将事件绑定在父节点上,而非绑定每一个子元素,这样可以减少 DOM 的操作,对性能进行提升。
以一个推广为例,正常的推广会有一个图片,一段介绍,正常情况下来说,只要点击图片或是文字介绍都可以超链接转链到商品详情上去。这样的话,就可以直接在父元素上绑定 onclick 事件,而不用循环操作所有的子元素。
注意,事件委托中的 this
和 event
并不一定是一样的—— this
指的是绑定的元素,在下列情况下是 card
,而 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>
<style>
* {
margin: 0;
padding: 0;
}
.card {
height: 200px;
width: 150px;
margin: 80px;
border: 1px solid #000;
text-align: center;
}
.card:hover {
cursor: pointer;
}
.img {
width: 100%;
height: 150px;
background-color: gray;
background-image: linear-gradient(
transparent 50%,
rgba(255, 255, 255, 0.5) 50%
);
background-size: 50px 50px;
}
</style>
</head>
<body>
<div class="card">
<div class="img"></div>
<h3>假设标题</h3>
<p class="intro">假设介绍</p>
<script>
// this 和 event 是不一样的
const card = document.querySelector(".card");
card.addEventListener("click", function (e) {
console.log(e.srcElement);
console.log(this);
});
</script>
</div>
</body>
</html>
案例 5 鼠标事件
案例中使用
-
禁止选中内容(感觉好像某图书库,登录 VIP 才能用功能的那个)
-
禁止右键获取菜单
-
鼠标事件获取了当前视窗的位置,使图标可以悬浮跟随光标。这个功能用的还挺频繁的,例如说 放大镜 功能,可以在地图上用,很多商品图片上也会用到。
还有就是在地图上插入图标,例如说打卡啊,或者是设置途径地点之类的。
效果图:
代码实现:
<!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>
svg {
position: absolute;
}
</style>
</head>
<body>
<svg
t="1620258512730"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="2475"
width="50"
height="50"
>
<path
d="M224.128 155.498667C380.16 2.688 631.786667-0.490667 791.722667 147.712l8.149333 7.786667a394.176 394.176 0 0 1 0 565.589333L512 1002.944 224.128 721.066667a394.176 394.176 0 0 1 0-565.589334zM512 275.2a168.533333 168.533333 0 1 0 0 337.066667 168.533333 168.533333 0 0 0 0-337.066667z m0 64a104.533333 104.533333 0 1 1 0 209.066667 104.533333 104.533333 0 0 1 0-209.066667z"
fill="#717378"
p-id="2476"
></path>
</svg>
onclick,点击事件 onmouseover,鼠标经过触发 onmouseout,鼠标离开触发
onfocus,获得鼠标焦点触发 onblur,失去鼠标焦点触发 onmousemove,鼠标移动触发
onmouseup,鼠标弹起触发 onmousedown,鼠标按下触发
<script>
// 1. 禁止鼠标右键菜单
// 使用 contextmenu
document.addEventListener("contextmenu", function (e) {
e.preventDefault();
});
// 2. 禁止鼠标选中
// 使用 selectstart
document.addEventListener("selectstart", function (e) {
e.preventDefault();
});
// 3. 鼠标光标跟随
document.addEventListener("mousemove", function (e) {
const svg = document.querySelector("svg");
const { pageX, pageY } = e;
[svg.style.left, svg.style.top] = [
`${pageX - 25}px`,
`${pageY - 25}px`,
];
});
</script>
</body>
</html>
案例 6 键盘事件
模拟的一个快递单号查询功能,输入单号的时候上面会出现一个对话框,上面是放大的快递单号。当单号是空的时候,或者输入框失去焦点是,对话框会隐藏:
代码实现:
<!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>
.enlarged-package-id,
.enlarged-package-id::after,
input {
box-sizing: border-box;
}
.enlarged-package-id {
display: none;
position: absolute;
top: 70px;
left: 108px;
width: 175px;
border: 1px solid #ccc;
margin-bottom: 15px;
font-size: 20px;
}
/* credit: */
/* https://stackoverflow.com/questions/47318399/how-to-make-a-border-triangle-using-css */
.enlarged-package-id::after {
content: "";
width: 10px;
height: 10px;
position: absolute;
background-color: #fff;
bottom: -5px; /* half of the elements width/height */
left: 50%;
transform: translateX(-50%) rotate(45deg);
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
}
input {
margin: 100px;
border: 1px solid #ccc;
outline: none;
}
</style>
</head>
<body>
<div class="enlarged-package-id"JavaScript高级笔记