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 相关文章推荐
hover的用法及live的用法介绍(鼠标悬停效果)
Mar 29 Javascript
js导出table数据到excel即导出为EXCEL文档的方法
Oct 10 Javascript
iframe子页面与父页面在同域或不同域下的js通信
May 07 Javascript
jquery获取html元素的绝对位置和相对位置的方法
Jun 20 Javascript
js操作数据库实现注册和登陆的简单实例
May 26 Javascript
js实现目录链接,内容跟着目录滚动显示的简单实例
Oct 15 Javascript
js实现随机抽选效果、随机抽选红色球效果
Jan 13 Javascript
获取url中用&amp;隔开的参数实例(分享)
May 28 Javascript
基于rem的移动端响应式适配方案(详解)
Jul 07 Javascript
Layui事件监听的实现(表单和数据表格)
Oct 17 Javascript
微信小程序中weui用法解析
Oct 21 Javascript
在vue中使用回调函数,this调用无效的解决
Aug 11 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设计模式 Prototype (原型模式)代码
2011/06/26 PHP
使用PHP接收POST数据,解析json数据
2013/06/28 PHP
PHP利用百度ai实现文本和图片审核
2019/05/08 PHP
php7连接MySQL实现简易查询程序的方法
2020/10/13 PHP
niceTitle 基于jquery的超链接提示插件
2010/05/31 Javascript
jQuery弹性滑动导航菜单实现思路及代码
2013/05/02 Javascript
indexOf 和 lastIndexOf 使用示例介绍
2014/09/02 Javascript
JavaScript中的Math.LOG2E属性使用详解
2015/06/14 Javascript
初识Javascript小结
2015/07/16 Javascript
深入学习Bootstrap表单
2016/12/13 Javascript
Vue-resource实现ajax请求和跨域请求示例
2017/02/23 Javascript
jQuery手风琴的简单制作
2017/05/12 jQuery
用JS编写一个函数,返回数组中重复出现过的元素(实例)
2017/09/14 Javascript
微信小程序中setInterval的使用方法
2017/09/29 Javascript
JS装饰器函数用法总结
2018/04/21 Javascript
在vue-cli项目中使用bootstrap的方法示例
2018/04/21 Javascript
微信JS-SDK实现微信会员卡功能(给用户微信卡包里发送会员卡)
2019/07/25 Javascript
react组件基本用法示例小结
2020/04/27 Javascript
[01:06]DOTA2隆重推出2016冬季勇士令状 内含上海特级锦标赛互动指南
2016/02/17 DOTA
Tornado Web服务器多进程启动的2个方法
2014/08/04 Python
用Python编写一个每天都在系统下新建一个文件夹的脚本
2015/05/04 Python
详解常用查找数据结构及算法(Python实现)
2016/12/09 Python
Python 文件操作的详解及实例
2017/09/18 Python
Python实现曲线点抽稀算法的示例
2017/10/12 Python
使用Python实现租车计费系统的两种方法
2018/09/29 Python
在Python中增加和插入元素的示例
2018/11/01 Python
python GUI库图形界面开发之PyQt5 UI主线程与耗时线程分离详细方法实例
2020/02/26 Python
使用python脚本自动生成K8S-YAML的方法示例
2020/07/12 Python
香港通票:Hong Kong Pass
2019/02/26 全球购物
古驰英国官网:GUCCI英国
2020/03/07 全球购物
计算机专业自荐信
2013/10/14 职场文书
服装设计师职业生涯规划范文
2014/02/28 职场文书
金融管理专业毕业生求职信
2014/03/12 职场文书
园林技术专业求职信
2014/07/28 职场文书
2015年世界无烟日活动总结
2015/02/10 职场文书
使用Redis实现实时排行榜功能
2021/07/02 Redis