小案例带你揭秘JS事件

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

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

事件传播的过程

  • 捕获阶段

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

事件委托

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

常见事件

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

浏览器事件

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

鼠标事件

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

键盘事件

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

表单事件

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

触摸事件

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

事件案例

  • 鼠标坐标定位器
  1. <!DOCTYPE html>
  2. <!--
  3. * @Descripttion:
  4. * @version:
  5. * @Author: 小小荧
  6. * @Date: 2020-03-14 15:55:22
  7. * @LastEditors: 小小荧
  8. * @LastEditTime: 2020-03-14 16:08:19
  9. -->
  10. <html lang="en">
  11. <head>
  12. <meta charset="UTF-8">
  13. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  14. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  15. <title>Document</title>
  16. <style>
  17. body {
  18. margin: 0;
  19. padding: 0;
  20. }
  21. div {
  22. width: 100px;
  23. height: 30px;
  24. position: absolute;
  25. bottom: 0;
  26. left: 0;
  27. border: 1px solid #eeeeee;
  28. background-color: aqua;
  29. box-sizing: border-box;
  30. line-height: 30px;
  31. text-align: center;
  32. }
  33. </style>
  34. </head>
  35. <body>
  36. <div></div>
  37. <script>
  38. // 获得div盒子的节点
  39. var div_ele = document.querySelector("div");
  40. // 绑定鼠标移动事件
  41. document.onmousemove = function( evt ){
  42. // 处理兼容
  43. var e = evt || event
  44. // 获取鼠标每次移动距离浏览器窗口左上角的坐标
  45. var client_x = e.clientX;
  46. var client_y = e.clientY;
  47. div_ele.innerHTML = "x:" + client_x + " y:" + client_y;
  48. }
  49. </script>
  50. </body>
  51. </html>

  • 模拟下拉菜单
  1. <!DOCTYPE html>
  2. <!--
  3. * @Descripttion:
  4. * @version:
  5. * @Author: 小小荧
  6. * @Date: 2020-03-10 21:26:28
  7. * @LastEditors: 小小荧
  8. * @LastEditTime: 2020-03-14 16:33:39
  9. -->
  10. <html lang="en">
  11. <head>
  12. <meta charset="UTF-8">
  13. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  14. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  15. <title>Document</title>
  16. <style>
  17. body,
  18. ul,
  19. li {
  20. margin: 0;
  21. padding: 0;
  22. }
  23. li {
  24. list-style: none;
  25. }
  26. .container {
  27. width: 150px;
  28. height: 30px;
  29. margin: 30px auto;
  30. }
  31. span {
  32. display: block;
  33. width: 150px;
  34. height: 30px;
  35. border: 1px solid black;
  36. line-height: 30px;
  37. }
  38. .list {
  39. width: 150px;
  40. height: 30px;
  41. display: none;
  42. }
  43. .list li {
  44. width: 150px;
  45. height: 30px;
  46. border: 1px solid black;
  47. border-top: none;
  48. cursor: pointer;
  49. }
  50. .list .active {
  51. background: skyblue;
  52. }
  53. </style>
  54. </head>
  55. <body>
  56. <div class="container">
  57. <span>请选择</span>
  58. <ul class="list">
  59. <li>HTML</li>
  60. <li>CSS</li>
  61. <li>JavaScript</li>
  62. <li>Java</li>
  63. <li>Python</li>
  64. </ul>
  65. </div>
  66. <script>
  67. // 获取最外面大盒子的节点
  68. var container = document.querySelector(".container");
  69. // 获取菜单ul的节点
  70. var list_ele = document.querySelector(".list");
  71. // 获取菜单ul下面每一个li的节点
  72. var li_eles = list_ele.querySelectorAll(".list li");
  73. /*
  74. 给最外层的盒子添加事件监听
  75. 这里我们需要了解一下什么是事件委托
  76. 事件委托的含义就是把自己的时间交给别人来完成
  77. */
  78. container.addEventListener("click", function (evt) {
  79. // 处理事件对象兼容
  80. var e = evt || event;
  81. // 拿到事件源
  82. var target = e.target || e.srcElement;
  83. // 判断事件源与我们点击的时间原是否一致
  84. if (target.nodeName === "SPAN") {
  85. // 让一开始隐藏的节点显示
  86. list_ele.style.display = "block";
  87. // 获取该节点下面所有的子元素节点
  88. li_eles = list_ele.children;
  89. // 循环遍历每一个节点为他们绑定事件
  90. for (var i = 0; i < li_eles.length; i++) {
  91. // 绑定鼠标移入事件
  92. li_eles[i].addEventListener("mouseover", function () {
  93. // 调用函数用来处理class类名
  94. removeClassName(li_eles, "active");
  95. this.className += "active";
  96. });
  97. // 为每一个li绑定点击事件每当点击每一个里的时候我们需要将给li里面的内容放入选择框中
  98. li_eles[i].addEventListener("click", function () {
  99. target.innerHTML = this.innerHTML;
  100. removeClassName(li_eles, "active");
  101. list_ele.style.display = "none";
  102. })
  103. }
  104. }
  105. });
  106. document.addEventListener("click", function () {
  107. list_ele.style.display = "none";
  108. removeClassName(li_eles, "active");
  109. }, true);
  110. /**
  111. * 删除active的className的名字
  112. *
  113. */
  114. function removeClassName(eles, className) {
  115. // 循环遍历每个节点,取出每个class
  116. for (var i = 0; i < eles.length; i++) {
  117. var class_name = eles[i].className.split(" ");
  118. var active_index = class_name.indexOf(className);
  119. // 如果找到了就把那个active删除
  120. if (active_index !== -1) {
  121. // 删除
  122. class_name.splice(active_index, 1);
  123. // 删除之后我们在把处理好的值给拼接回去
  124. eles[i].className = class_name.join(" ");
  125. }
  126. }
  127. }
  128. </script>
  129. </body>
  130. </html>

  • 图片拖拽加回放
  1. <!DOCTYPE html>
  2. <!--
  3. * @Descripttion:
  4. * @version:
  5. * @Author: 小小荧
  6. * @Date: 2020-03-11 10:34:04
  7. * @LastEditors: 小小荧
  8. * @LastEditTime: 2020-03-14 17:05:27
  9. -->
  10. <html lang="en">
  11. <head>
  12. <meta charset="UTF-8">
  13. <title>Title</title>
  14. <style>
  15. body {
  16. margin: 0;
  17. padding: 0;
  18. }
  19. #box {
  20. width: 100px;
  21. height: 100px;
  22. background: teal;
  23. position: absolute;
  24. top: 0;
  25. left: 0;
  26. }
  27. #replay {
  28. position: absolute;
  29. right: 0;
  30. top: 0;
  31. }
  32. </style>
  33. </head>
  34. <body>
  35. <div id="box"></div>
  36. <button id="replay">回放</button>
  37. <script>
  38. (function () {
  39. // 盒子
  40. var box = document.getElementById("box");
  41. // 回放按钮节点
  42. var replay_btn = document.getElementById("replay");
  43. var drag_start = false;
  44. // 第一次鼠标按下的时候鼠标相对于点击元素的x轴距离
  45. var offset_x = null;
  46. // 第一次鼠标按下的时候鼠标相对于点击元素的y轴距离
  47. var offset_y = null;
  48. // 拖拽盒子的宽度
  49. var c_w_max = (document.body.clientWidth || document.documentElement.clientWidth) - box.offsetWidth;
  50. // 拖拽盒子的高度
  51. var c_h_max = (document.body.clientHeight || document.documentElement.clientHeight) - box.offsetHeight;
  52. // 存储没鼠标移动是x和y轴的坐标
  53. var replay_x_y_arr = [];
  54. // 鼠标按下事件
  55. box.onmousedown = function (evt) {
  56. var e = evt || event;
  57. drag_start = true;
  58. // 鼠标点击的时候我们需要获取鼠标距离这个元素左上角的坐标
  59. offset_x = e.offsetX;
  60. offset_y = e.offsetY;
  61. // 鼠标按下的时候我们需要降低一个坐标放入数组中记录
  62. var replay_x = this.offsetLeft;
  63. var replay_y = this.offsetTop;
  64. replay_x_y_arr.push({ x: replay_x, y: replay_y });
  65. }
  66. document.onmousemove = function (evt) {
  67. var e = evt || event;
  68. if (drag_start === false) {
  69. return false;
  70. }
  71. var left_x = e.clientX - offset_x;
  72. var top_y = e.clientY - offset_y;
  73. left_x = left_x <= 0 ? 0 : left_x;
  74. left_x = left_x >= c_w_max ? c_w_max : left_x;
  75. top_y = top_y <= 0 ? 0 : top_y;
  76. top_y = top_y >= c_h_max ? c_h_max : top_y;
  77. // 每一次鼠标移动的时候我们把x和y的值放入数组中记录
  78. // 记录的数字我们可以优化一下,让最后一个数字和当前的数字之前差距为5px的时候在去存储
  79. 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) {
  80. replay_x_y_arr.push({ x: left_x, y: top_y });
  81. }
  82. // 每一次拖动我们需要让盒子的位置发生变化
  83. box.style.left = left_x + "px";
  84. box.style.top = top_y + "px";
  85. }
  86. box.onmouseup = function () {
  87. drag_start = false;
  88. }
  89. // 回放按钮的监听
  90. var timer = null;
  91. replay_btn.addEventListener("click", function () {
  92. clearInterval(timer);
  93. timer = setInterval(function () {
  94. // 将数组的最后一个元素取出
  95. var item_val = replay_x_y_arr.pop();
  96. // 然后分别把该对象的x值和y值分别设置给盒子的left和top
  97. box.style.left = item_val.x + "px";
  98. box.style.top = item_val.y + "px";
  99. // 如果当数组为0的时候清空定时器
  100. if (replay_x_y_arr.length === 0) {
  101. clearInterval(timer);
  102. }
  103. }, 50)
  104. });
  105. })();
  106. </script>
  107. </body>
  108. </html>

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

    • a标签的点击会默认跳转地址事件
    • submit点击后表单会直接提交事件
    • contentmenu浏览器奶鼠标右键弹出浏览器菜单事件
  • 如何禁止这些默认事件
    • 非IE浏览器使用event.preventDefault();
    • IE浏览器使用event.returnValue = false;
  • 阻止默认事件的兼容写法
  1. <a href="https://www.baidu.com">点击我试试</a>
  2. <script>
  3. var oA = document.querySelector('a')
  4. a.addEventListener('click', function (e) {
  5. e = e || window.event
  6. console.log(this.href)
  7. e.preventDefault ? e.preventDefault() : e.returnValue = false
  8. })
  9. </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. 微信小程序实战(一)之仿美丽说

    被美丽说少女粉吸引,就想着自己也写一个来练练手,正好最近在学习微信小程序.接下来让我们分享一下我的学习历程吧! 选题 其实纠结了好久该仿什么,看到别人都写的差不多了,自己却还没有动手,很着急,那两天一 ...

  2. fsLayuiPlugin数据表格动态转义

    数据表格动态转义提供一种更简洁的方式,主要解决前端laytpl模板转义的问题,对于一些简单的,例如:状态展示,我们可以通过前端编写laytpl模板来处理:对于动态的数据,通过这种静态方式是没有办法处理 ...

  3. vue+express+mysql项目总结(node项目部署阿里云通用)

    原文发布于我的个人博客上:原文点这里   前面经历千辛万苦,终于把博客的所有东西都准备好了,现在就只等部署了.下面我介绍下我的部署过程: 一.购买服务器和域名   如果需要域名(不用域名通过ip也可以 ...

  4. Jsp页面中动态的引入另一个jsp,jsp:include路径是变量的实现

    1 问题描述 在页面搭建时,会有这样的需求,希望局部页面动态的引用另一个jsp.这里的"动态"的意思引用的jsp的路径是个变量.举个例子,我们希望局部页面可能是page1.jsp或 ...

  5. [LeetCode] 994. Rotting Oranges 腐烂的橘子

    题目: 思路: 每个腐烂的橘子都能将自己上下左右的新鲜橘子传染,像极了现在的肺炎... 如果格子中只有一个腐烂的橘子,那么这便是一个典型的层次遍历,第一个传染多个,称为第二层,第二层传染第三层 但这里 ...

  6. JZOJ 5257. 小X的佛光 (Standard IO)

    5257. 小X的佛光 (Standard IO) Time Limits: 2000 ms Memory Limits: 524288 KB Description Input Output Sam ...

  7. C# BASS音频库 + 频谱基本用法

    效果图: 使用了 BASS.dll.  BASS.NET.dll   和  PeakMeterCtrl.dll 前面两个负责播放   最后一个负责绘制频谱,本文重点讲的是频谱部分,播放音频部分注意一点 ...

  8. php+apache 环境配置(window环境)

    最近,小主从事PHP开发.特将最近如何搭建php7的过程记录在此!希望有需要,可以借鉴!( 电脑必须win7 sp1以上, .netframework4 ) Windows7安装php7,Win7+p ...

  9. session、cookie和taken的区别

    http是无状态的协议,所以要维持应用的会话形式,就需要加入以下几种机制,来进行会话跟踪,识别用户身份(当同一用户进行多次操作,不用反复请求建立新的连接,从而节省服务器资源和处理速度)   生成位置 ...

  10. Collection-接口中的方法(新手)

    /* Collection 接口中的方法 ArrayList implements List 数组列表 实现 列表 List extends Collection 列表 继承 数组列表*///导入包. ...