JS DOM基础 事件概述 事件流 事件处理方法 添加监听器 事件类型 事件对象 事件委托

一、事件概述

  事件是什么?

    在我们的生活中,都会接触到事件这样一个概念,它通常通过描述发生这件事的时间、地点、人物,发生了什么来进行概括。

    同样的在javascript也有这样的一个的东西------事件。

    页面上发生的事件:鼠标移动、点击、滚动等等。

    事件描述了页面上发生的事情,通常它有以下三个要素组成:

        事件源:触发事件的元素

        事件类型:事件的触发方式(例如鼠标点击或键盘点击)

        事件处理程序(事件监听器):事件触发后要执行的代码(函数形式)

    Javascript 使我们可以动态的去操作一个页面。当我们在与浏览器交互的时候,浏览器就会触发各种事件。

    比如我们打开某一个网页的时候,浏览器需要加载完成这个网页,就会触发一个加载事件;当我们点击页面中的某一个“地方”,浏览器就会在那个“地方”触发一个点击事件。

二、事件流

  什么是事件流?

    DOM(文档对象模型)结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素结点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程、这种问题的处理方式可以称之为事件流即事件的传播机制。对于事件流IE跟FF有不同的解释。

    IE下的解决方案称之为:冒泡型事件,从里向外

    而FF下称之为:捕获型事件,从外向里。

    冒泡型事件是从低而上的触发机制,而捕获型事件则是从上到下的触发机制。

       事件冒泡:事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的结点(文档),即沿着DOM树向上传播。
       事件捕获:不太具体的节点(document)应该更早接收到事件,最具体的节点最后接收到事件,即沿着DOM树向下传播。
 

    DOM同时支持这两种事件模型:捕获型事件和冒泡型事件,并且把事件流分为了三个阶段:

       事件捕获阶段,处于目标阶段,事件冒泡阶段。

    处于目标阶段时(中间阶段)的事件触发顺序,和事件的声明顺序有关,先声明的先触发,一般不怎么关注前两个阶段,默认冒泡阶段dom0。

 

三、事件处理方法

  事件的绑定、添加监听器

    要使用事件,首先我们需要绑定事件。

  DOM0级提供了两种事件绑定方案:

    事件绑定在html标签上:

<input type="button" onclick="doit()" value="test">  //onclick="doit()",内嵌式,鼠标点击,调用函数 doit
<script> function doit() {alert("html绑定");} </script>

注:将js与html合并在一起,没有实现分离,违背了结构、样式、行为分离的要求,不推荐。

  但有时候这样子很方便或者需要,也可以用。

    函数绑定:

<input id='inputBtn' type="button" value="test">

<script>

