事件

事件:浏览器赋予元素的默认行为,可以理解为事件是天生具备的。不论是否为其绑定方法,当某些行为触发的时候,相关的事件都会被触发执行。
事件绑定:给元素默认的事件行为绑定方法,这样在行为触发的时候才会执行绑定的方法。
document.body.onclick=function (){}; 大部分人:给body绑定一个点击事件 标准:给body的点击事件行为绑定方法

浏览器常用的事件行为

-1)鼠标事件

  • 元素.onclick=function(){} 单击(移动端:300ms内没触发第二次,所以click在移动端有300ms延迟);点击(PC端)
  • 元素.oncontextmenu=function(){}右键点击
  • 元素.ondblclick=function(){} 双击,大约300ms内连续点击两次
  • 元素.onmouseenter=function(){}鼠标移入,进入子节点不会触发这个事件
  • 元素.onmouseleave=function(){}鼠标移出,进入子节点不会触发这个事件
  • 元素onmouseover=function(){}鼠标滑过,进入子节点会触发这个事件
  • 元素.onmouseout=function(){}鼠标滑出,进入子节点会触发这个事件
  • 元素.onmousemove=function(){}鼠标滑动,只要鼠标动就会触发
  • 元素.onmousedown=function(){}鼠标按下
  • 元素.onmouseup=function(){}鼠标抬起
  • 元素.onwheel=function(){}滚轮滚动

    思考:如何让按钮单击和双击做不同的事情

    1. let btn=document.querySelector('.two');
    2. btn.onclick=function(){
    3. // 鼠标点击第一次的时候,先不着急执行单击函数 等一会 看是否点击了第二下
    4. // 如果点击了第二下,就自动触发了双击,这样就不执行对应的代码了
    5. clearTimeout(this.timer);
    6. this.dbl=false;
    7. this.timer=setTimeout(() => {
    8. if(this.dbl)return;
    9. console.log('单击'); //单击业务
    10. }, 300);
    11. };
    12. btn.ondblclick=function(){
    13. this.dbl=true;
    14. console.log('双击');
    15. };

    mouseover和mouseenter的区别

    over和out是忽略元素之间的层级关系,只看鼠标在哪个元素显示的范围上,存在事件冒泡
    image.png
    enter和leave会受到元素之间的层级关系,默认阻止了事件冒泡机制

    image.png

    image.png

    键盘事件

  • 元素.onkeydown=function(){}键盘按下,所有键都行

  • 元素.onkeyup=function(){}键盘抬起
  • 上面元素有限制:input textarea document document.body document.documentElement window
  • 元素.onkeypress=function(){} 长按(Shift/Fn/CapsLock)一些系统键监听不到 不建议用

    键盘事件对象

    image.png
    image.png

    表单事件

  • input.onfocus=function(){}获取光标时触发

  • input.onblur=function(){}失去焦点时触发
  • input.onchange=function(){}内容改变并且失焦
  • input.oninput=function(){}只要内容改变就会触发
  • submit表单提交(前提:表单元素都包含在form中,并且点击的按钮是 submit)
  • reset表单重置
  • select下拉框内容选中

    this.value代表输入的内容

系统常用事件

  • window.onload=function(){}页面资源全部加载完

    • $(document).ready() jQuery里的ready事件 原生没有
    • ready和load区别:ready是页面DOM结构加载完成就会触发,比load触发早
  • window.onresize=function(){}可视窗口发生改变时

  • document.body.onscroll=function(){}滚动条监听
  • window.onscroll=function(){}

移动端常用事件

单手指事件 Touch Event

  • 元素.ontouchstart=function(){} 触碰到元素触发 【手指碰到屏幕】
  • 元素.ontouchend=function(){}离开元素触发 【手指离开屏幕】
  • 元素.ontouchmove=function(){} 手指移动
  • 元素.onclick=function(){} 单击大约300ms延迟 在移动端用的比较少

    手指事件对象

    changedTouches / targetTouches / touches都是记录手指信息的,平时用的多的是changedTouches
    手指按下、移动、离开屏幕 changedTouches都存储了对应的手指信息,哪怕离开屏幕后,存储的也是最后一次手指在屏幕 中的信息;而 touches在手指离开屏幕后,就没有任何的信息了;=>获取的结果都是一个 TouchList集合,记录每一根手指的信息;
    image.png

    css3动画事件(了解)

  • transitionend transition动画结束

  • transitionstart transition动画开始
  • transitionrun transition动画运行中

事件对象

1、定义:

  • 给元素的事件行为绑定方法,当事件行为触发方法会被执行,不仅被执行,而且还会把当前操作的相关信息传递给这个函数 =>传递过来相关信息就叫做事件对象

    事件对象是由事件当前本身产生的,和执行什么函数没有关系

2、原理:

事件对象和函数以及给谁绑定的事件没啥必然关系,它存储的是当前本次操作的相关信息,操作一次只能有一份信息,所以在哪个方法中获取的信息都是一样的;第二次操作,存储的信息会把上一次操作存储的信息替换掉…;

  • 每一次事件触发,浏览器都会这样处理一下:
    • 1.捕获到当前操作的行为(把操作信息获取到),通过创建MouseEvent等类的实例,得到事件对象EV
    • 2.通知所有绑定的方法(符合执行条件的)开始执行,并且把EV当做实参传递给每个方法,所以在每个方法中得到的事件对象其实是一个
    • 3.后面再重新触发这个事件行为,会重新获取本次操作的信息,用新的信息替换老的信息,然后继续之前的步骤…

      3、事件对象类型

      -1)鼠标事件对象

      如果是鼠标操作,获取的是MouseEvent类的实例(这个实例就是 =>鼠标事件对象)

  1. var box = document.getElementsByClassName('box')[0];
  2. box.onclick = function (e) {
  3. //e 我们一般称为事件对象
  4. //里面存储了事件的信息
  5. e = e || window.event;
  6. var tar = e.target || e.srcElement;
  7. console.log(e);
  8. }

