提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
转帖|其它|编辑:郝浩|2011-08-11 15:24:48.000|阅读 513 次
概述:本文主要对Javascript事件进行了一次深入的总结,希望对大家有帮助。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
一、事件冒泡
1.1 事件的不同阶段
Javascript事件在2个阶段执行:捕获与冒泡。
如下图的Dom结构中如果指向锚点#1.1的链接被点击,则依次会触发document > body > ul > li > ul > li > a 的Click处理函数。至此完成捕获阶段。当这阶段完成,开始冒泡阶段,如图中向上箭头的顺序。事件处理函数全部触发。有兴趣可以移步,可以看到动态的过程。
我们对上述代码稍加更改,假如alert,因为那个demo中的效果切换太快了,我们慢一点洗洗体会。【注:这里订阅的事件都是冒泡阶段的,也是最 常用的,因为IE并不支持订阅捕获阶段的时间。比较特殊的还有Opera,常常遇到有些特性向Firefox系,偶尔会有个别特性像IE】。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"//www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="//www.w3.org/1999/xhtml" lang="zh" xml:lang="zh">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="developer" content="Realazy" />
<title>Bubble in JavaScript DOM</title>
<style type="text/css" media="screen">
div * {display:block; margin:4px; padding:4px; border:1px solid white;}
textarea {width:20em; height:2em;}
</style>
<script type="text/javascript">
//<![CDATA[
function init(){
var log = document.getElementsByTagName('textarea')[0];
var all = document.getElementsByTagName('div')[0].getElementsByTagName('*');
for (var i = 0, n = all.length; i < n; ++i){
all[i].onmouseover = function(e){
alert('鼠标现在进入的是: ' + this.nodeName);
this.style.border = '1px solid red';
log.value = '鼠标现在进入的是: ' + this.nodeName;
};
all[i].onmouseout = function(e){
alert('鼠标现在移出的是: ' + this.nodeName);
this.style.border = '1px solid white';
};
}
var all2 = document.getElementsByTagName('div')[1].getElementsByTagName('*');
for (var i = 0, n = all2.length; i < n; ++i){
all2[i].onmouseover = function(e){
this.style.border = '1px solid red';
if (e) //停止事件冒泡
e.stopPropagation();
else
window.event.cancelBubble = true;
log.value = '鼠标现在进入的是: ' + this.nodeName;
};
all2[i].onmouseout = function(e){
this.style.border = '1px solid white';
};
}
}
window.onload = init;
//]]>
</script>
</head>
<body>
<h1>Bubble in JavaScript DOM</h1>
<p>DOM树的结构是:</p>
<pre><code>
UL
- LI
- A
- SPAN
</code></pre>
<div>
<ul>
<li><a href="#"><span>Bubbllllllllllllllle</span></a></li>
<li><a href="#"><span>Bubbllllllllllllllle</span></a></li>
</ul>
</div>
<textarea></textarea>
<p>鼠标进入UL的任何一个子元素,如果不停止冒泡,我们从UL到SPAN都定义了鼠标悬停(<code>mouseover</code>)事件,这个事件会上升了UL,从而从鼠标所进入的元素到UL元素都会有红色的边。</p>
<div>
<ul>
<li><a href="#"><span>Bubbllllllllllllllle</span></a></li>
<li><a href="#"><span>Bubbllllllllllllllle</span></a></li>
</ul>
</div>
<p>如果停止冒泡,事件不会上升,我们就可以获取精确的鼠标进入元素。</p>
</body>
</html>
1.2 取消事件冒泡
其实1.1的代码中已经包含了取消事件冒泡的代码。这里我们专门提出来写,使其具有更好的兼容性与美观。
1 function stopBubble(e) {
2 if (e && e.stopPropagation) {
3 e.stopPropagation(); //因为传入了事件对象e,并且支持W3C标准的stopPropagation()
4 } else {
5 window.event.cancelBubble = true; //For IE
6 }
7 }
【注】:我们不能简单的看到传入了事件对象就判断为非IE浏览器,因为有时候我们使用3.1的方式来绑定事件,此时极有可能也会传入一个window.event的引用。
1.3 重载浏览器默认行为
对于a标签等具有默认行为(如跳转到某URL)的HTML元素,我们可能想要部分a表现的有特色些,点击某a就是不跳转,可以重载其默认行为。
function stopDetault(e) {
if (e&&e.preventDetault) {
e.preventDefault();
} else {
window.event.returnValue = false;
}
return false;
}
使用方法:
document.getElementById("##").onclick = function (e) {
//do sth.
return stopDetault(e);
}
我们也常用下面的方式阻止默认行为,所以阻止事件处理函数本身return false也就可以理解了。
<a href="javascript:alert('clicked');return false;">a link without redirect action</a>
《Pro Javascript Techniques》[美 John Resig]一书中提到95%的情况中防止默认行为都有效,但是偶尔也会失效,因为该行为是由浏览器决定的,尤其是在文本域中防止敲击和iframe内的 行为。除此之外,都应该无大碍。这是一本学习javascript的好书。推荐。
二、 常见事件对象
2.1 this
this 关键字是javascript中提供对当前对象引用的变量。绑定事件时this通常指的是当前元素,但是也有例外!!初接触javascript觉得这个this有点变换莫测,难以捉摸。
如果你的感觉也是这样,可以看看下边的文章:
通常在绑定事件时可以这样使用this
document.getElementById("input1").onclick = function(e){
this.style.color="Red";
};
2.2 事件对象
通过对下面的代码调试我们可以看到,事件对象通常包含当前键码等事件相关信息。值得一提的是IE的实现把事件对象放在一个全局变量window.event变量中保存,而其他遵从W3C标准浏览器则作为一个参数传进处理函数。
三、 事件绑定
各浏览器虽然支持的方式都不太一样,但是相比混乱的CSS,事件绑定还是有章可循的。IE有自己的实现方式,并且各版本统一,其他现代浏览器都按照W3C标准来实现。
3.1 传统Dom绑定
这种方式最简单,最有效。而且this关键词指向的是当前元素。但是缺点也不少,他们是:
1.只能绑定一次。假如我们引用的多个类库中都对window.onload事件进行绑定,则前边的绑定将会被后边的覆盖,并且常常难以察觉。
2.只支持订阅冒泡阶段事件。
3.事件参数只支持非IE,虽然事件对象参数仅支持非IE浏览器,但是我们可以使用下边这种方式解决。
<a onclick="handle(event)" href="#">link</a>
3.2 W3C标准绑定
这个是最开心的方式了,除IE以外的现代浏览器都支持,我们可以直接使用每个dom元素的 addEventListener(eventName,handleFunc,trueOrFalse),第一个参数为订阅的事件名称,如 click(没有on),第二个参数为时间处理函数,第三个参数为是否订阅事件捕获阶段。
下面是使用addEventListener的例子
document.getElementById("linkA").addEventListener('click', function (e) {
alert('i am clicked!');
return stopDetault(e);
}, false);
优点:
1.支持冒泡与捕获阶段。
2.在处理函数内部,this关键字引用当前元素。
3.可以为同一元素的同一时间绑定多个处理函数,不会覆盖。
缺点:
1.IE不支持
3.3 IE绑定
既然上边提到IE不支持addEventListener,那么肯定要找个解决方案帮帮IE小兄弟,那就是attachEvent,虽然有很多缺点,但也够用。
下面是attachEvent的例子
document.attachEvent("onload", function () {
alert("i am load");
});
优点:
1.当然这个优点是和第一种绑定方式相比的:),同一元素支持多次绑定。
缺点:
1.仅支持IE事件的冒泡阶段。
2.事件处理函数内部this关键字引用了window对象。要解决这个问题请继续往下看。
3.事件名前必须加on,当然这个只是叫法不同,也没什么大碍。
4.只支持IE啊,这个很痛啊。
四、 牛人们的解决方案
Dean Edwards的方案:addEvent/removeEvent库
这个方案比较特别。详细请移步
特点: 1 it performs no object detection
2 it does not use the addeventListener/attachEvent methods
3 it keeps the correct scope (the this keyword)
4 it passes the event object correctly
5 it is entirely cross-browser (it will probably work on IE4 and NS4)
6 and from what I can tell it does not leak memory
源码:
function handleEvent(event) {
var returnValue = true;
// grab the event object (IE uses a global event object)
event = event || fixEvent(window.event);
// get a reference to the hash table of event handlers
var handlers = this.events[event.type];
// execute each event handler
for (var i in handlers) {
this.$$handleEvent = handlers[i];
if (this.$$handleEvent(event) === false) {
returnValue = false;
}
}
return returnValue;
};
function fixEvent(event) {
// add W3C standard event methods
event.preventDefault = fixEvent.preventDefault;
event.stopPropagation = fixEvent.stopPropagation;
return event;
};
fixEvent.preventDefault = function() {
this.returnValue = false;
};
fixEvent.stopPropagation = function() {
this.cancelBubble = true;
};
【注】:这个方案有一个致命的东西,千万不要这样做这样会覆盖之前绑定的处理函数
<body onload="alert('hi');"></body>
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
文章转载自:博客园面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@pclwef.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