小案例带你揭秘JS事件

### 什么是事件?
  • 在js中一个事件的组成由那些呢?

    • 谁触发事件:事件源
    • 触发什么事件: 事件的类型
    • 触发事件干什么事:事件处理函数

事件传播的过程

  • 捕获阶段

    • 就是从window事件处理函数开始,依次向内,只要事件目标的事件处理函数都会执行
    • 执行顺序是从上到下的函数执行顺序
  • 目标阶段
    • 你触发在哪个元素上那么这个事件的目标源就是谁
  • 冒泡阶段
    • 从事件目标的时间处理函数开始,依次向外,知道window的事件处理函数触发
    • 执行顺序是从内到外的

事件委托

  • 就是我们把要做的事情委托给别人做
  • 因为存在冒泡机制,点击子元素的时候,实际上也会同步触发父元素的相同事件
  • 所以我们可以把子元素的时间委托给父元素来监听

常见事件

  • 我们在写页面的时候经常用到的一些事件
  • 大致分为几类,浏览器事件 / 鼠标事件 / 键盘事件 / 表单事件 / 触摸事件
  • 不需要都记住,但是大概要知道

浏览器事件

  • load : 页面全部资源加载完毕
  • scroll : 浏览器滚动的时候触发
  • ...

鼠标事件

  • click :点击事件
  • dblclick :双击事件
  • contextmenu : 右键单击事件
  • mousedown :鼠标左键按下事件
  • mouseup :鼠标左键抬起事件
  • mousemove :鼠标移动
  • mouseover :鼠标移入事件
  • mouseout :鼠标移出事件
  • mouseenter :鼠标移入事件
  • mouseleave :鼠标移出事件
  • ...

键盘事件

  • keyup : 键盘抬起事件
  • keydown : 键盘按下事件
  • keypress : 键盘按下再抬起事件
  • ...

表单事件

  • change : 表单内容改变事件
  • input : 表单内容输入事件
  • submit : 表单提交事件
  • ...

触摸事件

  • touchstart : 触摸开始事件
  • touchend : 触摸结束事件
  • touchmove : 触摸移动事件
  • ...

事件案例

  • 鼠标坐标定位器
<!DOCTYPE html>
<!--
* @Descripttion:
* @version:
* @Author: 小小荧
* @Date: 2020-03-14 15:55:22
* @LastEditors: 小小荧
* @LastEditTime: 2020-03-14 16:08:19
-->
<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>
body {
margin: 0;
padding: 0;
}
div {
width: 100px;
height: 30px;
position: absolute;
bottom: 0;
left: 0;
border: 1px solid #eeeeee;
background-color: aqua;
box-sizing: border-box;
line-height: 30px;
text-align: center;
}
</style>
</head>
<body>
<div></div> <script> // 获得div盒子的节点
var div_ele = document.querySelector("div");
// 绑定鼠标移动事件
document.onmousemove = function( evt ){ // 处理兼容
var e = evt || event // 获取鼠标每次移动距离浏览器窗口左上角的坐标
var client_x = e.clientX; var client_y = e.clientY; div_ele.innerHTML = "x:" + client_x + " y:" + client_y;
} </script>
</body>
</html>

  • 模拟下拉菜单
