参考javascript编程全解  javascript高级程序设计 javascript经典实例

对事件的处理方式称为事件处理程序或事件侦听器 ,对于一个元素或事件,只能设定1个事件处理程序,却可以同时设定多个事件监听器

1)设定为HTML元素的属性

<!DOCTYPE html>
<meta charset="UTF-8" />
<head></head>
<body>
<a href="http://www.baidu.com" onclick="console.log('haha');return false;">百度</a> </body>

上面将事件处理程序设定为html元素的属性,能在元素在载入的时候被设定

2)为了在页面在中使javascript代码与html分离,可以在在javascript中将事件处理程序设定为DOM元素的属性

<a href="http://www.baidu.com" id="btn">百度</a>

	<script type="text/javascript">
var button = document.getElementById("btn");
function test() {
console.log('haha');
return false;
} btn.onclick = test; </script> //上面这两种方案 通过将事件处理函数设为html元素的属性 和 element.onXXX = handler 的方式 都是默认冒泡的

2016 5 9 DOM0 级别的事件处理程序只能绑定一个

3)上面的两种方式中,对一个事件只能指定一种操作(覆盖),为了实现在一个事件响应多种操作,可以使用addEventListener()方法

addEventListener(1,2,3)

参数1 事件

参数2 处理函数

参数3 true/false 指定是在捕获阶段还是冒泡阶段执行 省略第三个参数默认冒泡阶段执行(false冒泡阶段执行 true捕获阶段执行)

<button id="btn">big button</button>

	<script type="text/javascript">
var button = document.getElementById("btn"); button.addEventListener('click',function(){console.log('haha');},false);
button.addEventListener('click',function(){console.log('hello')},false); </script>

这里为button的click事件注册了两个事件侦听器,并且事件侦听器的触发顺序和注册的顺序相同

还可以将含有handleEvent()方法的对象指定为事件监听器

var button = document.getElementById("btn");

		var listener = {
message: 'hello world', handleEvent:function(e) {
console.log(this.message);
}
}; button.addEventListener('click',listener,false);

事件的触发

上面的图是DOM的事件流 其实它是融合了两种事件流 IE的事件冒泡和事件捕获

事件冒泡:事件开始由最具体的元素接收,逐级的向上传递到父节点

事件捕获:由不具体的节点(父节点)接收事件,具体的节点最后接收事件

一个完成的DOM事件流是这样的:在捕获阶段事件由父元素向目标元素传播事件,此时目标元素没有接收到事件,在目标阶段元素接收到事件然后在冒泡阶段事件逐级的向上传递

<body id='haha'>
<button id="btn">big button</button>
<script type="text/javascript">
var btn = document.getElementById('btn'); btn.onclick = function(event) {
console.log(event.eventPhase);
};//2 目标阶段 document.body.addEventListener('click',function(event){console.log(event.eventPhase,event.target.id,event.currentTarget.id);},true);
         //1 btn haha 捕获阶段 event.target指向实际发生事件的目标 event.currentTarget指向实际处理事件的目标 document.body.onclick = function(event) {console.log(event.eventPhase)}; // 3 冒泡阶段 </script>
</body>

上面的例子详细的说明的DOM事件流的执行过程(event的eventPhase属性能显示出事件处于事件流的哪个阶段 1代表捕获阶段2目标阶段 3 冒泡阶段) 先是捕获阶段处理 显示1 btn haha 接着是目标阶段处理 显示2 接着是冒泡阶段 显示3

<body id='haha'>
<button id="btn">big button</button>
<script type="text/javascript">
var btn = document.getElementById('btn'); btn.onclick = function(event) {
console.log(event.eventPhase);
event.stopPropagation();
}; document.body.addEventListener('click',function(event){console.log(event.eventPhase,event.target.id,event.currentTarget.id);},true); document.body.onclick = function(event) {console.log(event.eventPhase)}; </script>

我在上面相同的代码中在目标阶段的处理函数中加了句event.stopPropagation() 它能立即停止事件在DOM中的传播,取消进一步的捕获或者冒泡