image.pngimage.png

  • 原型链:
    • 鼠标事件对象 -> MouseEvent.prototype -> UIEvent.prototype -> Event.prototype -> Object.prototype
  • 常用属性:
    • clientX/clientY:当前鼠标触发点距离当前窗口左上角的X/Y轴坐标
    • pageX/pageY:触发点距离当前页面左上角的X/Y轴坐标

day25-DOM事件 - 图10

-2)键盘事件对象

如果是键盘操作,获取的是KeyboardEvent类的实例 =>键盘事件对象

  • 常用属性:
    • code & key:存储的都是按键,code更细致
    • keyCode & which:存储的是键盘按键对应的码值
  • 键盘常用码值:
    • 方向键:37 38 39 40 =>左上右下
    • 空格SPACE:32
    • 回车ENTER:13
    • 回退BACK:8
    • 删除DEL:46
    • SHIFT:16
    • CTRL:17
    • ALT:18

window键盘码值:
day25-DOM事件 - 图11苹果键盘码值:day25-DOM事件 - 图12

-2)除了以上还有:

  • 普通事件对象(Event)、
  • 手指事件对象(TouchEvent)等

    4、事件对象event的属性

    除了上面,只有鼠标和键盘中有的属性外,还有一些公共的所有事件对象都有的属性

  • type:触发事件的类型

  • target:事件源(操作的是哪个元素,哪个元素就是事件源)
    • 在不兼容的浏览器中可以使用srcElement获取,也代表的是事件源
  • preventDefault():用来阻止默认行为的方法
    • 不兼容的浏览器中用ev.returnValue=false也可以阻止默认行为
  • stopPropagation():阻止冒泡传播
    • 不兼容的浏览器中用ev.cancelBubble=true也可以阻止默认行为

阻止默认事件

a标签、onkeydown、ontouchmove 、右键菜单 有默认事件

  • e.preventDefault();//阻止默认事件
  • e.returnValue=false; 兼容IE
  • return false

    需求:点击右键不出现系统菜单,出现自定义菜单

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Document</title>
    8. <style>
    9. * {
    10. margin: 0;
    11. padding: 0;
    12. }
    13. #box {
    14. position: relative;
    15. left: 0px;
    16. top: 0px;
    17. width: 100px;
    18. height: 100px;
    19. background: lightcoral;
    20. transition: all ease;
    21. }
    22. .menu {
    23. position: fixed;
    24. display: none;
    25. width: 50px;
    26. height: 200px;
    27. background-color: lightcoral;
    28. }
    29. ul {
    30. list-style: none;
    31. text-align: center;
    32. }
    33. </style>
    34. </head>
    35. <body>
    36. <div id="box">
    37. <div class="menu">
    38. <ul>
    39. <li>确定</li>
    40. <li>打印</li>
    41. </ul>
    42. </div>
    43. </div>
    44. <script>
    45. let menuDiv = document.querySelector('#box .menu');
    46. console.log(menuDiv);
    47. window.oncontextmenu = function (e) {
    48. e.preventDefault();
    49. let left = e.clientX,
    50. top = e.clientY;
    51. // 拿到鼠标的点击位置 把点击的位置信息给menuDiv
    52. menuDiv.style.left = left + 'px';
    53. menuDiv.style.top = top + 'px';
    54. menuDiv.style.display = 'block';
    55. };
    56. window.onclick = function () {
    57. menuDiv.style.display = 'none';
    58. };
    59. </script>
    60. </body>
    61. </html>

    事件传播机制

    在点击事件时,浏览器会首先从外往里捕获,找到点击的元素,这个阶段称为 捕获阶段 。 捕获完后,会从里往外执行点击事件,这个阶段叫做 冒泡阶段 总的来说,捕获触发的是从外向里触发事件 冒泡触发是从里向外触发事件 且捕获比冒泡阶段先执行

阻止冒泡

e.stopPropagation();//阻止冒泡 e.cancelBubble=true;//兼容

事件委托

  • 通过点击子级元素来触发父级元素的事件
  • 利用事件源e.target||e.srcElment来获取点击的元素
    var ul = document.getElementsByTagName('ul')[0];
      ul.onclick = function (e) {
          e = e || window.event
          var tar = e.target || e.srcElement
          console.log(tar.innerText)
      }
    

    2级事件绑定

    零级事件绑定只能绑定一个事件(函数),2级事件绑定可在0级的基础上绑定多个
    btn.addEventListener('click',fn1,false)
    //参数1是事件类型,参数2是要执行的函数
    //参数3只有true和false
    //true代表函数要在事件捕获阶段触发
    //false代表函数要在事件冒泡阶段触发
    btn.removeEventListener('click',fn1,false)
    //移除
    //IE低版本
    //this是window
    btn.attachEvent('onclick',fn1)
    //都是在冒泡阶段触发
    btn.detachEvent('onclick',fn1)
    //移除
    

    HTML禁止事件

    oncontextmenu='return false'//禁止右键
    ondragstart='return false' 
    onselectstart ='return false' //禁止选中
    onselect='document.selection.empty()' //把选中的内容清空
    oncopy='document.selection.empty()' //把选中的内容清空
    onbeforecopy='return false' 
    onmouseup='document.selection.empty()'