WEB前端最常见驱动方式就是事件了, 所有交互等等都是通过事件,前端的常见事件有:

UI事件;
焦点事件;
鼠标事件;
滚轮事件;
文本事件;
键盘事件;
变动事件;

  现在网页上有一个输入框, 如果我们要对用户输入的字符串进行过滤, 或者是截获用户的输入进行处理的话, 我们要肿么办

  同学们纷纷举手说:“老师,我知道,是使用添加事件“,

  老师也很欣慰地点了点头, 这群家伙真的是越来越聪明了,

  老师又问了”如果要取消用户的输入怎么办了“,

  坐在最前排眼睛最小的同学急忙说”ev.preventDefault(),ev.returnValue = false;"

  老师又说“不错啊,都学会抢答了啊, 我裤子都脱了, 你就答这个2?”

  

  过了一秒钟, 又一位同学主动跑到黑板这边写了如下的代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>MAKER</title>
</head>
<body>
<div id="log">
Log:
</div>
<input id="text">data</input> <script>
window.onload = init; if(console&&console.log) {
var originalLog = console.log;
var log = document.getElementById("log");
console.log = function(arg) {
var eDiv = document.createElement("div");
eDiv.innerHTML = typeof arg === "string" ? arg : arg.toString();
log.appendChild( eDiv );
originalLog.apply(console, arguments);
};
}; function init () {
var eText = document.getElementById("text");
eText.addEventListener("keypress", function( ev ) {
//逻辑全部在这里面, 很简单吧;
var code = ev.which = ev.which || ev.keyCode || ev.charCode;
console.log( code );
if(code > 80) {
console.log("code>80");
};
if(ev.shiftKey === true) {
console.log("shift key is pressed!")
}
});
};
</script>
</body>
</html>

  "哎哟,不错哦,这个*x"老师说道:"这个就是我们最常用的方法, 直接为元素绑定了keypress事件,然后通过这个事件的回调对用户的输入进行处理";

  如果在事件里面的代码多了, 我们又可以把事件的代码单独取出来作为一个函数:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>MAKER</title>
</head>
<body>
<div id="log">
Log:
</div>
<input id="text">data</input> <script>
window.onload = init; if(console&&console.log) {
var originalLog = console.log;
var log = document.getElementById("log");
console.log = function(arg) {
var eDiv = document.createElement("div");
eDiv.innerHTML = typeof arg === "string" ? arg : arg.toString();
log.appendChild( eDiv );
originalLog.apply(console, arguments);
};
};
var 我是事件 = function(ev) {
//逻辑全部在这里面, 很简单吧;
var code = ev.which = ev.which || ev.keyCode || ev.charCode;
console.log( code );
if(code > 80) {
console.log("code>80");
};
if(ev.shiftKey === true) {
console.log("shift key is pressed!")
};
};
function init () {
var eText = document.getElementById("text");
eText.addEventListener("keypress", function( ev ) {
我是事件(ev);
});
};
</script>
</body>
</html>

  看起来清楚多了是吧, 但是在大的项目中(我说的是如果哇), 我们想要充分解耦代码, 可以事件里面的代码全部重新分开:

  函数1 :console.log( code );

  函数2:

  if(code > 80) {

      console.log("code>80");

  };
 函数3: 
 if(ev.shiftKey === true) {
   console.log("shift key is pressed!")
 };
 好吧,现在问题来了....
 
 现在有要上菜了哇, JS中的自定义事件, 充分利用JS的事件机制,
 
抄自百科:对于自定义事件最需要了解的一点是,您的代码必须导致这些事件发生。这些事件不会为响应用户或系统的动作而自动发生,即使能够编写导致事件确实以这种方式发生的代码也不例外。包含自定义事件的类模块还必须包括一个唤起事件的公有方法。这个方法通过调用 RaiseEvent 语句并传入为事件定义的任何参数来唤起事件。这些参数按顺序传入为响应事件而运行的事件过程中
 自定义事件就是一种的设计模式,比如订阅者发布者模式, 观察者模式等等, 都是自定义事件基础上的模式(个人观点, 勿拍砖), 关键是很多大神写代码喜欢用这一种模式写, 那么我们也可以借鉴, 这样就够了;
 我们现在把上面那段通过自定义事件的方式写出来:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>MAKER</title>
</head>
<body>
<script>
//d为目标对象, b为一个函数对象;
var __extends = this.__extends || function (d, b) {
//继承了静态属性
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
//继承了原型
__.prototype = b.prototype;
d.prototype = new __();
}; var EventEmitter = (function () {
function EventEmitter() {
this._events = {};
}
EventEmitter.prototype.emit = function (type) {
var _this = this;
var args = [];
for (var _i = 0; _i < (arguments.length - 1); _i++) {
args[_i] = arguments[_i + 1];
}
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events[type] || (Array.isArray(this._events[type]) && !this._events[type].length)) {
if (args[0] instanceof Error) {
throw args[0];
} else {
throw new Error("Uncaught, unspecified 'error' event.");
}
return false;
}
}
if (this._events[type]) {
this._events[type].forEach(function (handler) {
return handler.apply(_this, args);
});
return true;
}
return false;
}; EventEmitter.prototype.addListener = function (type, listener) {
if ('function' !== typeof listener) {
throw new Error('addListener only takes instances of Function');
}
var events = this._events;
var listeners = events[type];
if (!listeners)
listeners = events[type] = [];
else if (listeners.indexOf(listener) >= 0)
return this;
listeners.push(listener);
return this;
}; EventEmitter.prototype.removeListener = function (type, listener) {
var events = this._events;
if (!events[type])
return this;
var listeners = events[type];
var i = listeners.indexOf(listener);
if (i >= 0)
listeners.splice(i, 1);
return this;
};
return EventEmitter;
})(); //写一个小的案例, 为了充分解耦代码, 我们可以把代码通过自定义的事件分成几个模块; </script> <input id="text">data</input> <script>
window.onload = init;
function init () {
var TextEvent = (function(Emiter) {
__extends(TextEvent, Emiter);
function TextEvent() {
Emiter.apply(this);
};
return TextEvent;
}.call(TextEvent,EventEmitter)); //创建了这个实例;
var textEvent = new TextEvent(); //为实例添加自定义事件;
textEvent.addListener("keypress", function preventDefault(ev) {
ev.preventDefault();
});
//为实例添加自定义事件;
textEvent.addListener("keypress", function(ev) {
var code = ev.which = ev.which || ev.keyCode || ev.charCode;
console.log( code );
});
//为实例添加自定义事件;
textEvent.addListener("keypress", function(ev) {
var code = ev.which = ev.which || ev.keyCode || ev.charCode;
if(code > 80) {
console.log("code>80");
};
});
//为实例添加自定义事件;
textEvent.addListener("keypress", function(ev) {
var code = ev.which = ev.which || ev.keyCode || ev.charCode;
if(ev.shiftKey === true) {
console.log("shift key is pressed!")
};
}); document.getElementById("text").addEventListener("keypress", function( ev ) {
textEvent.emit("keypress",ev)
});
};
</script>
</body>
</html>

  楼主你他妈在逗我? 这么多

 实现要懂JS的继承:
        //d为目标对象, b为一个函数对象;
var __extends = this.__extends || function (d, b) {
//继承了静态属性
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
//继承了原型
__.prototype = b.prototype;
d.prototype = new __();
};

  其次呢, 自定义事件的代码要懂, 很多地方都有用到;

        var EventEmitter = (function () {
function EventEmitter() {
this._events = {};
}
EventEmitter.prototype.emit = function (type) {
var _this = this;
var args = [];
for (var _i = 0; _i < (arguments.length - 1); _i++) {
args[_i] = arguments[_i + 1];
}
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events[type] || (Array.isArray(this._events[type]) && !this._events[type].length)) {
if (args[0] instanceof Error) {
throw args[0];
} else {
throw new Error("Uncaught, unspecified 'error' event.");
}
return false;
}
}
if (this._events[type]) {
this._events[type].forEach(function (handler) {
return handler.apply(_this, args);
});
return true;
}
return false;
}; EventEmitter.prototype.addListener = function (type, listener) {
if ('function' !== typeof listener) {
throw new Error('addListener only takes instances of Function');
}
var events = this._events;
var listeners = events[type];
if (!listeners)
listeners = events[type] = [];
else if (listeners.indexOf(listener) >= 0)
return this;
listeners.push(listener);
return this;
}; EventEmitter.prototype.removeListener = function (type, listener) {
var events = this._events;
if (!events[type])
return this;
var listeners = events[type];
var i = listeners.indexOf(listener);
if (i >= 0)
listeners.splice(i, 1);
return this;
};
return EventEmitter;
})();

  最后通过组合继承, 实现了一个自定义事件类方法:

            var TextEvent = (function(Emiter) {
__extends(TextEvent, Emiter);
function TextEvent() {
Emiter.apply(this);
};
return TextEvent;
}.call(TextEvent,EventEmitter));

  

  我们通过实例化TextEvent, 为这个实例添加自定义的方法;

  在onkeypress的事件回调触发自定义事件textEvent.emit("keypress",ev), 最后的最后只要为textEvent绑定自定义事件即可,这样做的优势就是: 我们可以通过removeListener去除事件, 事件函数也可以直接复用, 很灵活;

 

D

JavaScript使用自定义事件实现简单的模块化开发的更多相关文章

  1. 详解javascript实现自定义事件

    这篇文章主要为大家介绍了javascript实现自定义事件的方法,自定义事件,顾名思义,就是自己定义事件类型,自己定义事件处理函数,javascript如何实现自定义事件,需要了解的朋友可以参考下 我 ...

  2. Javascript之自定义事件

    Javascript自定义事件,其本质就是观察者模式(又称订阅/发布模式),它的好处就是将绑定事件和触发事件相互隔离开,并且可以动态的添加.删除事件. 下面通过实例,一步一步构建一个具体的Javasc ...

  3. javascript中自定义事件

    自定义事件:用户可以指定事件类型,这个类型实际上就是一个字符串,然后为这个类型的事件指定事件处理函数,可以注册多个事件处理函数(用数组管理),调用时,从多个事件处理函数中找到再调用. function ...

  4. 使用jQuery在javascript中自定义事件

    js中的自定义事件有attachEvent,addEventListener等等好多种,往往受困于浏览器兼容,而且代码写起来也相当麻烦.jQuery为我们解决了这个问题,几行代码就可以很好的实现事件的 ...

  5. 利用javascript(自定义事件)记录尺寸可变元素的尺寸变化过程

    1.效果图 2.源码 <%@ page contentType="text/html;charset=UTF-8" language="java" %&g ...

  6. javascript和jquey的自定义事件小结

    “通过事件机制,可以将类设计为独立的模块,通过事件对外通信,提高了程序的开发效率.” 可以把多个关联但逻辑复杂的操作利用自定义事件的机制灵活地控制好 对象之间通过直接方法调用来交互 1)对象A直接调用 ...

  7. Qt 学习之路:自定义事件

    尽管 Qt 已经提供了很多事件,但对于更加千变万化的需求来说,有限的事件都是不够的.例如,我要支持一种新的设备,这个设备提供一种崭新的交互方式,那么,这种事件如何处理呢?所以,允许创建自己的事件 类型 ...

  8. Spring(十)之自定义事件

    编写自定义事件的简单流程如下: (1)编写CustomEvent.java package com.tutorialspoint; import org.springframework.context ...

  9. Qt 学习之路 2(23):自定义事件

    Qt 学习之路 2(23):自定义事件  豆子  2012年10月23日  Qt 学习之路 2  21条评论 尽管 Qt 已经提供了很多事件,但对于更加千变万化的需求来说,有限的事件都是不够的.例如, ...

随机推荐

  1. AC日记——单词翻转 1.7 27

    27:单词翻转 总时间限制:  1000ms 内存限制:  65536kB 描述 输入一个句子(一行),将句子中的每一个单词翻转后输出. 输入 只有一行,为一个字符串,不超过500个字符.单词之间以空 ...

  2. codevs 1082 线段树练习3

    1082 线段树练习 3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题解       题目描述 Description 给你N个数,有两种操作: 1: ...

  3. u3d_shader_surface_shader_1

    http://docs.unity3d.com/Manual/SL-SurfaceShaders.html 一:surface shader是啥 Writing shaders that intera ...

  4. U-BOOT-Linux启动指令bootm分析

    首先说一下uImage和zImage的区别 uImage是在zImage之前加上信息头.包含系统类型.是否压缩及压缩方式等 bootm命令只能启动uImage 幻数:说得再好听的名字也只不过是个0~0 ...

  5. SQL2012连接字符串

    安装了sqlserver2012数据库,测试一包代码,搜索网上的方法,死活连接不上,最后偶然测试通过,居然是连接字符串的问题. “如果开发软件的时候是在局域网或者是在本机,并且数据库不在远程计算机上面 ...

  6. maven总结5

    上篇文章中项目最终发布的release仓库和快照仓库都是nexus的默认仓库,若所有的本地开发项目版本都发布到同一个仓库,可能会造成冲突.因此,我们可以为每一个项目创建一组仓库(快照版本和releas ...

  7. Android三种播放视频的方式

    在Android中,我们有三种方式来实现视频的播放: 1.使用其自带的播放器.指定Action为ACTION_VIEW,Data为Uri,Type为其MIME类型. 2.使用VideoView来播放. ...

  8. JavaScript Math 对象

    JavaScript Math 对象 Math 对象 Math 对象用于执行数学任务. Math 对象并不像 Date 和 String 那样是对象的类,因此没有构造函数 Math(). 语法 var ...

  9. codevs 1281 Xn数列

    题目描述 Description 给你6个数,m, a, c, x0, n, g Xn+1 = ( aXn + c ) mod m,求Xn m, a, c, x0, n, g<=10^18 输入 ...

  10. salt基本原理

            转载自: 来自:http://tech.mainwise.cn/?p=438     说明:salt是一个异构平台基础设置管理工具(虽然我们通常只用在Linux上),使用轻量级的通讯器 ...