第七章 事件处理

7.1 典型用法

作者首先给了个我们一个处理事件的方法。看起来也没啥俩样,不过后来给出的优化方法很值得学习:

         // 不好的写法
function handleClick(event) {
var popup = document.getElementById("popup");
popup.style.left = event.clientX + "px";
popup.style.top = event.clientY + "px";
pop.className = "reveal";
} // 一个事件绑定事件(第5章的)
addListener(element, "click", handleClick);

作者补充了一句:这段代码只用到了event对象的俩个属性:clientX和clientY。在将元素显示在页面里之前先用这俩个属性给它做定位。

尽管这段代码开起来非常简单且没有什么问题,但实际上是不好的写法,因为这种做法有其局限性。

7.2 规则 1:隔离应用逻辑

首先,这段代码的应用逻辑(application logic)和用户行为混在一起了。就是说:这个事件的处理方法和点击事件连在一起了,从而导致耦合度的提高。

这个情况其他语言中也很常见,通常我们将处理逻辑封装起来从而可以把代码重用,所以作者提出了很重要的思想:

将应用逻辑从所有事件处理程序中抽离出来的做法是一种最佳实践。

将代码重构一下变成这样:

         // 好的写法 - 拆分应用逻辑
var MyApplication = {
handleClick: function(event){
this.showPopUp(event);
}, showPopUp: function(event) {
var popup = document.getElementById("popup");
popup.style.left = event.clientX + "px";
popup.style.top = event.clientY + "px";
popup.className = "reveal";
}
}; addListener(element, "click", function(event) {
MyApplication.handleClick(event);
});

7.3 规则2:不要分发事件对象

上述代码还存在一个问题:即event对象被无节制地分发。event对象上包含很多的和事件相关的额外信息,而这段代码只用到了其中俩个而已。

作者提供了俩个理由:

  1. 方法接口并没有表明那些数据是必要的。好的API一定是对于期望和依赖都是透明的。(译者在此也加了译注:大多数情况并不理想,主要看第二点)。
  2. 方便测试

最佳的办法是让事件处理程序使用event对象来处理事件,然后拿到所有需要的数据传给应用逻辑。

将代码重构一下:

         // 好的写法
var MyApplication = { handleClick: function(event){
this.showPopUp(event.clientX,event.clientY); // 这里标明所期待传入的参数
}, showPopUp: function(x,y) { // 这里的参数就不再依赖event咯
var popup = document.getElementById("popup");
popup.style.left = x + "px";
popup.style.top = y + "px";
popup.className = "reveal";
}
}; addListener(element, "click", function(event) {
MyApplication.handleClick(event);
});

测试时或者代码的任意位置都很轻易调用这段逻辑:

         // 这样调用非常棒
MyApplication.showPopUp(10, 10);

最后,当处理事件时,最好让事件处理程序成为接触到event对象的唯一的函数。事件处理程序应当在进入应用逻辑之前针对event对象执行任何必要的操作,包括阻止默认事件或阻止事件冒泡,都应当直接包含在事件程序中。

         // 好的写法
var MyApplication = { handleClick: function(event){ // 假设事件支持DOM Level2
event.preventDefault();
event.stopPropagation(); // 传入应用逻辑
this.showPopUp(event.clientX,event.clientY);
}, showPopUp: function(x,y) {
var popup = document.getElementById("popup");
popup.style.left = x + "px";
popup.style.top = y + "px";
popup.className = "reveal";
}
};

在这段代码中,MyApplication.handleClick()是事件处理程序,因此它在数据传入应用逻辑之前调用 event.preventDefault()和 event.stopPropagation(),这清楚的展示了事件处理程序和应用逻辑之间的分工。因为应用逻辑不需要对event产生依赖,进而在很多地方都可以轻松地使用相同的业务逻辑,包括写测试代码。

读《编写可维护的JavaScript》第七章总结的更多相关文章

  1. 读《编写可维护的JavaScript》第一章总结

    第一章 基本的格式化 1.4 ① 换行 当一行长度到达了单行最大的字符限制时,就需要手动将一行拆成俩行.通常我们会在运算符后换行,下一行会增加俩个层级的缩进. // 好的做法: 在运算符后换行,第二行 ...

  2. [已读]编写可维护的javascript

    13年4月份出版,作者是大名鼎鼎的Zakas,他的另两本书<javascript高级程序设计>与<高性能javascript>你一定听过或者读过. 这本书重点讲了编码风格和编码 ...

  3. 【读书笔记】读《编写可维护的JavaScript》 - 编程实践(第二部分)

    本书的第二个部分总结了有关编程实践相关的内容,每一个章节都非常不错,捡取了其中5个章节的内容.对大家组织高维护性的代码具有辅导作用. 5个章节如下—— 一.UI层的松耦合 二.避免使用全局变量 三.事 ...

  4. 拯救一切强迫症 - 读《编写可维护的 JavaScript》(一)

    拯救一切强迫症 - 读<编写可维护的 JavaScript>(一) 本文写于 2020 年 4 月 24 日 我在小学的时候就有接触过编程,所以读大一的时候 C 语言还算是轻车熟路.自然会 ...

  5. 《编写可维护的javascript》读书笔记(上)

    最近在读<编写可维护的javascript>这本书,为了加深记忆,简单做个笔记,同时也让没有读过的同学有一个大概的了解. 一.编程风格 程序是写给人读的,所以一个团队的编程风格要保持一致. ...

  6. 编写可维护的JavaScript 收纳架

    如果你看过Nicolas C.Zakas写过的任何作品,你必须承认他是个不折不扣的天才.也只有天才级的才能写出<JavaScript高级程序设计>让所有的前端攻城师人手一本.Nicolas ...

  7. 推荐一本好书:编写可维护的JavaScript(可下载)

    目录 推荐一本好书:编写可维护的JavaScript(可下载) 书摘: 下载: 有些建议: 推荐一本好书:编写可维护的JavaScript(可下载) 书摘: 很多设计模式就是为了解决紧耦合的问题.如果 ...

  8. 《编写可维护的JavaScript》之编程实践

    最近读完<编写可维护的JavaScript>,让我受益匪浅,它指明了编码过程中,需要注意的方方面面,在团队协作中特别有用,可维护性是一个非常大的话题,这本书是一个不错的起点. 本书虽短,却 ...

  9. 编写可维护的Javascript读书笔记

    写在前面:之前硬着头皮参加了java方面的编程规范培训,收货良多,工作半年有余的时候,总算感觉到一丝丝Coding之美,以及造轮子的乐趣,以至于后面开发新功能的时候,在Coding style方面花了 ...

  10. 《编写可维护的javascript》读书笔记(中)——编程实践

    上篇读书笔记系列之:<编写可维护的javascript>读书笔记(上) 上篇说的是编程风格,记录的都是最重要的点,不讲废话,写的比较简洁,而本篇将加入一些实例,因为那样比较容易说明问题. ...

随机推荐

  1. uva 147 Dollars

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  2. echarts 用marlkline画线 同时配置中含有datazoom,怎么设置markline

    由于项目需要设置边界值即用markline 画标线,通过echarts文档可以查看到(如下) 1.通过坐标点(xAxis和yAxis的设置) 通过网上搜索许多markline的配置都是通过下面来设置的 ...

  3. hdu 1004 Let the Balloon Rise

    Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

  4. 自定义 JSON 对象

    针对 IE9 以下不支持 JSON 对象的处理方式,网上大部分自定义的方式无形之中都会将中文转码为 Unicode 编码格式的字符换,但是在浏览器中我们有无法察觉到(浏览器自己解析成 UTF8 了), ...

  5. html5,增加flash插件

    <embed src="2.swf" type="" width="500" height="" >< ...

  6. maven 构建一个web项目

    maven已经大型的Java项目的管理工具,其功能非常强大,这里简单总结一下maven构建web项目的过程.本文介绍的是集成环境下的maven构建web项目. 一.准备 1.安装maven. 2.把m ...

  7. C#如何反射出委托的签名,如何使用反射调用委托

    本文阐述C#中如何反射出委托的签名,假如我们有委托FooDelegate定义如下 delegate double FooDelegate (string param, bool condition); ...

  8. 学习笔记:MySQL列属性

    列属性 a)         null|not null 缺省值是null,也就是允许为空,如果是not null而又没有给该字段赋值的话,系统会首先查询该字段有没有默认值 b)         de ...

  9. Subversion Edge

    http://www.collab.net/downloads/subversion#tab-1

  10. iOS 图片的按照比例拉伸

    // 这是一个UIImage 的分类 (  UIImage+Extension.h   ) UIImage+Extension.h #import <UIKit/UIKit.h> @int ...