优化网站设计(二十六):设计“智能”的事件处理程序
2013-05-19 11:57
405 查看
前言
网站设计的优化是一个很大的话题,有一些通用的原则,也有针对不同开发平台的一些建议。这方面的研究一直没有停止过,我在不同的场合也分享过这样的话题。作为通用的原则,雅虎的工程师团队曾经给出过35个最佳实践。这个列表请参考BestPracticesforSpeedingUpYourWebSite(准备工作
为了跟随我进行后续的学习,你需要准备如下的开发环境和工具GoogleChrome或者firefox,并且安装VisaulStudio2010SP1或更高版本,推荐使用VisualStudio2012
你需要对ASP.NET的开发基本流程和核心技术有相当的了解,本系列文章很难对基础知识做普及。
本文要讨论的话题
这一篇我和大家讨论的是第二十六条原则:<%@PageLanguage="C#"AutoEventWireup="true"CodeBehind="WebForm1.aspx.cs"Inherits="WebApplication4.WebForm1"%> <!DOCTYPEhtml> <htmlxmlns="http://www.w3.org/1999/xhtml"> <headrunat="server"> <title></title> </head> <body> <formid="form1"runat="server"> <divid="testdiv"> <inputtype="button"value="button1"/> <inputtype="button"value="button2"/> <inputtype="button"value="button3"/> <inputtype="button"value="button4"/> <inputtype="button"value="button5"/> <inputtype="button"value="button6"/> <inputtype="button"value="button7"/> </div> </form> <scriptsrc="Scripts/jquery-2.0.0.min.js"></script> <scripttype="text/javascript"> $(function(){ $("input[type=button]").click(function(event){ alert("ButtonClicked:"+$(this).val()); }); }); </script> </body> </html>
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
这样做当然是没有问题的,这是最直接和“正常”的用法。但如果细想一下的话,上述的代码,其实是为每个按钮控件都绑定了一个处理程序。如果按钮有很多(例如100个),那么就需要产生100个事件的绑定。过多的事件绑定会对性能有所影响。
利用DOM事件的冒泡机制,我们可以将代码改写成下面这样:
<%@PageLanguage="C#"AutoEventWireup="true"CodeBehind="WebForm1.aspx.cs"Inherits="WebApplication4.WebForm1"%> <!DOCTYPEhtml> <htmlxmlns="http://www.w3.org/1999/xhtml"> <headrunat="server"> <title></title> </head> <body> <formid="form1"runat="server"> <divid="testdiv"> <inputtype="button"value="button1"/> <inputtype="button"value="button2"/> <inputtype="button"value="button3"/> <inputtype="button"value="button4"/> <inputtype="button"value="button5"/> <inputtype="button"value="button6"/> <inputtype="button"value="button7"/> </div> </form> <scriptsrc="Scripts/jquery-2.0.0.min.js"></script> <scripttype="text/javascript"> $(function(){ $("#testdiv").click(function(event){ varbt=$(event.target); alert("DivClicked:"+bt.val()); }); }); </script> </body> </html>
我们看到,在这个改进的版本中,没有直接对按钮进行事件绑定,而是为它们的容器控件(DIV)做了一个事件绑定。如果你运行起来,实际上的效果和之前那一次是一样的:点击每个按钮,分别会弹出一个对话框,显示当前按钮的文本。
这是怎么回事呢?总结起来说,DOM元素的一些事件(例如click)会按照下面的方式运作的:
用户点击了按钮,首先会去查找按钮上面有没有直接绑定事件处理程序,如果有的话,先执行这个事件处理程序;
然后会尝试查找按钮的上层元素是否有绑定相应的事件处理程序,如果有,则也会执行。
再往上查找,只要有相应的事件注册,都会被执行,直到最顶层的BODY为止。
这就是“冒泡”的意思。同时,这种事件机制还有一种叫法:事件代理。
一个附加的问题是:如果我们既在按钮上面订阅了事件,而且也在DIV上面订阅了事件,那么会不会同时都会被触发了。
<%@PageLanguage="C#"AutoEventWireup="true"CodeBehind="WebForm1.aspx.cs"Inherits="WebApplication4.WebForm1"%>
<!DOCTYPEhtml>
<htmlxmlns="http://www.w3.org/1999/xhtml">
<headrunat="server">
<title></title>
</head>
<body>
<formid="form1"runat="server">
<divid="testdiv">
<inputtype="button"value="button1"/>
<inputtype="button"value="button2"/>
<inputtype="button"value="button3"/>
<inputtype="button"value="button4"/>
<inputtype="button"value="button5"/>
<inputtype="button"value="button6"/>
<inputtype="button"value="button7"/>
</div>
</form>
<scriptsrc="Scripts/jquery-2.0.0.min.js"></script>
<scripttype="text/javascript">
$(function(){
$("input[type=button]").click(function(event){
alert("ButtonClicked:"+$(this).val());
});
$("#testdiv").click(function(event){
varbt=$(event.target);
alert("DivClicked:"+bt.val());
});
});
</script>
</body>
</html>
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
答案是:他们都会被执行。
那么,如果我想在某些情况下,只触发按钮直接订阅的事件,而不触发DIV订阅的事件(阻止将事件冒泡),行不行呢?当然是可以的,你可以添加下面这样的代码
<%@PageLanguage="C#"AutoEventWireup="true"CodeBehind="WebForm1.aspx.cs"Inherits="WebApplication4.WebForm1"%>
<!DOCTYPEhtml>
<htmlxmlns="http://www.w3.org/1999/xhtml">
<headrunat="server">
<title></title>
</head>
<body>
<formid="form1"runat="server">
<divid="testdiv">
<inputtype="button"value="button1"/>
<inputtype="button"value="button2"/>
<inputtype="button"value="button3"/>
<inputtype="button"value="button4"/>
<inputtype="button"value="button5"/>
<inputtype="button"value="button6"/>
<inputtype="button"value="button7"/>
</div>
</form>
<scriptsrc="Scripts/jquery-2.0.0.min.js"></script>
<scripttype="text/javascript">
$(function(){
$("input[type=button]").click(function(event){
alert("ButtonClicked:"+$(this).val());
window.event.cancelBubble=true;
});
$("#testdiv").click(function(event){
varbt=$(event.target);
alert("DivClicked:"+bt.val());
});
});
</script>
</body>
</html>
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
所以,通过本文,我们了解到事件远非我们看到的那么简单。通过理解“冒泡”或者“事件代理”,我们可以将事件处理得更加合理。
值得一说的是,在桌面开发的WPF和Silverlight中,很多事件也同样采用了“冒泡”这样的策略,有兴趣的朋友可以参考:
.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}
相关文章推荐
- 优化网站设计(二十六):设计“智能”的事件处理程序
- JS注册/移除事件处理程序(ExtJS应用程序设计实战)
- seo教程之百度权重对网站程序的代码优化设计要求
- JS注册/移除事件处理程序(ExtJS应用程序设计实战)
- 事件处理程序
- 关于大型网站技术演进的思考(二十一)--网站静态化处理―web前端优化―下【终篇】(13)
- python3+PyQt5重新实现QT事件处理程序
- 深入理解DOM事件机制系列第二篇——事件处理程序
- 优化网站设计(一):减少请求数
- java处理高并发高负载类网站的优化方法
- 浅析嵌入式程序设计中的优化问题
- QT 程序全屏 与 ESC退出事件处理
- SSE指令指令集进行程序加速、DCT的优化处理
- Java NIO 与 基于reactor设计模式的事件处理模型
- 通过给事件处理程序传递this参数,获取事件源对象的引用。单机提交按钮时在信息框中显示用户输入的字符。
- 在C# WinForm程序中创建控件数组及相应的事件处理
- 文本框的简单事件处理程序
- 【js学习笔记-091】-----------注册事件处理程序
- js使用函数绑定技术改变事件处理程序的作用域
- 关于大型网站技术演进的思考(二十)--网站静态化处理—web前端优化—中(12)