上面的输出是 1 btn hah 2 应为它阻止了事件在冒泡阶段的传播,所以在冒泡阶段的处理函数没有执行

在DOM level3中还引入了另一个方法 stopImmediatePropagation()

它还能阻止当前侦听器的其他侦听器的执行

<body id='haha'>
<button id="btn">big button</button>
<script type="text/javascript">
var btn = document.getElementById('btn'); function hello(event) {
console.log('hello');
event.stopImmediatePropagation(); }
function world(event) {
console.log('world');
} document.body.onclick = function() {
console.log('body');
} btn.addEventListener('click',hello,false);
btn.addEventListener('click',world,false);
</script>

在上面的例子中你将两个事件侦听器的注册顺序改变会发现输出不同的结果,上面的例子中只输出了hello 并且在冒泡阶段body上的处理函数也没有执行

合理的利用冒泡,可以实现事件委托  如下

<body>
<ul id="container">
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
</ul>
</body>

这样的页面结构中我们想单击li时获得li的内容,如果为每一个li都绑定事件侦听器的话,会增加对内存的占用,这时候我们就可以利用冒泡,来实现我们的功能

<ul id="container">
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
</ul> <script type="text/javascript">
var container = document.getElementById('container');
    container.addEventListener('click',function(event){console.log(event.target.innerHTML);},false);
</script>

跨浏览器的通用的事件处理函数

function listenEvent(eventTarget,eventType,eventHandler) {
if(eventTarget.addEventListener) {//DOM level 2
eventTarget.addEventListener(eventType,eventHandler,false);
} else if(eventTarget.attachEvent) {//IE
eventType = "on" + eventType;
eventTarget.attachEvent(eventType,eventHandler);
} else {//DOM level 0
eventTarget["on" + eventType] = eventHandler;
}
}

跨浏览器的通用的停止事件监听函数

function removeListenEvent(eventTarget,eventType,eventHandler) {
if(eventTarget.removeEventListener) {//DOM level 2
eventTarget.removeEventListener(eventType,eventHandler,false);
} else if(eventTarget.detachEvent) {//IE /2016 3 23 改/
eventType = "on" + eventType;
eventTarget.detachEvent(eventType,eventHandler);
} else {//DOM level 0
eventTarget["on" + eventType] = null;
}
}

