Js中的事件、事件模型、事件对象


一、事件

  • 基本概念:
    (1). 什么是事件: 浏览器自动触发的或用户手动触发页面内容状态的改变。
    (2). 什么是事件属性: 每个元素上都有一批on开头的事件属性,每当事件发生时,浏览器会自动找到这些on开头的事件属性,触发提前绑定的处理函数。
    (3). 什么是事件处理函数: 当事件发生时,希望自动执行的函数
    (4). 什么是事件绑定: 提前将事件处理函数赋值给元素的事件属性保存起来。

  • 事件绑定: 3种方式:
    (1). 在HTML中: <元素 on事件名=”js语句”>
    问题: 不便于维护和重用
    (2). 在js中: 通过为事件属性赋值的方式
    元素对象.on事件名=function(){ … }
    问题: 一个元素的一个事件上只能绑定一个处理函数
    (3). 在js中: 通过添加事件监听对象的方式

    • 什么是事件监听对象: 一个保存了元素+事件+处理函数的一个对象。
    • 如何添加:
      元素对象.addEventListener(“事件名”, function(){ … })
    • 添加到哪儿去:
      浏览器中有一个事件监听对象的队列,addEventListener会将一个监听对象添加到监听对象队列中保存
    • 当事件发生时,如何触发事件处理函数:
      浏览器会遍历整个事件监听对象队列,找到元素+事件名都相符的监听对象,调用其保存的处理函数。
    • 移除事件监听对象:
      元素.removeEventListener(“事件名”,原处理函数)

      1.问题: 即使第二个参数写的和原函数一模一样,也无法删除处理函数
      2.因为function是创建新函数的意思。如果在移除时,又写了一遍function,则会新传感一个函数,而不是引用原函数。新函数和原函数地址不相同,所有,不是原函数,无法删除
      3.今后如果一个处理函数有可能被移除,则绑定时,不要用匿名函数,而要用有名称函数因为有名称的函数可随时找到。注意:不允许创建元素对象+事件名+处理函数完全相同的事件监听。

二、事件模型

  • 什么是事件模型: 从事件发生开始,到所有处理函数执行完毕所经历的过程。
  • 包括3个阶段:
    1.捕获: 由外向内,依次记录各级父元素上绑定的事件处理函数。但是,只记录,不执行
    2.目标触发: 优先触发目标元素上的事件处理函数,最初想点击的元素,就称为目标元素
    3.冒泡: 由内向外,依次触发捕获阶段记录的父元素上的处理函数
    事件模型

三、事件对象

  • 什么是事件对象: 当事件发生时,浏览器自动创建的封装事件信息的对象。
  • 何时使用事件对象: a. 获取事件信息 b. 修改事件的行为
  • 如何使用事件对象:
    a. 不用自己创建!而是在事件发生时,浏览器就自动创建了
    b. 获得: 事件对象永远作为事件处理函数的第一个参数默认传入!
    btn.onclick=function(e){ ... e就是事件对象 }

事件对象包含的功能

  1. 取消冒泡: e.stopPropagation();

  2. 事件委托/利用冒泡:
    优化: 尽量减少事件监听对象的个数 因为浏览器触发事件时,是从事件,数组中遍历查找符合条件的监听对象执行其处理函数。事件数组中监听对象的个数决定了遍历的时间长短。所以,要尽量减少事件数组中监听对象的个数,缩短遍历查找的时间。
    何时使用: 多个平级子元素都需要绑定一种事件时就要使用事件委托。
    如何使用事件委托:

    • 只要在父元素上绑定一次处理函数就好了。点击任何一个子元素,都会冒泡到父元素,触发父元素上公共的事件处理函数——也称为事件代理/事件委托。

    问题: this不能用了!因为事件绑定在父元素上,所以,当事件冒泡到父元素行执行时,this改为指向父元素,而不是子元素了。

    • 用e.target代替this,e.target始终保存目标元素,不随冒泡改变!

    问题:点除了按钮以外的其它子元素,甚至点父元素都会触发事件

    • 在使用e.target之前必须先判断e.target的特征是否想要的,比如: 元素名(nodeName全大写), class, …
  3. 阻止默认行为:

    • 个别元素在单击时或拖拽时,有默认行为,
      比如: <a href="#锚点地址">,单击这个a时,会自动修改地址栏中的内容,在url结尾添加”#锚点地址”,会干扰将来框架的路由
    • 有些默认行为我们不想要,就可用e.preventDefault() 阻止,比如:
    <a id="a1" href="#">空链接按钮</a>
    <script>
     a1.onclick=function(e){
       alert("hello"); //执行
       e.preventDefault(); //阻止添加url中的#
     }
    </script>
  4. 获取鼠标位置:
    1). 相对于屏幕左上角的坐标:
    e.screenX, e.screenY
    2). 相对于文档显示区左上角的坐标:
    e.clientX, e.clientY
    3). 相对于元素左上角的坐标
    e.offsetX, e.offsetY
    强调: e.offsetX或e.offsetY,可都是相对于事件现在绑定的元素左上角

  1. 页面滚动事件:
    1). 绑定页面滚动事件:
    window.onscroll=function(){ ... }
    2). 获得页面滚动过的距离:
    var scrollTop=document.body.scrollTop||document.documentElement.scrollTop
    3). 用程序主动滚动页面:
    window.scrollTo(水平方向滚动到, 垂直方向滚动到)
    window.scrollBy(水平方向滚动过, 垂直方向滚动过)

文章作者: Love--金哥哥
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Love--金哥哥 !
评论
 上一篇
正则表达式中的零宽断言 正则表达式中的零宽断言
前言在使用正则表达式时,有时我们需要捕获的内容前后必须是特定的内容,但又不捕获这些特定的内容,这个时候就要使用零宽断言了。零宽断言和它的名字一样,是一种零宽度的匹配,它匹配的内容不会保存到结果中去,最终匹配结果只是一个位置而已。零宽断言是给
2020-03-29
下一篇 
Js中深克隆与浅克隆的实现原理 Js中深克隆与浅克隆的实现原理
前言我们在项目开发中经常会遇到复制一个对象进行相关业务开发的情况,要求新对象和原来的对象一模一样,而开发时对对象进行操作又不能影响原对象。那么怎么实现呢?本文就带你研究一下克隆对象的实现与原理。 浅克隆概念是很枯燥的,我们用案例解释吧。 v
2020-03-26
  目录