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 相关文章推荐
鼠标移动到一张图片时变为另一张图片
Dec 05 Javascript
用JQuery调用Session的实现代码
Oct 29 Javascript
js onkeypress与onkeydown 事件区别详细说明
Dec 13 Javascript
原生的html元素选择器类似jquery选择器
Oct 15 Javascript
jQuery中delegate()方法用法实例
Jan 19 Javascript
浅谈angular.js中实现双向绑定的方法$watch $digest $apply
Oct 14 Javascript
原生js实现自由拖拽弹窗代码demo
Jun 29 Javascript
Javascript中arguments对象的详解与使用方法
Oct 04 Javascript
Ionic 2 实现列表滑动删除按钮的方法
Jan 22 Javascript
关于使用js算总价的问题
Jun 23 Javascript
在vue项目中使用sass的配置方法
Mar 20 Javascript
react native基于FlatList下拉刷新上拉加载实现代码示例
Sep 30 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
PHP 和 MySQL 开发的 8 个技巧
2007/01/02 PHP
PHP 组件化编程技巧
2009/06/06 PHP
ThinkPHP CURD方法之page方法详解
2014/06/18 PHP
简单实用的网站PHP缓存类实例
2014/07/18 PHP
浅谈PHP解析URL函数parse_url和parse_str
2014/11/11 PHP
利用PHP判断是手机移动端还是PC端访问的函数示例
2017/12/14 PHP
PHP安装memcache扩展的步骤讲解
2019/02/14 PHP
jQuery实现切换页面布局使用介绍
2011/10/09 Javascript
js中settimeout方法加参数的使用实例
2014/02/27 Javascript
js简单实现竖向tab选项卡的方法
2015/05/04 Javascript
JS实现统计复选框选中个数并提示确定与取消的方法
2015/07/01 Javascript
浅析JavaScript 调试方法和技巧
2015/10/22 Javascript
分享两款带遮罩的jQuery弹出框
2015/12/30 Javascript
JS基础随笔(菜鸟必看篇)
2016/07/13 Javascript
Bootstrap基本插件学习笔记之按钮(21)
2016/12/08 Javascript
JavaScript实现左右下拉框动态增删示例
2017/03/09 Javascript
js原生Ajax的封装和原理详解
2017/03/11 Javascript
bootstrap的工具提示实例代码
2017/05/17 Javascript
layui禁用侧边导航栏点击事件的解决方法
2019/09/25 Javascript
[04:54]DOTA2 2017国际邀请赛:上届冠军WINGS采访短片
2017/08/09 DOTA
[01:20:37]FNATIC vs NIP 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
JavaScript实现一维数组转化为二维数组
2018/04/17 Python
Python帮你微信头像任意添加装饰别再@微信官方了
2019/09/25 Python
python实现可下载音乐的音乐播放器
2020/02/25 Python
python 读txt文件,按‘,’分割每行数据操作
2020/07/05 Python
css3动画效果抖动解决方法
2018/09/03 HTML / CSS
使用CSS变量实现炫酷惊人的悬浮效果
2019/04/26 HTML / CSS
雅诗兰黛旗下专业男士保养领导品牌:Lab Series
2017/05/15 全球购物
大学生考试作弊检讨书
2014/09/21 职场文书
北京离婚协议书范文2014
2014/09/29 职场文书
苏州园林导游词
2015/02/03 职场文书
营业员岗位职责
2015/02/11 职场文书
调解书格式范本
2015/05/20 职场文书
物业公司管理制度
2015/08/05 职场文书
Vue3如何理解ref toRef和toRefs的区别
2022/02/18 Vue.js
nginx中封禁ip和允许内网ip访问的实现示例
2022/03/17 Servers