<!DOCTYPE html>
<!--
* @Descripttion:
* @version:
* @Author: 小小荧
* @Date: 2020-03-10 21:26:28
* @LastEditors: 小小荧
* @LastEditTime: 2020-03-14 16:33:39
-->
<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>
body,
ul,
li {
margin: 0;
padding: 0;
} li {
list-style: none;
} .container {
width: 150px;
height: 30px;
margin: 30px auto;
} span {
display: block;
width: 150px;
height: 30px;
border: 1px solid black;
line-height: 30px;
} .list {
width: 150px;
height: 30px;
display: none;
} .list li {
width: 150px;
height: 30px;
border: 1px solid black;
border-top: none;
cursor: pointer;
} .list .active {
background: skyblue;
}
</style>
</head> <body>
<div class="container">
<span>请选择</span>
<ul class="list">
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
<li>Java</li>
<li>Python</li>
</ul>
</div>
<script> // 获取最外面大盒子的节点
var container = document.querySelector(".container"); // 获取菜单ul的节点
var list_ele = document.querySelector(".list"); // 获取菜单ul下面每一个li的节点
var li_eles = list_ele.querySelectorAll(".list li"); /*
给最外层的盒子添加事件监听
这里我们需要了解一下什么是事件委托
事件委托的含义就是把自己的时间交给别人来完成
*/
container.addEventListener("click", function (evt) { // 处理事件对象兼容 var e = evt || event; // 拿到事件源
var target = e.target || e.srcElement; // 判断事件源与我们点击的时间原是否一致
if (target.nodeName === "SPAN") { // 让一开始隐藏的节点显示
list_ele.style.display = "block"; // 获取该节点下面所有的子元素节点
li_eles = list_ele.children; // 循环遍历每一个节点为他们绑定事件
for (var i = 0; i < li_eles.length; i++) { // 绑定鼠标移入事件
li_eles[i].addEventListener("mouseover", function () { // 调用函数用来处理class类名 removeClassName(li_eles, "active"); this.className += "active"; }); // 为每一个li绑定点击事件每当点击每一个里的时候我们需要将给li里面的内容放入选择框中
li_eles[i].addEventListener("click", function () { target.innerHTML = this.innerHTML;
removeClassName(li_eles, "active");
list_ele.style.display = "none"; })
} } }); document.addEventListener("click", function () { list_ele.style.display = "none"; removeClassName(li_eles, "active"); }, true); /**
* 删除active的className的名字
*
*/
function removeClassName(eles, className) { // 循环遍历每个节点,取出每个class for (var i = 0; i < eles.length; i++) { var class_name = eles[i].className.split(" "); var active_index = class_name.indexOf(className); // 如果找到了就把那个active删除 if (active_index !== -1) { // 删除 class_name.splice(active_index, 1); // 删除之后我们在把处理好的值给拼接回去 eles[i].className = class_name.join(" "); } } } </script>
</body> </html>

  • 图片拖拽加回放
<!DOCTYPE html>
<!--
* @Descripttion:
* @version:
* @Author: 小小荧
* @Date: 2020-03-11 10:34:04
* @LastEditors: 小小荧
* @LastEditTime: 2020-03-14 17:05:27
-->
<html lang="en"> <head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
margin: 0;
padding: 0;
} #box {
width: 100px;
height: 100px;
background: teal;
position: absolute;
top: 0;
left: 0;
} #replay {
position: absolute;
right: 0;
top: 0;
}
</style>
</head> <body>
<div id="box"></div>
<button id="replay">回放</button>
<script>
(function () {
// 盒子 var box = document.getElementById("box"); // 回放按钮节点
var replay_btn = document.getElementById("replay"); var drag_start = false; // 第一次鼠标按下的时候鼠标相对于点击元素的x轴距离
var offset_x = null; // 第一次鼠标按下的时候鼠标相对于点击元素的y轴距离 var offset_y = null; // 拖拽盒子的宽度 var c_w_max = (document.body.clientWidth || document.documentElement.clientWidth) - box.offsetWidth; // 拖拽盒子的高度 var c_h_max = (document.body.clientHeight || document.documentElement.clientHeight) - box.offsetHeight; // 存储没鼠标移动是x和y轴的坐标 var replay_x_y_arr = []; // 鼠标按下事件
box.onmousedown = function (evt) {
var e = evt || event; drag_start = true;
// 鼠标点击的时候我们需要获取鼠标距离这个元素左上角的坐标 offset_x = e.offsetX; offset_y = e.offsetY; // 鼠标按下的时候我们需要降低一个坐标放入数组中记录 var replay_x = this.offsetLeft; var replay_y = this.offsetTop; replay_x_y_arr.push({ x: replay_x, y: replay_y });
}
document.onmousemove = function (evt) { var e = evt || event; if (drag_start === false) { return false; } var left_x = e.clientX - offset_x; var top_y = e.clientY - offset_y; left_x = left_x <= 0 ? 0 : left_x; left_x = left_x >= c_w_max ? c_w_max : left_x; top_y = top_y <= 0 ? 0 : top_y; top_y = top_y >= c_h_max ? c_h_max : top_y; // 每一次鼠标移动的时候我们把x和y的值放入数组中记录 // 记录的数字我们可以优化一下,让最后一个数字和当前的数字之前差距为5px的时候在去存储
if (Math.abs(left_x - replay_x_y_arr[replay_x_y_arr.length - 1].x) >= 5 || Math.abs(top_y - replay_x_y_arr[replay_x_y_arr.length - 1].y) >= 5) { replay_x_y_arr.push({ x: left_x, y: top_y });
} // 每一次拖动我们需要让盒子的位置发生变化 box.style.left = left_x + "px"; box.style.top = top_y + "px"; } box.onmouseup = function () {
drag_start = false;
} // 回放按钮的监听 var timer = null; replay_btn.addEventListener("click", function () { clearInterval(timer);
timer = setInterval(function () { // 将数组的最后一个元素取出
var item_val = replay_x_y_arr.pop(); // 然后分别把该对象的x值和y值分别设置给盒子的left和top
box.style.left = item_val.x + "px"; box.style.top = item_val.y + "px"; // 如果当数组为0的时候清空定时器
if (replay_x_y_arr.length === 0) {
clearInterval(timer);
} }, 50) });
})();
</script>
</body> </html>

  • 顺表提起一下一些常见的默认事件

    • a标签的点击会默认跳转地址事件
    • submit点击后表单会直接提交事件
    • contentmenu浏览器奶鼠标右键弹出浏览器菜单事件
  • 如何禁止这些默认事件
    • 非IE浏览器使用event.preventDefault();
    • IE浏览器使用event.returnValue = false;
  • 阻止默认事件的兼容写法
