事件_事件委托 - CSDN
事件 订阅
事件,读音是shì jiàn,汉语词语,意思是事情、事项。 展开全文
事件,读音是shì jiàn,汉语词语,意思是事情、事项。
信息
外文名
event
拼    音
shì jiàn
中文名
事件
解    释
事情、事项
事件解释
收起全文
  • 事件

    2020-06-17 22:37:19
    事件 事件就是交互事件,用户点击实现回馈,是交互体验的核心功能。 绑定事件处理函数 ele.onxxxx = function(event){} 兼容性很好,但是一个元素的同一事件上只能绑定一个 基本等同于写在HTML行间上 obj....

    事件

    事件就是交互事件,用户点击实现回馈,是交互体验的核心功能。

    绑定事件处理函数

    1. ele.onxxxx = function(event){}
      兼容性很好,但是一个元素的同一事件上只能绑定一个
      基本等同于写在HTML行间上
    2. obj.addEventListener(type,fn,false)
      IE9一下不兼容,可以为一个事件绑定多个处理程序
    3. obj.attachEvent(‘on’ + type, fn);
      IE独有,一个事件同样可以绑定多个处理程序

    事件处理程序的运行环境

    1. ele.onxxx = function (event){}
      程序this指向是dom元素本身。
      //谁点击,this就指向它。
    2. obj.addEventListener(type,fn,false);
      程序this指向是dom元素本身
    3. obj.attachEvent(‘on’ + type, fn);
      程序this指向window

    给一个对象封装一个事件处理函数

    function addEvent(elem , type, handle){
        if(elem.addEventListener){
            elem.addEventListener(type,handle,false)
        }else if(elem.attachEvent){
            elem.attachEvent('on' + type, function(){
                handle.call(elem)
            })
        }else{
            elem['on' + type] = handle;
        }
    }
    

    解除事件处理程序

    1. ele.onclick = false/’’/null;
    2. ele.removeEventListener(type, fn, false);
    3. ele.detachEvent(‘on’ + type, fn)
      注意:若绑定匿名函数,则无法解除绑定

    事件处理模型,事件冒泡、捕获

    事件冒泡:

    1. 结构上(非视觉上)嵌套关系的元素,会存在事件冒泡功能,即同一事件,自子元素冒泡向父元素。(自底向上)

    事件捕获

    1. 结构上(非视觉上)嵌套关系的元素,会存在事件捕获功能,即同一事件,自父元素捕获至子元素(事件源元素)。(自顶向下)
    2. IE没有捕获事件

    触发顺序,先捕获,后冒泡

    不会触发冒泡事件的方法

    1. focus
    2. blur
    3. change
    4. submit
    5. rest
    6. select

    取消冒泡和阻止默认事件

    取消冒泡

    1. W3C标准event.stopPropagation(),不支持IE9以下版本
    2. IE独有的,event.cancaleBubble = true;
    3. 封装取消冒泡的函数stopBubble(event)
    function stopBubble(event){
        if(event.stopPropagation){
            event.stopPropagation();
        }else{
            event.cancelBubble = true;
        }
    }
    

    阻止默认事件

    1. 默认事件—表单提交,a标签跳转,右键菜单等
    2. return false;以对象属性的方式注册的时间才生效
    3. Event.preventDefault();W3C标准,IE9以下不兼容
    4. event.returnValue = false;兼容IE
    5. 封装阻止默认事件的函数 cancelHandler(event)
    function canceHandler(event){
        if(event.preventDefault){
            event.preventDefaule();
        }else{
            event.returnValue = false;
        }
    }
    

    事件对象

    1. event || window.event 用于IE
    2. 事件源对象:
      event.target 火狐只有这个
      event.srcElement IE只有这个
      谷歌浏览器都有
    3. 兼容性写法,方法
    ele.onclick = function(e){
        var event = e || window.event;
        var target = event.target || event.srcElement;
    }
    
    

    事件委托

    利用事件冒泡,和事件源对象进行处理

    优点:

    1. 性能不需要循环所有的元素一个个绑定事件
    2. 灵活,当有新的子元素时不需要重新绑定事件

    鼠标事件

    click
    鼠标点击之后
    mousedown
    鼠标按键事件
    mousemove
    鼠标移动事件
    mouseup
    区分鼠标按键
    contextmenu
    右键菜单事件
    mouseover
    鼠标放入区域
    mouseout
    鼠标离开区域
    mouseenter
    鼠标放入区域
    mouseleave
    鼠标离开区域

    用button来区分鼠标的按键,0/1/2
    DOM3标准规定:click事件只能监听左键,只能通过mousedown和mouseup来判断鼠标键
    解决mousedown和click的冲突

    键盘事件

    1. keydown
      按下键盘触发
    2. keyup
      松开键盘触发
    3. keypress
      按住连续触发
      keydown>keyoress>keyup
    4. keydown 和 keypress的区别
    5. keydown 可以响应任意键盘按键,keypress只可以响应字符类键盘按键
    6. keypress返回ASCLL码,可以转换成相应字符。
    7. oninput监测输入框输入事件
    8. onchange输入框聚焦输入再离开的时候触发
    9. onfouce当聚焦的时候触发
    10. onscroll鼠标滚动条滚动触发
    11. onload当文档解析完之后所有页面全部渲染完之后再触发
    展开全文
  • 三大事件(鼠标事件、键盘事件、html事件) 1、鼠标事件 click:单击 dblclick:双击 mousemove:鼠标移动 mousedown:鼠标按下 mouseup:鼠标抬起 mouseover:鼠标悬浮 mouseout:鼠标离开 mouseenter:鼠标进入 ...

    三大事件(鼠标事件、键盘事件、html事件)

    1、鼠标事件

    • click:单击
    • dblclick:双击
    • mousemove:鼠标移动
    • mousedown:鼠标按下
    • mouseup:鼠标抬起
    • mouseover:鼠标悬浮
    • mouseout:鼠标离开
    • mouseenter:鼠标进入
    • mouseleave:鼠标离开

    2、键盘事件

    • keydown:按键按下
    • keyup:按键抬起
    • keypress:按键按下抬起

    3、HTML事件

    • load:文档加载完成
    • select:被选中的时候
    • change:内容被改变
    • focus:得到光标
    • blur:失去光标
    • resize:窗口尺寸变化
    • scroll:滚动条移动

    事件委托机制

    事件委托指的是,不在事件的发生地设立监听函数,而是在事件发生地的父元素或者祖先元素设置监听器函数,这样可以大大提高性能,因为可以减少绑定事件的元素,比如:

    <ul>
      <li></li>
      <li></li>
      <li></li>
    </ul>
    

    你要给li元素绑定click事件,
    使用事件委托机制的话,就只需要给ul绑定click事件就行了,
    这样就不需要给每个li’绑定click事件,减小内存占用,提高效率。

    事件的移除

    事件的注册方式对应其移除方式
    1、 el.onclick = null

    var el = document.getElementById("btn");
    //事件注册
     el.onclick = function(event){  
         alert(id); 
         el.onclick = null;   //事件删除
     }
    

    2、el.removeEventListener(type,fn,false); //这里 fn 必须是原有绑定的函数,否侧解除无效

    var div = document.getElemetById('id');
    div.addEventListener('click',test,false);
    function test(){
     console.log('remove click');
    }
    div.removeEventListener('click',test,false);
    

    事件循环机制

    1、是什么

    浏览器中的事件循环机制(event-loop)流程如下:
    1.1,js在执行代码时,由上至下遍历;
    1.2, 首先,遇到任务,判断该任务是同步还是异步任务;
    1.3,如果是
    同步任务
    ,一般会直接进入到主线程中执行;
    1.4,如果是异步任务,先行加入任务队列( Event Queue );
    1.5,主线程内的任务执行完毕时,会去 任务队列 读取对应的异步任务,把它推入主线程执行。(读取任务队列中的任务时,优先读取微任务,后读取宏任务),执行完了再去 任务队列读取异步任务,把任务放到主线程中执行,如此循环。
    1.6,就是我们说的 事件循环(Event Loop)。

    总结 js执行顺序: 同步函数 ===》微任务 ===》 宏任务

    这里的主线程 ,也就是运行栈

    总结:事件循环机制如下:
    1、同步代码,直接执行
    2、异步先放在任务队列中
    3、待同步函数执行完毕,轮询执行任务队列的函数

    2、哪些语句会放入异步任务队列中?

    • 1、定时任务:setTimeout、setInterval
    • 2、网络请求:ajax请求、动态img加载
    • 3、DOM绑定的事件:dom事件
    • 4、ES6中的promise.then中的函数

    Promise 构造函数是同步执行的,promise.then 中的函数是异步执行的。

    3、何时被放入任务队列?

    • 1、类似onclick事件等,由浏览器内核的DOM binding模块处理,事件触发时,回调函数添加到任务队列中;
    • 2、setTimeout的定时任务等,由浏览器内核的Timer模块处理,时间到达时,回调函数添加到任务队列中;
    • 3、Ajax异步请求,由浏览器内核的Network模块处理,网络请求返回后,添加到任务队列中。

    ajax加载完成,即ajax什么时候success,就什么时候把ajax中的函数放入到异步队列中

    4、同步任务和异步任务

    • 同步任务:加入主线程中,立即执行;
    • 异步任务:加入任务队列,等待主线程中的同步任务执行完毕,才会去任务队列中读取相应的任务执行。(常见的异步任务,比如ajax网络请求,setTimeout 定时函数等都属于异步任务)

    异步任务又分为 宏观任务 、微观任务

    5、 宏观任务和微观任务

    • 宏观任务包含以下几类
    1. script( 整体代码)
    2. setTimeout
    3. setInterval
    4. I/O
    5. UI交互事件
    6. setImmediate(Node.js 环境)
    • 微观任务包含以下几类
    1. Promise
    2. MutaionObserver
    3. process.nextTick(Node.js 环境)

    [事件循环机制的参考链接]:(https://www.cnblogs.com/yugege/p/9598265.html)https://www.cnblogs.com/yugege/p/9598265.html

    展开全文
  • JavaScript 事件模型 事件处理机制

    万次阅读 多人点赞 2013-08-21 21:10:38
    这篇文章对于了解Javascript的事件处理机制非常好,将它全文转载于此,以备不时之需。 什么是事件事件(Event)是JavaScript应用跳动的心脏 ,也是把所有东西粘在一起的胶水。当我们与浏览器中 Web 页面进行...

    这篇文章对于了解Javascript的事件处理机制非常好,将它全文转载于此,以备不时之需。

    什么是事件?

    事件(Event)是JavaScript应用跳动的心脏 ,也是把所有东西粘在一起的胶水。当我们与浏览器中 Web 页面进行某些类型的交互时,事件就发生了。事件可能是用户在某些内容上的点击、鼠标经过某个特定元素或按下键盘上的某些按键。事件还可能是 Web 浏览器中发生的事情,比如说某个 Web 页面加载完成,或者是用户滚动窗口或改变窗口大小。

    通过使用 JavaScript ,你可以监听特定事件的发生,并规定让某些事件发生以对这些事件做出响应。

    今天的事件

    在漫长的演变史,我们已经告别了内嵌式的事件处理方式(直接将事件处理器放在 HTML 元素之内来使用)。今天的事件,它已是DOM的重要组成部分,遗憾的是, IE继续保留它最早在IE4.0中实现的事件模型,以后的IE版本中也没有做太大的改变,这也就是说IE还是使用的是一种专有的事件模型(冒泡型),而其它的主流浏览器直到DOM 级别 3 规定定案后,才陆陆续续支持DOM标准的事件处理模型 — 捕获型与冒泡型。

    历史原因是:W3C 规范 在DOM 级别 1中并没有定义任何的事件,直到发布于 2000 年 11 月 的DOM 级别 2 才定义了一小部分子集,DOM 级别 2中已经提供了提供了一种更详细的更细致的方式以控制 Web 页面中的事件,最后,完整的事件是在2004年 DOM 级别 3的规定中才最终定案。因为IE4是1995推出的并已实现了自己的事件模型(冒泡型),当时根本就没有DOM标准,不过在以后的DOM标准规范过程中已经把IE的事件模型吸收到了其中。

    目前除IE浏览器外,其它主流的Firefox, Opera,
    Safari都支持标准的DOM事件处理模型。IE仍然使用自己专有的事件模型,即冒泡型,它事件模型的一部份被DOM标准采用,这点对于开发者来说也是有好处的,只有使用
    DOM标准,IE都共有的事件处理方式才能有效的跨浏览器。

    DOM事件流

    DOM(文档对象模型)结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素结点与根节点之间按特定的顺序传播,路径所经过的节点都会收到该事件,这个传播过程可称为DOM事件流。

    事件顺序有两种类型:事件捕捉事件冒泡

    冒泡型事件(Event Bubbling)

    这是IE浏览器对事件模型的实现,也是最容易理解的,至少笔者觉得比较符合实际的。冒泡,顾名思义,事件像个水中的气泡一样一直往上冒,直到顶端。从
    DOM树型结构上理解,就是事件由叶子节点沿祖先结点一直向上传递直到根节点;从浏览器界面视图HTML元素排列层次上理解就是事件由具有从属关系的最确定的目标元素一直传递到最不确定的目标元素.冒泡技术.冒泡型事件的基本思想,事件按照从特定的事件目标开始到最不确定的事件目标.

    捕获型事件(Event Capturing)

    Netscape 的实现,它与冒泡型刚好相反,由DOM树最顶层元素一直到最精确的元素,这个事件模型对于开发者来说(至少是我..)有点费解,因为直观上的理解应该如同冒泡型,事件传递应该由最确定的元素,即事件产生元素开始。

     

    event-buddle

    DOM标准的事件模型

    我们已经对上面两个不同的事件模型进行了解释和对比。DOM标准同时支持两种事件模型,即捕获型事件冒泡型事件,但是,捕获型事件先发生。两种事件流都会触发DOM中的所有对象,从document对象开始,也在document对象结束(大部分兼容标准的浏览器会继续将事件是捕捉/冒泡延续到window对象)。

    domevent

    如图:首先是捕获式传递事件,接着是冒泡式传递,所以,如果一个处理函数既注册了捕获型事件的监听,又注册冒泡型事件监听,那么在DOM事件模型中它就会被调用两次。

    DOM标准的事件模型最独特的性质是,文本节点也会触发事件(在IE不会)。

    capturing-bubbling

    事件传送

    为了更好的说明DOM标准中的事件流原理,我们把它放在“事件传送”小结里来更具体的解释。

    显然,如果为一个超链接添加了click事件监听器,那么当该链接被点击时该事件监听器就会被执行。但如果把该事件监听器指派给了包含该链接的p元素或者位于DOM树顶端的document节点,那么点击该链接也同样会触发该事件监听器。这是因为事件不仅仅对触发的目标元素产生影响,它们还会对沿着DOM结构的所有元素产生影响。这就是大家所熟悉的事件转送

    W3C事件模型中明确地指出了事件转送的原理。事件传送可以分为3个阶段。

    Standard-event-propagation

    如图:标准的事件转送模式

    (1).在事件捕捉(Capturing)阶段,事件将沿着DOM树向下转送,目标节点的每一个祖先节点,直至目标节点。例如,若用户单击了一个超链接,则该单击事件将从document节点转送到html元素,body元素以及包含该链接的p元素。

    在此过程中,浏览器都会检测针对该事件的捕捉事件监听器,并且运行这件事件监听器。

    (2). 在目标(target)阶段,浏览器在查找到已经指定给目标事件的事件监听器之后,就会运行 该事件监听器。目标节点就是触发事件的DOM节点。例如,如果用户单击一个超链接,那么该链接就是目标节点(此时的目标节点实际上是超链接内的文本节点)。

    (3).在冒泡(Bubbling)阶段,事件将沿着DOM树向上转送,再次逐个访问目标元素的祖先节点到document节点。该过程中的每一步。浏览器都将检测那些不是捕捉事件监听器的事件监听器,并执行它们。

    并非所有的事件都会经过冒泡阶段的

    所有的事件都要经过捕捉阶段和目标阶段,但是有些事件会跳过冒泡阶段。例如,让元素获得输入焦点的focus事件以及失去输入焦点的blur事件就都不会冒泡。

     

    事件句柄和事件接听器

    事件句柄

    事件句柄(又称事件处理函数,DOM称之为事件监听函数),用于响应某个事件而调用的函数称为事件处理函数
    。每一个事件均对应一个事件句柄,在程序执行时,将相应的函数或语句指定给事件句柄,则在该事件发生时,浏览器便执行指定的函数或语句,从而实现网页内容与用户操作的交互。当浏览器检测到某事件发生时,便查找该事件对应的事件句柄有没有被赋值,如果有,则执行该事件句柄。

    我们认为响应点击事件的函数是onclick事件处理函数。以前,事件处理函数有两种分配方式:在JavaScript中或者在HTML中

    如果在JavaScript 中分配事件处理函数, 则需要首先获得要处理的对象的一引用,然后将函数赋值给对应的事件处理函数属性,请看一个简单的例子:

     

    复制代码
    1 var link=document.getElementById("mylink");
    2 link.onclick=function(){
    3   alert("I was clicked !");
    4 }; 
    复制代码

     

    从我们看到的例子中,我们发现使用事件句柄很容易,
    不过事件处理函数名称必须是小写的,还有就是只有在
    元素载入完成之后才能将事件句柄赋给元素,不然会有异常。

    关于文档载入技术,请看《window.onload加载的多种解决方案》 的文章。

    如果在HTML中分配事件句柄的话,则直接通过HTML属性来设置事件处理函数就行了,并在其中包含合适的脚本作为特性值就可以了,例如:

    <a href="/" onclick="JavaScript code here">......</a>

    这种JavaScript 代码和通过HTML的style属性直接将CSS属性赋给元素类似。这样会代码看起来一团糟,也违背了将实现动态行为的代码与显示文档静态内容的代码相分离的原则。从1998年开始,这种写法就过时了。

    这种传统的事件绑定技术,优缺点是显然的:

    *简单方便,在HTML中直接书写处理函数的代码块,在JS中给元素对应事件属性赋值即可。

    *IE与DOM标准都支持的一种方法,它在IE与DOM标准中都是在事件冒泡过程中被调用的。

    *可以在处理函数块内直接用this引用注册事件的元素,this引用的是当前元素。

    *要给元素注册多个监听器,就不能用这方法了。

    事件接听器

    除了前面已经介绍的简单事件句柄之外,现在大多数浏览器都内置了一些更高级的事件处理方式,即,事件监听器,这种处理方式就不受一个元素只能绑定一个事件句柄的限制。

    我们已经知道了事件句柄与事件监听器的最大不同之处是使用事件句柄时一次只能插接一个事件句柄,但对于事件监听器,一次可以插接多个。

    IE下的事件监听器:

    IE提供的却是一种自有的,完全不同的甚至存在BUG的事件监听器,因此如果要让脚本在本浏览器中正常运行的话,就必须使用IE所支持的事件监听器。另外,Safari 浏览器中的事件监听器有时也存在一点不同。

    在IE中,每个元素和window对象都有两个方法:attachEvent方法和detachEvent方法。 

    复制代码
    1 element.attachEvent("onevent",eventListener);
    复制代码

    此方法的意思是在IE中要想给一个元素的事件附加事件处理函数,必须调用attachEvent方法才能创建一个事件监听器。attachEvent方法允许外界注册该元素多个事件监听器。

    attachEvent接受两个参数。第一个参数是事件类型名,第二个参数eventListener是回调处理函数。这里得说明一下,有个经常会出错的地方,IE下
    利用attachEvent注册的处理函数调用时this指向不再是先前注册事件的元素,这时的this为window对象。还有一点是此方法的事件类型名称必须加上一个”on”的前缀(如onclick)。 

    复制代码
    1 element.attachEvent("onevent",eventListener);
    复制代码

    要想移除先前元素注册的事件监听器,可以使用detachEvent方法进行删除,参数相同。

    DOM标准下的事件监听器:

    在支持W3C标准事件监听器的浏览器中,对每个支持事件的对象都可以使用addEventListener方法。该方法既支持注册冒泡型事件处理,又支持捕获型事件处理。所以与IE浏览器中注册元素事件监听器方式有所不同的。

    复制代码
    1 //标准语法 
    2 element.addEventListener('event', eventListener, useCapture);
    3 //默认
    4 element.addEventListener('event', eventListener, false);
    复制代码

    addEventListener方法接受三个参数。第一个参数是事件类型名,值得注意的是,这里事件类型名称与IE的不同,事件类型名是没’on’开头的;第二个参数eventListener是回调处理函数(即监听器函数);第三个参数注明该处理回调函数是在事件传递过程中的捕获阶段被调用还是冒泡阶段被调用 ,通常此参数通常会设置为false(为false时是冒泡),那么,如果将其值设置为true,那就创建一个捕捉事件监听器。

    移除已注册的事件监听器调用element的removeEventListener方法即可,参数相同。

    复制代码
    1 //标准语法 
    2 element.removeEventListener('event', eventListener, useCapture);
    3 //默认
    4 element.removeEventListener('event', eventListener, false);
    复制代码

    通过addEventListener方法添加的事件处理函数,必须使用removeEventListener方法才能删除,而且要求参数与添加事件处理函数时addEventListener方法的参数完全一致(包括useCapture参数),否则将不能成功删除事件处理函数。

    跨浏览器的注册与移除元素事件监听器方案

    我们现在已经知道,对于支持addEventListener方法的浏览器,只要需要事件监听器脚本就都需要调用addEventListener方法;而对于不支持该方法的IE浏览器,使用事件监听器时则需要调用attachEvent方法。要确保浏览器使用正确的方法其实并不困难,只需要通过一个if-else语句来检测当前浏览器中是否存在addEventListener方法或attachEvent方法即可。

    这样的方式就可以实现一个跨浏览器的注册与移除元素事件监听器方案:

     

    复制代码
     1 var EventUtil = {
     2   //注册
     3   addHandler: function(element, type, handler){
     4     if (element.addEventListener){
     5       element.addEventListener(type, handler, false);
     6     } else if (element.attachEvent){
     7       element.attachEvent("on" + type, handler);
     8     } else {
     9       element["on" + type] = handler;
    10     }
    11   },
    12   //移除注册
    13   removeHandler: function(element, type, handler){
    14     if (element.removeEventListener){
    15             element.removeEventListener(type, handler, false);
    16     } else if (element.detachEvent){
    17             element.detachEvent("on" + type, handler);
    18     } else {
    19             element["on" + type] = null;
    20     }
    21   }             
    22  }; 
    复制代码

     

    事件对象引用

    为了更好的处理事件,你可以根据所发生的事件的特定属性来采取不同的操作。

    如事件模型一样,IE 和其他浏览器处理方法不同:IE 使用一个叫做 event 的全局事件对象来处理对象(它可以在全局变量window.event中找到),而其它所有浏览器采用的 W3C 推荐的方式,则使用独立的包含事件对象的参数传递。

    跨浏览器实现这样的功能时,最常见的问题就是获取事件本身的引用及获取该事件的目标元素的引用。

    下面这段代码就为你解决了这个问题:

    复制代码
    1 var EventUtil ={
    2   getEvent: function(event){
    3     return event ? event : window.event;
    4   },
    5   getTarget: function(event){
    6     return event.target || event.srcElement;
    7   }
    8 };
    复制代码

    停止事件冒泡和阻止事件的默认行为

    “停止事件冒泡“和”阻止浏览器的默认行为“,这两个概念非常重要,它们对复杂的应用程序处理非常有用。

    1.停止事件冒泡

    停止事件冒泡是指,停止冒泡型事件的进一步传递(取消事件传递,不只是停止IE和DOM标准共有的冒泡型事件,我们还可以停止支持DOM标准浏览器的捕捉型事件,用topPropagation()方法)。例如上图中的冒泡型事件传递中,在body处理停止事件传递后,位于上层的document的事件监听器就不再收到通知,不再被处理。

    2.阻止事件的默认行为

    停止事件的默认行为是指,通常浏览器在事件传递并处理完后会执行与该事件关联的默认动作(如果存在这样的动作)。例如,如果表单中input type 属性是 “submit”,点击后在事件传播完浏览器就自动提交表单。又例如,input 元素的 keydown 事件发生并处理后,浏览器默认会将用户键入的字符自动追加到 input 元素的值中。

    停止事件冒泡的处理方法

    在IE下,通过设置event对象的cancelBubble为true即可。

    复制代码
    1 function someHandle() {
    2   window.event.cancelBubble = true;
    3 }
    复制代码

    DOM标准通过调用event对象的stopPropagation()方法即可。

    复制代码
    1 function someHandle(event) {
    2   event.stopPropagation();
    3 }
    复制代码

    因些,跨浏览器的停止事件传递的方法是:

    复制代码
    1 function someHandle(event) {
    2   event = event || window.event;
    3   if(event.stopPropagation){
    4     event.stopPropagation();
    5   }else {
    6     event.cancelBubble = true;
    7   }
    8 }
    复制代码
     

    阻止事件的默认行为的处理方法

    就像事件模型和事件对象差异一样,在IE和其它所有浏览器中阻止事件的默认行为的方法也不同。

    在IE下,通过设置event对象的returnValue为false即可。

    复制代码
    1 function someHandle() {
    2   window.event.returnValue = false;
    3 }
    复制代码

    DOM标准通过调用event对象的preventDefault()方法即可。

    复制代码
    1 function someHandle(event) {
    2   event.preventDefault();
    3 }
    复制代码

    因些,跨浏览器的取消事件传递后的默认处理方法是:

    复制代码
    1 function someHandle(event) {
    2   event = event || window.event;
    3   if(event.preventDefault){
    4     event.preventDefault();
    5   }else{
    6     event.returnValue = false;
    7   }
    8 }
    复制代码

    完整的事件处理兼容性函数 

    复制代码
     1 var EventUtil = {
     2   addHandler: function(element, type, handler){
     3     if (element.addEventListener){
     4       element.addEventListener(type, handler, false);
     5     } else if (element.attachEvent){
     6       element.attachEvent("on" + type, handler);
     7     } else {
     8       element["on" + type] = handler;
     9     }
    10   },
    11   removeHandler: function(element, type, handler){
    12     if (element.removeEventListener){
    13       element.removeEventListener(type, handler, false);
    14     } else if (element.detachEvent){
    15       element.detachEvent("on" + type, handler);
    16     } else {
    17       element["on" + type] = null;
    18     }
    19   },
    20   getEvent: function(event){
    21     return event ? event : window.event;
    22   },
    23   getTarget: function(event){
    24     return event.target || event.srcElement;
    25   },
    26   preventDefault: function(event){
    27     if (event.preventDefault){
    28       event.preventDefault();
    29     } else {
    30       event.returnValue = false;
    31     }
    32   },
    33   stopPropagation: function(event){
    34     if (event.stopPropagation){
    35       event.stopPropagation();
    36     } else {
    37       event.cancelBubble = true;
    38     }
    39 };
    复制代码

    捕获型事件模型与冒泡型事件模型的应用场合

    标准事件模型为我们提供了两种方案,可能很多朋友分不清这两种不同模型有啥好处,为什么不只采取一种模型。
    这里抛开IE浏览器讨论(IE只有一种,没法选择)什么情况下适合哪种事件模型。

    1. 捕获型应用场合

    捕获型事件传递由最不精确的祖先元素一直到最精确的事件源元素,传递方式与操作系统中的全局快捷键与应用程序快捷键相似。当一个系统组合键发生时,如果注
    册了系统全局快捷键监听器,该事件就先被操作系统层捕获,全局监听器就先于应用程序快捷键监听器得到通知,也就是全局的先获得控制权,它有权阻止事件的进
    一步传递。所以捕获型事件模型适用于作全局范围内的监听,这里的全局是相对的全局,相对于某个顶层结点与该结点所有子孙结点形成的集合范围。

    例如你想作全局的点击事件监听,相对于document结点与document下所有的子结点,在某个条件下要求所有的子结点点击无效,这种情况下冒泡模型就解决不了了,而捕获型却非常适合,可以在最顶层结点添加捕获型事件监听器,伪码如下:

    复制代码
    1 function globalClickListener(event) {
    2   if(canEventPass == false) {
    3     //取消事件进一步向子结点传递和冒泡传递
    4     event.stopPropagation();
    5     //取消浏览器事件后的默认执行
    6     event.preventDefault();
    7   }
    8 }
    复制代码

    这样一来,当canEventPass条件为假时,document下所有的子结点click注册事件都不会被浏览器处理。

    2. 冒泡型的应用场合

    可以说我们平时用的都是冒泡事件模型,因为IE只支持这模型。这里还是说说,在恰当利用该模型可以提高脚本性能。在元素一些频繁触发的事件中,如
    onmousemove,
    onmouseover,onmouseout,如果明确事件处理后没必要进一步传递,那么就可以大胆的取消它。此外,对于子结点事件监听器的处理会对父
    层监听器处理造成负面影响的,也应该在子结点监听器中禁止事件进一步向上传递以消除影响。

    综合案例分析

    最后结合下面HTML代码作分析:

    复制代码
     1 <body onclick="alert('current is body');">
     2   <div id="div0" onclick="alert('current is '+this.id)">
     3     <div id="div1" onclick="alert('current is '+this.id)">
     4       <div id="div2" onclick="alert('current is '+this.id)">
     5         <div id="event_source" onclick="alert('current is '+this.id)" style="height:200px;width:200px;background-color:red;"></div>
     6       </div>
     7     </div>
     8   </div>
     9 </body>
    10 
    复制代码

    HTML运行后点击红色区域,这是最里层的DIV,根据上面说明,无论是DOM标准还是IE,直接写在html里的监听处理函数是事件冒泡传递时调用的,由最里层一直往上传递,所以会先后出现
    current is event_source
    current is div2
    current is div1
    current is div0
    current is body

    添加以下片段:

    复制代码
    1 var div2 = document.getElementById('div2');
    2 EventUtil.addHandler(div2, 'click'function(event){
    3   event = EventUtil.getEvent(event);
    4   EventUtil.stopPropagation(event);
    5 }, false);
    复制代码

    current is event_sourcecurrent is div2

    当点击红色区域后,根据上面说明,在泡冒泡处理期间,事件传递到div2后被停止传递了,所以div2上层的元素收不到通知,所以会先后出现:

    在支持DOM标准的浏览器中,添加以下代码:

    复制代码
    1 document.body.addEventListener('click'function(event){
    2   event.stopPropagation();
    3 }, true);
    复制代码

    以上代码中的监听函数由于是捕获型传递时被调用的,所以点击红色区域后,虽然事件源是ID为event_source的元素,但捕获型选传递,从最顶层开始,body结点监听函数先被调用,并且取消了事件进一步向下传递,所以只会出现 current is body .

    展开全文
  • C#中的事件

    千次阅读 2018-12-18 22:33:30
    C#中的事件其实就是C#中委托的一个属性,使用事件是为了防止委托中的参数被随意调用和修改,是出于安全性考虑。 event 还限定了 delegate 只能在定义的类中被调用。 using System; namespace Lesson26_2 { //...

    C#中的事件其实就是C#中委托的一个属性,使用事件是为了防止委托中的参数被随意调用和修改,是出于安全性考虑。

    event 还限定了 delegate 只能在定义的类中被调用。

    using System;
    
    namespace Lesson26_2
    {
    	//事件 - event 就是 delegate 的属性
    	//处于安全性的考虑
    	/// <summary>
    	/// 1.事件event 和 delegate 的关系就像字段和属性的关系
    	/// 2.event 会限制 delegate 不能够直接进行赋值操作,防止将委托替换掉,只能使用 += 和 -= 来绑定或者解除绑定
    	/// 3.event 还限定了 delegate 只能在定义的类中被调用
    	/// </summary>
    	//定义委托
    	public delegate void Something (string name);
    
    	public class Student  {
    		public string name;
    		//事件 - 使用了事件之后就不能直接给委托赋值,必须使用 += 和 -= 来解除绑定
    
    		public event Something something;
     
    		public Student (string name){
    			this.name = name;
    		}
    
    		public void Do (){
    			something (name);
    		}
    	}
    
    	public class Teacher{
    		public void Hungry (){
    			Student s = new Student ("dzzhyk");
    			//现在通过s中的something方法来直接赋值
    			s.something += new Something (A);
    			//使用了 event 之后就不能在Student的外部调用something
    			//s.something ("nihao");
    			s.Do ();
    		}
    		public void A (string name){
    			Console.WriteLine ("Hello!" + name);
    		}
    	}
    	class MainClass
    	{
    		public static void Main (string[] args)
    		{
    			Teacher t = new Teacher ();
    			t.Hungry ();
    		}
    	}
    }
    

     

    展开全文
  • JavaScript中事件的绑定与解绑

    千次阅读 2019-01-05 12:49:31
    1. 对象.on事件名字=事件处理函数 2. 对象.addEventListener("没有on的事件名字",事件处理函数,false); 3. 对象.attachEvent("有on的事件名字",事件处理函数); 4.总结绑定事件的区别 5.兼容...
  • C#事件

    千次阅读 2018-03-31 00:59:44
    C#事件的用法与意义C#事件与委托十分相似,其实事件包含了一个私有委托,所以事件就像是专门用于某种特殊用途的简单委托。事件使用的方法图:正如上图所示,发布者类Incrementer里面的事件CountedADozen就像一个装...
  • 什么是鼠标事件

    2020-09-17 14:42:34
    事件 事件源 1.鼠标单击事件:onclick 2.鼠标双击事件:ondblclick 3.鼠标移入/离开(onmouseenter/onmouseleave) 事件源 1.鼠标单击事件:onclick <body> <p id="p1" onclick="fun()">单机事件测试&...
  • 事件模型

    2018-08-28 11:51:20
    几乎所有的GUI编程都涉及到事件处理机制。 很简单: 事件:浏览器、window、document、HTML元素发生事情,浏览器封装事情信息,就是事件事件目标:引发事件的对象,就是事件源。 事件类型:每个事件都有相应...
  • MySQL中的事件

    千次阅读 2019-05-09 15:49:18
    文章目录事件是什么?使用开启定时器语法创建事件查看事件启用和禁用删除事件实践简单案例参考 事件是什么? MySQL5.1版本开始引进event概念,MySQL 中的事件(event:时间触发器)是用于执行定时或周期性的任务,类似...
  • js阻止事件冒泡

    万次阅读 2019-07-06 12:43:34
    js阻止事件冒泡 冒泡事件简介 当我们点击一个控件的时候,如果包括这个控件的父控件也有click事件,则会继续执行。 方法一:event.stopPropagation( ); 例如: <div> <p>段落文本内容 <input type=...
  • 无偏估计实例证明

    万次阅读 2014-04-01 11:07:19
    无偏估计 在概率论和数量统计中,学习过无偏估计,最近在学习论文时候,也经常论文中提到无偏估计。虽然对无偏估计有所了解,但是还是有些问题: 1)总体期望的无偏估计量是样本均值x-,总体方差的无偏估计是...
  • 如何使用事件风暴构建领域模型

    万次阅读 2020-04-07 11:39:18
    一、事件风暴简述 二、事件风暴的准备工作 (一)事件风暴的参与者 (二)事件风暴要准备的材料 (三)事件风暴的场地 (四)事件风暴分析的关注点 三、利用事件风暴构建领域模型 (一)产品愿景 (二)业务...
  • Android事件分发机制 详解攻略,您值得拥有

    万次阅读 多人点赞 2019-07-02 12:15:25
    网上有大量关于Android事件分发机制的文章,但存在一些问题:内容不全、思路不清晰、无源码分析、简单问题复杂化等等 今天,我将全面总结Android的事件分发机制,我能保证这是市面上的最全面、最清晰、最易懂的 ...
  • 其实我一直准备写一篇关于Android事件分发机制的文章,从我的第一篇博客开始,就零零散散在好多地方使用到了Android事件分发的知识。也有好多朋友问过我各种问题,比如:onTouch和onTouchEvent有什么区别,又该如何...
  • 微信小程序-bindtap等事件传参

    万次阅读 多人点赞 2017-03-01 20:28:00
    什么是事件 事件是视图层到逻辑层的通讯方式。 事件可以将用户的行为反馈到逻辑层进行处理。 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。 事件对象可以携带额外信息,如 id, ...
  • 今天来看看前端的冒泡和事件默认事件如何处理 1.event.stopPropagation()方法 这是阻止事件的冒泡方法,不让事件向documen上蔓延,但是默认事件任然会执行,当你掉用这个方法的时候,如果点击一个连接,这个连接...
  • IOS微信浏览器返回事件popstate监听

    万次阅读 2018-09-09 15:10:27
    通过监听popstate事件,来判断是否点击返回按钮,比如从A页面跳转到B页面(监听popstate),然后再跳转到C页面,点击返回的按钮,测试成功,包括安卓版,但是问题来了,IOS版的微信,是会立即触法popstate事件,导致...
  • 记得在前面的文章中,我带大家一起从源码的角度分析了Android中View的事件分发机制,相信阅读过的朋友对View的事件分发已经有比较深刻的理解了。 还未阅读过的朋友,请先参考 Android事件分发机制完全解析,带你从...
  • Android ViewGroup事件分发机制

    万次阅读 多人点赞 2016-08-10 19:38:56
    上一篇已经完整的解析了Android View的事件分发机制,今天给大家代码ViewGroup事件分发的源码解析~~凡是自定义ViewGroup实现各种滑动效果的,不可避免的会出现很多事件的冲突,对ViewGroup事件分发机制的了解,也...
  • 事件委派的使用及作用

    万次阅读 2019-07-07 20:57:09
    事件委派 事件委派适用于未来的元素(动态添加的元素)。 利用事件冒泡,将后代元素上事件的处理程序委派给祖先元素。 event.target || event.srcElement - 在事件传播的过程中,获取最初触发事件事件源元素 示例...
1 2 3 4 5 ... 20
收藏数 2,538,504
精华内容 1,015,401
关键字:

事件