javascript 類比JQuery的Ready方法實現並出現的問題

來源:互聯網
上載者:User

dom載入完後執行,一直不瞭解,基於對網上的一些方法邏輯不瞭解,所以去看了《jquery原始碼研究(ready函數) 》這篇文章後自己寫入如下代碼(已有詳細說明) 複製代碼 代碼如下:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>document.ready</title>
<script type="text/javascript" src="js/jquery-1.3.2.js"></script>
<script type="text/javascript">
var Darren;
(function(){
var isReady=false; //是否已經載入完畢
var readBound=false; //判斷是否已經調用過迴圈事件
var readylist=[]; //把需要執行的方法先暫存在這個數組裡
//判斷瀏覽器,該方法來自Cloudgamer JavaScript Library v0.1
var Browser = (function(ua){
var b = {
msie: /msie/.test(ua) && !/opera/.test(ua),
opera: /opera/.test(ua),
safari: /webkit/.test(ua) && !/chrome/.test(ua),
firefox: /firefox/.test(ua),
chrome: /chrome/.test(ua)
};
var vMark = "";
for (var i in b) {
if (b[i]) {
vMark = i;
}
}
if (b.safari) {
vMark = "version";
}
b.version = RegExp("(?:" + vMark + ")[\\/: ]([\\d.]+)").test(ua) ? RegExp.$1 : "0";
b.ie = b.msie;
b.ie6 = b.msie && parseInt(b.version) == 6;
b.ie7 = b.msie && parseInt(b.version) == 7;
b.ie8 = b.msie && parseInt(b.version) == 8;
return b;
})(window.navigator.userAgent.toLowerCase());
function bindReady()
{
if(readBound){ //保證bindReady方法只執行一遍
return;
}
readBound=true;
//For IE並且不是嵌套在frame中
if (Browser.msie && window==top)
{
(function(){
if (isReady) {
return;
}
try {
document.documentElement.doScroll("left"); //如果沒載入dom完畢這個會報錯
}
catch (error) {
setTimeout(arguments.callee, 0); //迴圈調用父函數,也就是ready方法
return;
}
Test.Done();
})();
}else if(Browser.firefox)//For FF
{
document.addEventListener( "DOMContentLoaded", Test.Done, false );
}
}
var Test={
ready:function(fn){
bindReady();//判斷是否載入完畢
if(isReady)
{
fn.call(document); //載入完畢,直接調用
}else{
readylist.push(fn);//如果還沒載入完成則將該方法暫存到readylist數組中,以便以後調用
}
return this;
}
};
//靜態方法:載入完畢執行
Test.Done=function(){
if (!isReady) {
isReady=true;
}
readylist[0].call(document);
}
Darren=Test;
})();
//測試
Darren.ready(function(){
alert("my");
document.getElementById("test").innerHTML="haha" //成功讀取dom
});
$(function(){alert("jq")});
window.onload=function(){alert("default")}
</script>
</head>
<body>
<div id="test">test</div>
</body>
</html>

由於要和jq做對比,所以測試時候需要匯入jq庫。函數本身是沒有調用jq的,請放心引用。

代碼我通過封裝完成,直接Darren.ready(fn)就可執行。

後來通過測試還是出現一個奇怪的問題:在FF下的執行順序是jq -> my -> load 。也就是說我這個函數能夠在onload事件執行前觸發,但會晚於jq的ready。對這個還是比較滿意。

但是在IE下測試居然是:jq -> load -> my。也就是 我的這個函數雖然能夠把代碼提前,但是還是在onload事件執行後觸發的,百思不得其解。

完同志們解答下如何?onload之前執行,jq又是怎麼實現的,我完全類比jq的結構,但是還是不能達到目的,難道中間有漏?

另大家可以參考下面的代碼複製代碼 代碼如下:var ready=function(readyCall) {
if(document.addEventListener)
document.addEventListener("DOMContentLoaded",function() {
document.removeEventListener("DOMContentLoaded",arguments.callee,false);
readyCall();
},false);
else if(document.attachEvent) {//for IE
if(document.documentElement.doScroll && window.self==window.top) {
(function() {
try {
document.documentElement.doScroll("left");
}catch(ex) {
setTimeout(arguments.callee,5);
return;
}
readyCall();
})();
}else {//maybe late but also for iframes
document.attachEvent("onreadystatechange",function() {
if(document.readyState==="complete") {
document.detachEvent("onreadystatechange", arguments.callee);
readyCall();
}
});
}
}
}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.