document.onreadystatechange事件的用法分析


Posted in Javascript onOctober 17, 2009

这两天,正在给部门的一个项目做优化,其中一项是将web应用中的所有alert用div方式实现,javascript的相关方法都写好了,方法名为showDialog,前台页面调用showDialog方法一点也没有问题,可是页面一旦提交,从后台输出脚本,调用showDialog方法,就会时不时的出现问题了,报一个无法打开Internet站点的错误,在脚本中下断点调试,依然找不到问题的根源,最后到网上一查,这个问题有可能是页面没有完全加载造成的,于是乎,修改后台输出脚本的代码,将其改为
document.onreadystatechange=function() { if(document.readyState == 'complete'){ showDialog('来自网页的消息','用户名或密码错误,请重新输入!','warning'); } };
问题解决,一切OK!

document.onreadystatechange = subSomething;//当页面加载状态改变的时候执行这个方法. 
function subSomething() 
{ 
if(document.readyState == "complete"){ //当页面加载状态为完全结束时进入 
//你要做的操作。 
} 
}

说明 :onreadystatechange 事件能辨识readyState 属性的改变。

关于onreadystatechange属性的一点疑问
在编写Ajax方法的时候,我们经常会写上类似于这样的代码:

<script type="text/javascript"> 
var xmlHttp; 
//创建一个XmlHttpRequeset对象 
function createXMLHttpRequest()...{ 
if(window.ActiveXObject)...{ 
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); 
} 
else if(window.XMLHttpRequest)...{ 
xmlHttp = new XMLHttpRequest(); 
} 
} 
//开始一个请求 
function startRequest()...{ createXMLHttpRequest(); 
xmlHttp.onreadystatechange = handlestatechange; 
xmlHttp.open("GET", "SimpleRespose.xml", true); 
xmlHttp.Send(null); 
} 
function handlestatechange()...{ 
if(xmlHttp.readyState == 4)...{//描述一种"已加载"状态;此时,响应已经被完全接收。 
if(xmlHttp.status == 200)...{//200表示成功收到 
alert("The Server Replied with:" + xmlHttp.responseText) 
} 
} 
} 
</script>

第一次阅读这段代码的时候,我就感到了一点点不对劲,但是说不出来什么地方不对劲。随着对Ajax代码的进一步了解,这种感觉时刻伴随着我。

后来,我知道了这种感觉来自于什么地方。

看看startRequest函数。我们发现xmlHttp.onreadystatechange指向了一个函数,这个函数是在xmlHttpRequest.readyState发生改变的时候触发。我们再来看startRequest函数,想象一下整个请求发送的步骤。现在我们点击一个按钮,触发了一个startRequest函数。函数往下走,第一步是createXmlHttpRequest(),它的作用是创建一个xmlHttpRequest对象,当它完毕的时候,xmlHttpRequest.readyState的值是0(window.alert跟踪得到的),程序继续往下走,xmlHttp.onreadystatechange = handlestatechange,因为状态没有改变(xmlHttpRequest.readyState的值是0),所以不触发函数,紧接着是Open()和Send(),那么,整个函数从头到尾都应该没有触发handlestatechange函数啊,但是为什么出来的结果是正确的呢?

后来我用window.alert跟踪xmlHttp.readystate的变化,发现于原来它运行的机制是这样的。首先创建一个xmlHttpRequest的对象之后xmlHttp.readyState的值是0了,然后xmlHttp.onreadystatechange = handlestatechange没有运行。紧接着是open(),这个函数发生了之后xmlHttp.readyState的值是1了,那么就会有一个断点在Open()函数处断开,保留现场,紧接着又返回到xmlHttp.onreadystatechange = handlestatechange运行,然后再执行Send()函数,这个函数发生了之后xmlHttp.readyState的值是2了,接着又返回到xmlHttp.onreadystatechange = handlestatechange运行。以此类推。

浏览器因为不能真正地像面向对象那么编程,所以找了个折衷的办法,但是这个办法看起来不伦不类,想了半天,再跟一个同学一起讨论,才得出这样的一个结果。

