最近读了几篇关于jQuery原理的文章,大致了解了一下jQuery的部分原理。
jQuery的ajax给我们封装好了整套实现JavaScript异步加载的方法,我们用它可以方便的跨浏览器实现异步加载。
其中jQuery的.get、.post、.getJSON都是对jQuery的ajax的二次封装。因此,直接关注ajax的实现即可。
而jQuery的ajax实则是对XMLHttpRequest的封装,对于不支持XMLHttpRequest的old IE,jQuery使用ActiveXObject实现。
具体实现流程如下:
解决好了浏览器的兼容性问题,接下来的共性问题就好办了。
关于XMLHttpRequest.readyState的状态码,参考如下:
0:请求未初始化(还没有调用 open())。
1:请求已经建立,但是还没有发送(还没有调用 send())。
2:请求已发送,正在处理中(通常现在可以从响应中获取内容头)。
3:请求在处理中;通常响应中已有部分数据可用了,但是服务器还没有完成响应的生成。
4:响应已完成;您可以获取并使用服务器的响应了。
摘自:XMLHTTP.readyState的五种状态
其中4表示服务器的响应已经完成了。
而XMLHttpRequest.status就是服务器的状态码,参考:
200 OK:服务器成功处理了请求
404 Not Found :未找到资源
501 Internal Server Error:服务器遇到一个错误,使其无法对请求提供服务
其余的参考 HTTP状态码详解
在callback方法里的responseText就是服务器返回的数据了。
3.调用send方法发送数据 if(type=="GET") xmlhttp.send(null); else xmlhttp.send(data);如果类型是GET表示从服务器获取数据,如果类型是POST则将要发送的数据传入send()方法。
这就是jQuery实现ajax的大致原理。
在用jQuery编写JavaScript代码时,我们一般在:
这里编写代码,其实这个就是jQuery ready()的简写,等价于:
$(document).ready(function(){ //do something }) $().ready(function(){ //do something })$符号即是jQuery,源码中有:window.jQuery = window.$ = jQuery;
那jQuery的ready是如何实现的?
其实还是对原生JavaScript进行了一下封装而已。
在原生JavaScript里,我们可以通过load事件来判断页面是否加载完毕,比如:
<html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script src="js/ray.js"></script> </head> <body onload="loaded()"> </body> <script> function loaded(){ //do sth; } </script> </html>而在jQuery中,对于非 IE浏览器,使用DOMContentLoaded事件来判断页面是否加载完,而对于old IE,则使用
onreadystatechange事件,来查看document的加载情况。当document.readyState === "complete"时,则表示加载完毕。
document.readyState是一个只读属性,一共有如下几个值:
摘自HTML DOM readyState 属性
每当document.readyState发生变化的时候,jQuery就判断它的状态是否是complete,如果是,那么就表示页面加载完成了。
对于IE浏览器,jQuery还多了一层判断。不停的调用doScroll('left')方法,如果能调用该方法,则表示页面加载完成了。
如果不能调用,则过50ms之后再次调用。这样做的目的是在于担心在iframe中,doScroll失效的问题。
知道原理之后,就简单多了。
var doc = document; if(doc.addEventListener){ doc.addEventListener("DOMContentLoaded",function(){ //do sth; }) } else{ doc.attachEvent("onreadystatechange",function(){ if(this.readyState==="complete"){ //do sth; } }); var top = document.documentElement; (function doScrollCheck() { try { top.doScroll("left"); } catch(e) { return setTimeout( doScrollCheck, 50 ); } //解绑onreadystatechange和DOMContentLoaded事件 //do sth; })(); }附jQuery源码部分: