|
张波老师
- 管理员
- 5017
- 626
-
2009-11-04
|
张波老师
2010-07-27 02:14
|只看楼主
1#
t
T
- <!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>
- <title>使用javascript模拟观察者模式和事件监听广播机制 - 作者:张波 [email]zhangbo99@gmail.com[/email]</title>
- <style type="text/css">
- div.box
- {
- float: left;
- width: 300px;
- border: solid 2px blue;
- height: 50px;
- margin-right: 5px;
- }
- #txt
- {
- display: block;
- }
- </style>
- <script type="text/javascript">
- //张波
- //Email:zhangbo99@gmail.com
- //观察者模式的主题
- function ObserverSubject(id)
- {
- this.ID = id; //实例的ID
- this._Listeners = new Array(); //存储当前所有监听器
- this.AddListener = function (listener)//添加新的监听器
- {
- this._Listeners.push(listener); //监听器加入数组
- };
- this.RemoveListener = function (listener, RemovingCallBack, RemovedCallback) //删除特定监听器,传入删除前回调委托和删除后回调委托
- {
- for (var i in this._Listeners) {//遍历当前所有监听器
- if (this._Listeners[i] == listener) { //如果存在要删除的监听器
- if (RemovingCallBack != undefined && typeof (RemovingCallBack) == "function") {//如果有传入删除前回调委托
- var removingEventArgs = { Cancel: false }; //定义回调委托参数
- RemovingCallBack(listener, removingEventArgs); //调用删除前回调委托
- if (!removingEventArgs.Cancel) {//如果在删除前回调委托中没有取消删除操作
- this._Listeners.splice(i, 1); //从当前数组中删除监听器
- if (RemovedCallback != undefined && typeof (RemovedCallback) == "function") { //如果有传入删除后回调委托
- RemovedCallback(listener, i); //调用删除后回调委托
- }
- }
- }
- break; //已找到要删除的监听器,后面的不需要再遍历
- }
- }
- };
- this.ClearListeners = function (ClearingCallBack, ClearedCallBack)//清空所有监听器,传入清空前回调委托和清空后回调委托
- {
- if (ClearingCallBack != undefined && typeof (ClearingCallBack) == "function") {//如果有传入删除前回调委托
- var args = { ListenersCount: this._Listeners.length, Cancel: false }; //定义回调委托参数,ListenersCount:当前要清空多少监听器,Cancel:是否取消操作
- ClearingCallBack(this, args); //调用清空前回调委托
- if (!args.Cancel) {//如果在清空前回调委托中没有取消清空操作
- this._Listeners.length = 0; //清空当前数组中所有元素(监听器)
- if (ClearedCallBack != undefined && typeof (ClearedCallBack) == "function") {//如果有传入删除后回调委托
- ClearedCallBack(); //调用清空后的回调委托,这里没有再传额外参数
- }
- }
- }
- };
- this.EventBroadcast = function (args)//激发事件,实现广播通知(Notify)所有监听器
- {
- for (var i in this._Listeners) {//遍历当前所有监听器
- var listener = this._Listeners[i]; //单独取出当前的监听器
- listener(args); //调用监听器(函数,委托),args参数原样传递(推给监听器)
- }
- };
- };
- var observer = new ObserverSubject("textElementSubject"); //定义一个可供监听的主题(Subject),以演示使用效果
- //以下定义第1个监听器,在div1中显示,干净格式
- var listener1 = function (args)
- {
- document.getElementById("div1").innerHTML = "第1个Listener收到消息:" + args;
- };
- //以下定义第2个监听器,在div2中显示,删除线格式
- var listener2 = function (args)
- {
- document.getElementById("div2").innerHTML = ("第2个Listener收到消息:" + args).strike();
- };
- //以下定义第3个监听器,在div3中显示,斜体格式
- var listener3 = function (args)
- {
- document.getElementById("div3").innerHTML = ("第3个Listener收到消息:" + args).italics();
- };
- //以下定义第4个监听器,在div4中显示,粗体格式
- var listener4 = function (args)
- {
- document.getElementById("div4").innerHTML = ("第4个Listener收到消息:" + args).bold();
- };
- window.onload = function ()//页面初始化
- {
- observer.AddListener(listener1); //向Subject注册第1个监听器(委托)
- observer.AddListener(listener2); //向Subject注册第2个监听器(委托)
- observer.AddListener(listener3); //向Subject注册第3个监听器(委托)
- observer.AddListener(listener4); //向Subject注册第4个监听器(委托)
- observer.AddListener(function (args)//向Subject注册匿名监听器(委托)
- {
- //alert("通过alert显示收到的消息:" + args);//监听器处理使用alert处理
- });
- observer.AddListener(function (args)//向Subject注册匿名监听器(委托)
- {
- document.title = "在标题栏中显示收到的消息:" + args; //监听器处理使用标题栏处理
- });
- observer.AddListener(function (args)//向Subject注册匿名监听器(委托)
- {
- window.status = "在状态栏中显示收到的消息:" + args; //监听器处理使用状态栏处理
- });
- document.getElementById("txt").onkeyup = function ()//为txt元素注册keyup事件处理程序,这里的txt元素是实际的Subject
- {
- observer.EventBroadcast(this.value); //激发Subject(observer变量)的事件,由其通知所有监听器,实现广播;
- };
- };
- function Add()//为Subject注册第3个监听器:listener3
- {
- observer.AddListener(listener3);
- }
- function Remove()//为Subject删除第3个监听器:listener3
- {
- observer.RemoveListener(listener3, function (sender, args)//调用删除方法,并传入要删除的委托实例(监听器),和匿名委托作为RemovingCallBack参数
- {
- args.Cancel = !confirm("将要删除监听委托:\r\n" + sender + "\r\n确定吗?"); //让用户确认是否要删除
- }, function (listener, indexInArray)//传入匿名委托作为RemovedCallBack参数
- {
- document.getElementById("div3").innerHTML = listener + "<br/>已删除,<br/>它在Observer中的索引为:" + indexInArray; //显示删除后的结果和参数
- });
- }
- function Clear()//清空所有已经注册的监听器
- {
- observer.ClearListeners(function (sender, args)//第一个参数为匿名委托,作为ClearingCallBack参数
- {
- alert("来自:" + sender.ID + "的确认消息:将要清空的Listener共:" + args.ListenersCount + "个"); //显示事件参数中的数组
- args.Cancel = !confirm("是否确定要清空?"); //把用户确认的结果反馈到事件参数中
- }, function ()//第二个参数为匿名委托,作为ClearedCallBack参数
- {
- //以下遍历所有div,用box样式来筛选,并清空这些div的内容
- var divs = document.getElementsByTagName("div");
- for (var i in divs) {
- if (divs[i].className == "box") {
- divs[i].innerHTML = "";
- }
- }
- window.status = "已清空"; //状态栏刷新
- document.title = "已清空"; //标题栏刷新
- });
- }
- </script>
- </head>
- <body>
- <input type="text" id="txt" />
- <div id="div1" class="box">
- </div>
- <div id="div2" class="box">
- </div>
- <div id="div3" class="box">
- </div>
- <div id="div4" class="box">
- </div>
- <input type="button" id="btnAdd" value="添加第3个Listener" onclick="Add();" />
- <input type="button" id="btnRemove" value="移除第3个Listener" onclick="Remove();" />
- <input type="button" id="btnClear" value="移除所有Listener" onclick="Clear();" />
- <%--这是最后一行,感谢您完整阅读了这篇代码--%>
- </body>
- </html>
复制代码
|