2016 5 9 封装更好的事件处理程序模块

  var EventUtil = {
addHanler: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;
}
},
/*兼容IE 在IE中DOM0方式绑定事件的时候 获取event对象是window的一个属性 通过attachEvent绑定事件的时候,既可以通过event直接获取事件对象
又可以通过window.event获取事件对象*/
getEvent:function(event) {
return event ? event : window.event;
},
/*当在DOM2的时候 event.target一定指向事件发生的对象 但是在DOM0的绑定事件的时候 window.event.srcElement是this*/
getTarget:function(event){
return event.target || event.srcElement;
},
/*returnValue属性相当于preventDefault()方法*/
preventDefault:function(event) {
if(event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
stopPropagation:function(event){
if(event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelEvent = true;
}
}
}

js事件小记的更多相关文章

  1. js事件相关面试题

    说是面试题,其实也相当于是对js事件部分知识点的一个总结.简单内容一笔带过,了解详情我都给出了参考链接,都是之前写的一些相关文章.JavaScript本身没有事件模型,但是环境可以有. DOM:add ...

  2. dynamic-css 动态 CSS 库,使得你可以借助 MVVM 模式动态生成和更新 css,从 js 事件和 css 选择器的苦海中脱离出来

    dynamic-css 使得你可以借助 MVVM 模式动态生成和更新 css,从而将本插件到来之前,打散.嵌套在 js 中的修改样式的代码剥离出来.比如你要做元素跟随鼠标移动,或者根据滚动条位置的变化 ...

  3. 什么是JS事件冒泡?

    什么是JS事件冒泡?: 在一个对象上触发某类事件(比如单击onclick事件),如果此对象定义了此事件的处理程序,那么此事件就会调用这个处理程序,如果没有定义此事件处理 程序或者事件返回true,那么 ...

  4. js事件技巧方法整合

    window.resizeTo(800,600); //js设置浏览器窗口尺寸 window.open (function(){ resizeTo(640,480);//设置浏览器窗口尺寸 moveT ...

  5. js事件浅析

    js中关于DOM的操作很多,因此js事件机制也就尤为重要. 事件绑定形式: 一. 内联形式 耦合度高,不利于维护 <button onclick="alert('你点击了这个按钮'); ...

  6. js 事件大全

    Js事件大全一般事件 事件 浏览器支持 描述onClick IE3|N2|O3 鼠标点击事件,多用在某个对象控制的范围内的鼠标点击onDblClick IE4|N4|O 鼠标双击事件onMouseDo ...

  7. 原生JS事件绑定方法以及jQuery绑定事件方法bind、live、on、delegate的区别

    一.原生JS事件绑定方法: 1.通过HTML属性进行事件处理函数的绑定如: <a href="#" onclick="f()"> 2.通过JavaS ...

  8. JS事件

    JS事件:  声明:为了事件对象event跨浏览器兼容: var oEvent==ev||event;      所以在下面用到 event 的地方都用 oEvent 代替  1)doucument的 ...

  9. 原生js事件和jquery事件的执行顺序问题

    场景:近日,写前端页面时候,在针对输入框input操作时,用到了jquery的插件,插件中使用了jquery的focus()和blur()方法.但是同时,又需要在插件之外再针对输入框的获取焦点和失去焦 ...

随机推荐

  1. Java Bytecode Instructions List

    monic Opcode(in hex) Other bytes Stack[before]→[after] Description aaload 32   arrayref, index → val ...

  2. Oracle数据库入门——如何根据物化视图日志快速刷新物化视图

    Oracle物化视图的快速刷新机制是通过物化视图日志完成的.Oracle如何通过一个物化视图日志就可以支持多个物化视图的快速刷新呢,本文简单的描述一下刷新的原理. 首先,看一下物化视图的结构:SQL& ...

  3. php 5.4 5.5 如何连接 ms sqlserver

    https://msdn.microsoft.com/en-us/sqlserver/ff657782.aspx

  4. EF执行存储过程时超时问题

    异常信息:Message = EF "Timeout 时间已到.在操作完成之前超时时间已过或服务器未响应." ((IObjectContextAdapter);

  5. MSIL解析一(转)

    转自:http://www.cnblogs.com/Yahong111/archive/2007/08/15/857140.html 在网上发现了一个非常好的MSIL教程,可惜是英文版的,于是就翻译了 ...

  6. [原]Ubuntu 14.04编译Android Kernel

    如何编译android kernel参考官方文档:https://source.android.com/source/building-kernels.html   在Ubuntu 14.04上编译a ...

  7. 线程安全集合 ConcurrentDictionary<TKey, TValue> 类

    ConcurrentDictionary<TKey, TValue> 类 [表示可由多个线程同时访问的键/值对的线程安全集合.] 支持 .NET Framework 4.0 及以上. 示例 ...

  8. css省略号布局实例截图

    过多文字li标签出现使用css省略号样式截图 使用text-overflow样式让显示不完内容通过css实现省略号排版

  9. AC_Dream 1224 Robbers(贪心)

    题意:n个抢劫犯分别抢到的金钱是k1, k2, k3,...,一共得到的金钱是m, 但是在分钱的时候是按照x1/y, x2/y, x3/y,....的比例进行分配的!这样的话 一些抢劫犯就会觉得不公平 ...

  10. [OpenCV] Face Detection

    即将进入涉及大量数学知识的阶段,先读下“别人家”的博文放松一下. 读罢该文,基本能了解面部识别领域的整体状况. 后生可畏. 结尾的Google Facenet中的2亿数据集,仿佛隐约听到:“你们都玩儿 ...