Javascript 相关文章推荐
javascript中的对象和数组的应用技巧
Jan 07 Javascript
js移除事件 js绑定事件实例应用
Nov 28 Javascript
原生javascript图片自动或手动切换示例附演示源码
Sep 04 Javascript
设置jsf的选择框h:selectOneMenu为不可编辑状态的方法
Jan 07 Javascript
使用js dom和jquery分别实现简单增删改
Sep 11 Javascript
animate 实现滑动切换效果【实例代码】
May 05 Javascript
纯js实现悬浮按钮组件
Dec 17 Javascript
JavaScript之promise_动力节点Java学院整理
Jul 03 Javascript
vue.js 实现点击展开收起动画效果
Jul 07 Javascript
微信小程序利用swiper+css实现购物车商品删除功能
Mar 06 Javascript
vue框架下部署上线后刷新报404问题的解决方案(推荐)
Apr 03 Javascript
富文本编辑器vue2-editor实现全屏功能
May 26 Javascript
将jQuery应用于login页面的问题及解决
Oct 17 #Javascript
层序遍历在ExtJs的TreePanel中的应用
Oct 16 #Javascript
JavaScript 基于原型的对象(创建、调用)
Oct 16 #Javascript
JavaScript 定义function的三种方式小结
Oct 16 #Javascript
JavaScript 函数式编程的原理
Oct 16 #Javascript
实现JavaScript中继承的三种方式
Oct 16 #Javascript
显示js对象所有属性和方法的函数
Oct 16 #Javascript
You might like
浅析Yii中使用RBAC的完全指南(用户角色权限控制)
2013/06/20 PHP
PHP使用文件锁解决高并发问题示例
2018/03/29 PHP
基于jQuery的遍历同id元素 并响应事件的代码
2012/06/14 Javascript
JavaScript将XML转成JSON的方法
2015/03/12 Javascript
js比较日期大小的方法
2015/05/12 Javascript
简介AngularJS的视图功能应用
2015/06/17 Javascript
AngularJS 过滤与排序详解及实例代码
2016/09/14 Javascript
Node.js学习入门
2017/01/03 Javascript
深入理解vue $refs的基本用法
2017/07/13 Javascript
vue+iview+less+echarts实战项目总结
2018/02/22 Javascript
vue-cli2打包前和打包后的css前缀不一致的问题解决
2018/08/24 Javascript
vue与bootstrap实现简单用户信息添加删除功能
2019/02/15 Javascript
Vue的click事件防抖和节流处理详解
2019/11/13 Javascript
VUE页面中通过双击实现复制表格中内容的示例代码
2020/06/11 Javascript
Python构造函数及解构函数介绍
2015/02/26 Python
利用python实现命令行有道词典的方法示例
2017/01/31 Python
python下读取公私钥做加解密实例详解
2017/03/29 Python
python爬虫基本知识
2018/03/05 Python
python 调试冷知识(小结)
2019/11/11 Python
Python Tricks 使用 pywinrm 远程控制 Windows 主机的方法
2020/07/21 Python
使用Python操作MySQL的小技巧
2020/09/10 Python
Python 远程开关机的方法
2020/11/18 Python
jupyter notebook更换皮肤主题的实现
2021/01/07 Python
Python绘制数码晶体管日期
2021/02/19 Python
使用phonegap获取设备的一些信息方法
2017/03/31 HTML / CSS
匡威帆布鞋美国官网:Converse美国
2016/08/22 全球购物
美体小铺波兰官方网站:The Body Shop波兰
2019/09/03 全球购物
Java Servlet API中forward() 与redirect()的区别
2014/04/20 面试题
影视艺术学院毕业生自荐信
2013/11/13 职场文书
电气专业推荐信范文
2013/11/18 职场文书
四下基层实施方案
2014/03/28 职场文书
医学专业毕业生求职信
2014/06/20 职场文书
抗洪救灾感谢信
2015/01/22 职场文书
2015年化工厂工作总结
2015/05/04 职场文书
公司联欢会主持词
2015/07/04 职场文书
个人自我鉴定怎么写?
2019/07/01 职场文书