let btn = document.getElementById('inputBtn’);

btn.onclick = function () {alert('函数绑定');} //可以通过btn.onclick = null;的方式 删除
</script>

注:兼容性很好,但是只能绑定一个监听处理函数。

    DOM2级新增了一种事件绑定方案:

      通过方法addEventListener():

<input id='inputBtn' type="button" value="test">

<script>

let btn = document.getElementById('inputBtn’);

btn.addEventListener('click', function () {alert('addEventListener方法');});

</script>

注:兼容性相对稍差,但是可以绑定多个事件函数。

  • 使用addEventListener(type, listener, useCapture)来注册事件的时候,第三个参数默认为false,代表事件捕获方式为冒泡

  • 使用.stopPropagation()可以阻断事件的传播,当为事件捕获时,阻断事件向下传播,当为事件冒泡时,阻断事件向上传播

  • .preventDefault()是用来阻止DOM元素默认的事件的,比如a标签的跳转动作,表单button的提交动作,与事件传播没关系

  .stopImmediatePropagation方法作用在当前节点以及所有后续节点上,在执行完当前事件处理程序之后,停止当前节点以及所有后续节点的事件处理程序的运行


  事件的移除

  DOM0级:

    targetElement.onclick = null;

  DOM2级:

    targetElement.removeEventListener(type, listener);

注意:事件函数listener需要保存才可以移除,因为需要传入该函数的引用

let a,b,c;
btn.addEventListener('click',a= function () {alert('addEventListener方法1');});
btn.addEventListener('click',b= function () {alert('addEventListener方法2');});
btn.addEventListener('click',c= function () {alert('addEventListener方法3');});
btn.removeEventListencer("click",a);

四、事件类型

  页面事件

      onload 一张页面或一幅图像完成加载时触发的事件

      onresize 窗口或框架被重新调整大小时触发的事件。

      onscroll 当文档被滚动时触发的事件

        

  鼠标事件

      onclick          当鼠标点击某个元素时触发的事件

      ondblclick        当鼠标双击某个元素时触发的事件

      onmousedown      当鼠标按钮被按下时触发的事件

      onmouseup        当鼠标按键被松开时触发的事件

      onmousemove      当鼠标在鼠标事件某个元素上移动时触发的事件

      onmouseenter       当鼠标指针移动到元素上时触发的事件

      onmouseleave      当鼠标指针移出元素时触发的事件

      onmouseover        鼠标指针移动到元素上时触发的事件

      onmouseout          当鼠标指针移出元素时触发的事件

注意1:事件mousemove会在满足条件的情况下不断触发;

注意2: onmouseenter和onmouseleave在进入元素时触发,其他时候不会触发;

    onmouseover和onmouseout不光会在进入元素时触发,在元素的子元素上也会触发。

  键盘事件

      onkeydown 当键盘按键被按下时触发的事件。

      onkeypress 当键盘按键被按下并松开时触发的事件。

      onkeyup 当键盘按键被松开时触发的事件。

注意1:事件触发顺序是down,press,up;

注意2:其中down和up任意的按键都能触发,press只有字符输入时会触发;

    也就是说,shift,delete这些特殊按键不会触发press事件;

    同时down和up并不能知道按下键的具体内容(比如大小写),而press就关注内容。

  表单事件

  focus  获得焦点时触发

  blur   失去焦点时触发

  reset  重置表单时触发

  submit  提交表单时触发

  change  input框失去焦点,判断value是否改变,改变时触发

  input  输入内容时,value改变了就触发

五、事件对象

  事件中的详细信息,事件内部的一些处理方法。

  IE 8 及之前版本 IE 浏览器:event 事件对象被提供在window对象中。

  所以有了兼容性的写法:

<input type="button" value="点击" id="clickBtn">

    <script>

        clickBtn.onclick = function (event) {

            let e = event || window.event;

        }

    </script>

  事件目标

      event 事件对象提供了target属性用于获取触发事件的目标元素(标签)。

<p id="para"> 我是一个p标签 </p>

<script>

para.onclick = function(event){

console.log( event.target );

}

</script>

    IE8 及之前版本的 IE 浏览器中同样存在兼容性问题,是srcElement属性,

    上面的javaScript代码改写成:

para.onclick = function(event){

  let target = event.target || event.srcElement;

}

  事件目标(事件源)与 this

        在事件的处理函数中,可以通过this关键字来指代绑定该事件的标签元素。

para.onclick = function(){

  console.log(this == para); //true

}

 注:绑定事件监听器时,不能使用箭头函数,不然就没有this。

    区分this和event.target:

        this指绑定监听器的元素节点;

        event.target指触发事件的目标元素节点。

      

  事件上与鼠标事件相关的属性

      事件对象(event)上提供了一些属性,可以用来获取当鼠标事件发生时鼠标的坐标

          clientX         返回当事件被触发时鼠标指针相对于浏览器文档显示区的水平坐标

          clientY         返回当事件被触发时鼠标指针相对于浏览器文档显示区的垂直坐标

          pageX         返回当事件被触发时鼠标指针相对于 HTML 文档页面的水平坐标

          pageY      返回当事件被触发时鼠标指针向对于 HTML 文档页面的垂直坐标

          screenX      返回事件发生时鼠标指针相对于屏幕的水平坐标

          screenY      返回事件发生时鼠标指针相对于屏幕的垂直坐标

          offsetX        返回事件发生时鼠标指针相对于事件源的水平坐标

          offsetY        返回事件发生时鼠标指针相对于事件源的垂直坐标

  功能键标志属性

  ctrlKey  altKey

  阻止默认行为

有些事件发生有默认行为,有时候不需要它执行,可以阻止:

  阻止默认行为:

     e.preventDefault();  或  return false;(只能用于dom0级)

  阻止事件流传播:

    e.stopPropergation(); 或 e.cancelBubble=true;

六、事件委托

  事件代理:将子节点的事件监听器,放置在上级(父亲或祖先)节点上,利用的是事件冒泡原理,实现上级节点代理子节点事件的一种技术。

  

  一般在,子节点很多,多个子节点需要绑定类似的事件函数,或子节点是动态时使用。

  可以很大程度上优化节约性能,也能解决节点动态问题。

注:上级节点的选定,要看情况,一般近一点比较好,还要保证必定不是动态节点。

  并且因为依赖事件冒泡,所以必须使用 mouseenter、mouseleave(事件会冒泡),mouseover和mouseout事件不会冒泡。

原文地址:https://www.cnblogs.com/jiayouba/p/11939459.html