javascript 中状态改变触发事件
转
有限状态机:是一个非常有用的模型,可以模拟世界上大部分事物。

它有三个特征:
* 状态总数(state)是有限的。 * 任一时刻,只处在一种状态之中。 * 某种条件下,会从一种状态转变(transition)到另一种状态。
它对JavaScript的意义在于,很多对象可以写成有限状态机。
举例来说,网页上有一个菜单元素。鼠标悬停的时候,菜单显示;鼠标移开的时候,菜单隐藏。如果使用有限状态机描述,就是这个菜单只有两种状态(显示和隐藏),鼠标会引发状态转变。
代码可以写成下面这样:
var menu = { // 当前状态 currentState: 'hide', // 绑定事件 initialize: function() { var self = this; self.on("hover", self.transition); }, // 状态转换 transition: function(event){ switch(this.currentState) { case "hide": this.currentState = 'show'; doSomething(); break; case "show": this.currentState = 'hide'; doSomething(); break; default: console.log('Invalid State!'); break; } } };可以看到,有限状态机的写法,逻辑清晰,表达力强,有利于封装事件。一个对象的状态越多、发生的事件越多,就越适合采用有限状态机的写法。
另外,JavaScript语言是一种异步操作特别多的语言,常用的解决方法是指定回调函数,但这样会造成代码结构混乱、难以测试和除错等问题。有限状态机提供了更好的办法:把异步操作与对象的状态改变挂钩,当异步操作结束的时候,发生相应的状态改变,由此再触发其他操作。这要比回调函数、事件监听、发布/订阅等解决方案,在逻辑上更合理,更易于降低代码的复杂度。
下面介绍一个有限状态机的函数库Javascript Finite State Machine。这个库非常好懂,可以帮助我们加深理解,而且功能一点都不弱。
该库提供一个全局对象StateMachine,使用该对象的create方法,可以生成有限状态机的实例。
var fsm = StateMachine.create();生成的时候,需要提供一个参数对象,用来描述实例的性质。比如,交通信号灯(红绿灯)可以这样描述:
var fsm = StateMachine.create({ initial: 'green', events: [ { name: 'warn', from: 'green', to: 'yellow' }, { name: 'stop', from: 'yellow', to: 'red' }, { name: 'ready', from: 'red', to: 'yellow' }, { name: 'go', from: 'yellow', to: 'green' } ] });交通信号灯的初始状态(initial)为green,events属性是触发状态改变的各种事件,比如warn事件使得green状态变成yellow状态,stop事件使得yellow状态变成red状态等等。
生成实例以后,就可以随时查询当前状态。
* fsm.current :返回当前状态。* fsm.is(s) :返回一个布尔值,表示状态s是否为当前状态。* fsm.can(e) :返回一个布尔值,表示事件e是否能在当前状态触发。* fsm.cannot(e) :返回一个布尔值,表示事件e是否不能在当前状态触发。Javascript Finite State Machine允许为每个事件指定两个回调函数,以warn事件为例:
* onafterwarn(可简写成onwarn) :在warn事件发生之后触发。同时,它也允许为每个状态指定两个回调函数,以green状态为例:
* onentergreen(可简写成ongreen) :在进入green状态时触发。假定warn事件使得状态从green变为yellow,上面四类回调函数的发生顺序如下:onbeforewarn → onleavegreen → onenteryellow → onafterwarn。
除了为每个事件和状态单独指定回调函数,还可以为所有的事件和状态指定通用的回调函数。
* onleavestate :离开任一状态时触发。* onenterstate :进入任一状态时触发。* onafterevent :任一事件结束后触发。如果事件的回调函数里面有异步操作(比如与服务器进行Ajax通信),这时我们可能希望等到异步操作结束,再发生状态改变。这就要用到transition方法。
fsm.onwarn = function(){ light.fadeOut('slow', function() { fsm.transition(); }); return StateMachine.ASYNC; };上面代码的回调函数里面,有一个异步操作(light.fadeOut)。如果不希望状态立即改变,就要让回调函数返回一个StateMachine.ASYNC对象,表示状态暂时不改变;等到异步操作结束,再调用transition方法,使得状态发生改变。
Javascript Finite State Machine还允许指定错误处理函数,当发生了当前状态不可能发生的事件时自动触发。
var fsm = StateMachine.create({ // ... error: function(eventName, from, to, args, errorCode, errorMessage) { return 'event ' + eventName + ': ' + errorMessage; }, // ... });比如,当前状态是green,理论上这时只可能发生warn事件。要是这时发生了stop事件,就会触发上面的错误处理函数。
javascript 中状态改变触发事件的更多相关文章
- Winform界面GridView中XCDataGridViewCheckBoxAllColumn改变触发事件
1.首先利用CurrentCellDirtyStateChanged事件 监测状态改变后判断是否有未提交的更改,若有则提交 private void CurrentCellDirtyStateChan ...
- html5与js关于input[type='text']文本框value改变触发事件一些属性的区别oninput,onpropertychange,onchange和文本框的value点击全选状态onclick="select();"。做购物车页面时会要用到。
关于input[type='text']文本框value改变触发事件一些属性的区别oninput,onpropertychange,onchange和文本框的点击全选状态onclick="s ...
- 刷新各ifream当前页,下拉项改变触发事件js,给选中项加背景色js
<script type="text/javascript" language="javascript"> //刷新框架各页面 function r ...
- 探究JavaScript中的五种事件处理程序
探究JavaScript中的五种事件处理程序 我们知道JavaScript与HTML之间的交互是通过事件实现的.事件最早是在IE3和Netscape Navigator 2中出现的,当时是作为分担服务 ...
- 在Javascript中监听flash事件(转)
在Javascript中监听flash事件,其实有两种做法: 1.在特定的环境下(例如专门制作的flash),大家约定一个全局函数,然后在flash的事件中用ExternalInterface.cal ...
- JavaScript中的鼠标滚轮事件详解
JavaScript中的鼠标滚轮事件详解/*Firefox注册事件*/ ~~~Firefox: addEventListener('DOMMouseScroll', handler, false)if ...
- vue中Enter触发登录事件和javascript中Enter触发点击事件
created(){ window.addEventListener('keydown', this.handleKeyDown, true)//开启监听键盘按下事件 } 在methods中当keyC ...
- javascript鼠标双击时触发事件大全
javascript事件列表解说 事件 浏览器支持 解说 一般事件 onclick IE3.N2 鼠标点击时触发此事件 ondblclick IE4.N4 鼠标双击时触发此事件 onmousedown ...
- javascript中的cookie,以及事件解析
Cookie: 它的意思是在本地的客户端的磁盘上以很小的文件形式保存数据,Cookie的处理原则上需要在服务器环境下运行,目前Chrome不可以在客户端操作Cookie,其他浏览器均可以, Coo ...
随机推荐
- JS 利用数组拼接html字符串
var cc = []; cc.push('<td colspan=' + fields.length + ' style="padding:10px 5px;border:0;&qu ...
- GIS应用及OpenGIS介绍
转自:http://blog.csdn.net/cdl2008sky/article/details/7266680 GIS的三大应用第一类是政府应用,“电子政务” 是当今政府加强信息化建设的新方向, ...
- pdb文件部分解释
pdb文件包含了编译后程序指向源代码的位置信息,用于调试的时候定位到源代码,主要是用来方便调试的. 在程序发布为release模式时,建议将 pdb文件删除, 同时,对外发布的时候,也把 pdb删除, ...
- ARM学习笔记10——GNU ARM命令行工具
一.编译器arm-linux-gcc 1.用arm-linux-gcc编译一个程序,一般它是要经过如下步骤的: 1.1.预处理阶段 编译器把上述代码中stdio.h编译进来,使用GCC的选项-E可以使 ...
- Java---replace与replaceAll的区别
乍一看,字面上理解好像replace只替换第一个出现的字符(受javascript的影响),replaceall替换所有的字符,其实大不然,只是替换的用途不一样. 这两者很容易搞混,在这里详细讲述下. ...
- POJ 3186Treats for the Cows (区间DP)
详见代码 #include <stdio.h> #include <algorithm> #include <string.h> using namespace s ...
- Bzoj 1982: [Spoj 2021]Moving Pebbles 博弈论
1982: [Spoj 2021]Moving Pebbles Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 130 Solved: 88[Submi ...
- GPGPU OpenCL/CUDA 高性能编程的10大注意事项
转载自:http://hc.csdn.net/contents/content_details?type=1&id=341 1.展开循环 如果提前知道了循环的次数,可以进行循环展开,这样省去了 ...
- 找回linux丢失的磁盘空间
最近一台服务器空间总是报警,磁盘空间不足. 使用 df 命令查看,磁盘空间耗用接近 100%,将机器上过期的数据以及日志清理掉,但是空间很快又是接近 100%. 使用 du 查看,想找出磁盘空间被耗用 ...
- springMVC源码浅析
因故,需要学习springmvc,现在demo已经跑起来.列文分析springmvc并简单对比struts2. springmvc的核心对象dispatcherServlet.struts2的核心对象 ...