浏览器事件之事件处理程序

更新日期: 2020-02-19阅读: 2.3k标签: 事件

介绍

事件是用户或浏览器自身执行的某种行动(如click、mousemove等)。而处理对应事件的程序称为事件处理程序(或事件监听器)。


html事件处理程序

通过在HTML标签中设置与相应事件处理程序同名的属性来指定事件处理程序的方法被称之为 HTML事件处理程序。如下面这段代码

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <button onclick="alert('click button1')">click1</button>
    <button onclick="handleButtonClick()">click2</button>
  </body>
  <script>
    function handleButtonClick() {
      alert('click button2');
    }
  </script>
</html>

在 HTML 中定义的事件处理程序可以包含要执行的具体动作,也可以调用在页面其他地方定义的脚本。就这个例子来说“click1”按钮就在标签中包含了具体的执行动作。而“click2”按钮的事件处理函数则放在了下方的<script>标签中。


dom0级事件处理程序

在JavaScript代码中通过将一个函数赋值给一个事件处理程序属性来指定事件处理程序的方法被称之为DOM0级事件处理程序
在指定事件处理函数前,要先获得一个操作对象的引用,如下面这段代码:

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <button id="myBtn">click</button>
  </body>
  <script>
    document.getElementById('myBtn').onclick = function(ev) {
      alert('click myBtn');
    };
  </script>
</html>

上方例子中我们通过文档对象取得了一个按钮的引用,然后为它指定了onclick事件处理程序。但要注意,在这些代码运行以前不会指定事件处理程序,因此如果这些代码在页面中位于按钮后面,就有可能在一段时间内怎么单击都没有反应。

使用DOM0级方法指定的事件处理程序被认为是元素的方法。所以在这个时候事件处理函数的作用域是在元素中,也就是说元素中的this是指向的该元素。

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <button id="myBtn">click</button>
  </body>
  <script>
    var myBtn = document.getElementById('myBtn');
    myBtn.onclick = function(ev) {
      alert(myBtn.isEqualNode(this)); // true
    };
  </script>
</html>

不仅能通过DOM0级方法指定事件处理函数,也能通过DOM0级方法删除事件处理程序,只需将事件处理程序属性的值设为null即可:

myBtn.onclick = null;

使用DOM0级事件处理程序存在许多缺点如:

  • 存在时差问题。因为用户可能会在HTML元素一出现在页面上就触发相应的事件,但当时的事件处理程序有可能尚不具备执行条件。
  • 扩展事件处理程序的作用域链在不同浏览器中会导致不同结果。不同JavaScript引擎遵循的标识符解析规则略有差异,很可能会在访问非限定对象成员时出错。
  • HTML与JavaScript代码紧密耦合。如果要更换事 件处理程序,就要改动两个地方:HTML代码和JavaScript代码。

    ......


DOM2级事件处理程序

DOM2级事件包含了两种方法用于增加和删除事件处理程序,分别为addEventListener()、removeEventListener()。

它们都接受三个参数:

  1. 事件名,如“click”(注意: 不是“onclick”)
  2. 事件处理函数
  3. 是否在捕获阶段调用事件处理程序,如果为true则在捕获阶段调用事件处理程序,否则在冒泡阶段调用事件处理程序
<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <button id="myBtn">click</button>
  </body>
  <script>
    var myBtn = document.getElementById('myBtn');
    myBtn.addEventListener(
      'click',
      function(ev) {
        alert(1);
      },
      false
    );
  </script>
</html>

上面的代码为一个按钮添加了onclick事件处理程序,而且该事件会在冒泡阶段被触发(因为最后一个参数是false)。与DOM0级方法一样,这里添加的事件处理程序也是在其依附的元素的作用域中运行。使用DOM2级方法添加事件处理程序的主要好处是可以添加多个事件处理程序。看下面的例子:

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <button id="myBtn">click</button>
  </body>
  <script>
    var myBtn = document.getElementById('myBtn');
    myBtn.addEventListener(
      'click',
      function(ev) {
        alert(1);
      },
      false
    );
    myBtn.addEventListener(
      'click',
      function(ev) {
        alert(2);
      },
      false
    );
  </script>
</html>

这里为按钮指定了两个事件处理程序,运行上面的例子,浏览器会先后弹出1和2。

若想使用removeEventListener()删除事件处理程序,则需先指定要删除的事件名,再指定函数名(注意:若在元素指定事件时是使用的匿名函数,是无法被删除的),最后指定处理阶段。看看下面的例子:

<!DOCTYPE html>
<html>
  <head></head>
  <body>
    <button id="myBtn">click</button>
  </body>
  <script>
    var myBtn = document.getElementById('myBtn');
    function handleBtnClick() {
      alert(2);
    }
    // 匿名函数
    myBtn.addEventListener(
      'click',
      function(ev) {
        alert(1);
      },
      false
    );
    // 具名函数
    myBtn.addEventListener('click', handleBtnClick, false);
    // 无效
    myBtn.removeEventListener(
      'click',
      function(ev) {
        alert(1);
      },
      false
    );
    // 有效
    myBtn.removeEventListener('click', handleBtnClick, false);
  </script>
</html>
大多数情况下,都是将事件处理程序添加到事件流的冒泡阶段,这样可以最大限度地兼容各种浏览器。最好只在需要在事件到达目标之前截获它的时候将事件处理程序添加到捕获阶段。如果不是特别需要,我们不建议在事件捕获阶段注册事件处理程序。


IE事件处理程序

IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。这两个方法接受相同的两个参数:事件处理程序名称与事件处理程序函数。由于IE8及更早版本只支持事件冒泡,所以通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段。

var btn = document.getElementById("myBtn");
btn.attachEvent("onclick", function(){ alert("Clicked"); });
attachEvent()的第一个参数是"onclick",而非DOM的addEventListener()方法中的"click"。

在IE中使用attachEvent()与使用DOM0级方法的主要区别在于事件处理程序的作用域。在使用DOM0级方法的情况下,事件处理程序会在其所属元素的作用域内运行。在使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,因此this等于window。


跨浏览器的事件处理程序

若想兼容DOM0级事件处理程序、DOM2级事件处理程序以及IE事件处理程序。可使用下面的方法进行封装和调用:

var EventUtil = {
    addHandler: function(element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent('on' + type, handler);
        } else {
            element['on' + type] = handler;
        }
    },
    removeHandler: function(element, type, handler) {
        if (element.removeEventListener) {
            element.removeEventListener(type, handler, false);
        } else if (element.detachEvent) {
            element.detachEvent('on' + type, handler);
        } else {
            element['on' + type] = null;
        }
    },
};


链接: https://www.fly63.com/article/detial/8306

js中addEventListener事件监听器参数详解

我们都知道addEventListener() 的参数约定是:useCapture是可选参数,默认值为false,目前DOM 规范做了修订:addEventListener() 的第三个参数可以是个对象值了。passive就是告诉浏览器我可不可以用stopPropagation...

js监听浏览器返回,pushState,popstate 事件,window.history对象

在WebApp或浏览器中,会有点击返回、后退、上一页等按钮实现自己的关闭页面、调整到指定页面、确认离开页面或执行一些其它操作的需求。可以使用 popstate 事件进行监听返回、后退、上一页操作。

CSS中的pointer-events属性实现点穿效果

具有层级关系的结构中,使用了pointer-events:none 属性将会使当前元素中的事件不会被捕获,从而实现了点穿的效果。而当代码示例中假如top元素具有子元素且显示指定pointer-events属性不为none的时候,top元素注册的事件将会被捕获/冒泡触发

js鼠标事件参数,获取鼠标在网页中的坐标

事件对象 event,JavaScript 将事件event作为参数传递,IE中把 event 事件对象作为全局对象 window 的一个属性,获取鼠标在网页中的坐标 = 鼠标在视窗中的坐标 + 浏览器滚动条坐标

js事件冒泡和默认事件处理(原生js、vue)

何为默认事件?比如 a 会跳转页面,submit 会提交表单等。普通js方法:e.preventDefault()函数。Vue.js方法: .prevent 是vue 的内置修饰符,调用了 event.preventDefault()阻止默认事件

js keyup、keypress和keydown事件 详解

js keyup、keypress和keydown事件都是有关于键盘的事件,当一个按键被pressed 或released在每一个现代浏览器中,都可能有三种客户端事件。

深入nodejs-核心模块Events详解(事件驱动)

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O的模型,使其轻量又高效。比如,文件操作中的fs事件流,网络编程所用到的tcp,http模块等,当你回想自己写的程序后,会发现很多操作都基于事件驱动,Events类。

纯CSS实现点击事件展现隐藏div菜单列表/元素切换

在写移动端导航的时候经常用到点击按钮出现/隐藏导航条的情况,最常见的方法当然还是前端框架直接调用,省心省力,不易出错;当然还有使用纯JS实现的小代码段。我这里整理了纯CSS实现方式,给需要的人和给自己做个笔记:实现原理利用CSS伪类:target

关于鼠标移动太快导致moseleave事件不触发的问题

我做的是一个table的编辑功能,当移入某行的时候展示编辑状态,在移出某行的时候显示的是原始状态,此时遇到一种情况,就是.当mousenter事件触发之后,由于鼠标移动得太快,同一个tr上绑定的mouseleave事件压根儿就没有执行。

Js事件传播流程

js事件传播流程主要分三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。在我们平常用的addEventListener方法中,一般只会用到两个参数,一个是需要绑定的事件,另一个是触发事件后要执行的函数

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!