<a href="https://www.baidu.com">点击我试试</a>
<script>
var oA = document.querySelector('a') a.addEventListener('click', function (e) {
e = e || window.event console.log(this.href) e.preventDefault ? e.preventDefault() : e.returnValue = false
})
</script>

小案例带你揭秘JS事件的更多相关文章

  1. React.js入门小案例

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...

  2. node.js(小案例)_实现学生信息增删改

    一.前言 本节内容主要对小案例做一个总结: 1.如何开始搭建小项目 2.路由设计 3.模块应用 4.项目源码以及实现过程github地址: 项目演示如下: 二.主要内容 1.项目的关键性js源码: 项 ...

  3. react框架实现点击事件计数小案例

    下面将以一个小案例来讲解react的框架的一般应用,重点内容在代码段都有详细的解释,希望对大家有帮助 代码块: 代码块: import React from 'react'; import React ...

  4. JS小案例:循环间隔重复变色

    在A.B.C三个区块中,有且仅有一个红色,要求红色每隔一秒即进入下一个区块,变色过程不断循环往复. 参考代码: <!DOCTYPE html> <html lang="zh ...

  5. Vue.js小案例、生命周期函数及axios的使用

    一.调色框小案例: 随着三个滑动框的变化,颜色框的颜色随之改变 1.1.实例代码 <!DOCTYPE html> <html lang="en" xmlns:v- ...

  6. 关于js事件执行顺序小技巧

    js事件执行顺序是js中一个老生常谈的一个话题, 聊这个话题之前我们先谈谈怎么给页面元素绑定我们需要的事件 1.给页面元素绑定事件 a)直接在元素上面加上需要绑定的事件,如 <button ty ...

  7. JS高级---沙箱小案例

    沙箱小案例 substr截取, 从指定的字段开始截取 (function () { var str="小白喜欢小黑"; str=str.substr(2); console.log ...

  8. JS高级---闭包小案例

    闭包小案例 普通的函数 //普通的函数 function f1() { var num = 10; num++; return num; } console.log(f1()); //11 conso ...

  9. ch1-vuejs基础入门(hw v-bind v-if v-for v-on v-model 应用组件简介 小案例)

    1 hello world 引入vue.min.js 代码: ----2.0+版本 <div id="test"> {{str}} </div> <s ...

随机推荐

  1. css 进度条的文字根据进度渐变

    需求 1.进度条里面的文字需要根据进度的长度而变化 原理 用两个一模一样的样式的 div 重叠起来 效果 字体开始为 蓝色,跟随进度条变为 白色 在线预览: https://jsfiddle.net/ ...

  2. 【Amaple教程】6. 路由配置

    在 第1节<启动路由> 章节中为了能让单页应用顺利跑起来,我们提前介绍了简单的路由配置方法.我们已了解路由配置的目的是指定不同的url下对应的 模块节点(也叫做模块容器)内应该显示哪个模块 ...

  3. 大数据篇:ElasticSearch

    ElasticSearch ElasticSearch是什么 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口. ...

  4. windows7免费永久激活方法分享

    前言 我相信,这里肯定有看过我上一篇博客的同学. 我说了,为解决windows7激活问题,我会找一个比较好的方法. 首先先让大家看一看激活前windows7的计算机属性: 显示是未激活的.下面就是方法 ...

  5. 通过欧拉计划学Rust编程(第500题)

    由于研究Libra等数字货币编程技术的需要,学习了一段时间的Rust编程,一不小心刷题上瘾. "欧拉计划"的网址: https://projecteuler.net 英文如果不过关 ...

  6. ReentrantReadWriteLock 源码分析以及 AQS 共享锁 (二)

    前言 上一篇讲解了 AQS 的独占锁部分(参看:ReentrantLock 源码分析以及 AQS (一)),这一篇将介绍 AQS 的共享锁,以及基于共享锁实现读写锁分离的 ReentrantReadW ...

  7. JS的3种核心设计模式

    一.单例模式 1.保证一个类仅有一个实例,并提供一个访问它的全局访问点 2.设计思路:如果存在,不创建,直接返回,不存在才创建. 在类的constructor方法里添加一个判断条件属性,并且让创建的实 ...

  8. 使用 notepad 正则转换 字符串

    一..在一堆字符串中找出某一个特定格式的字符串,例如如下 需要摘出 WMID_abc WMID_def WMID_ghi {"abc",WMID_abc,oid_abc} {&qu ...

  9. kafka原理解析

    两张图读懂kafka应用: Kafka 中的术语 broker:中间的kafka cluster,存储消息,是由多个server组成的集群. topic:kafka给消息提供的分类方式.broker用 ...

  10. Java的反射基础技术

    今天本人给大家讲解一下Java的反射基础技术,如有不对的或者讲的不好的可以多多提出,我会进行相应的更改,先提前感谢提出意见的各位了!!! 什么是反射? 反射它是根据字节码文件可以反射出类的信息.字段. ...