從一個例子瞭解window.onload、$(function(){})、$(window).load(function(){})的加載順序

最近遇到一個輪播需求css

1. ajax請求服務器,返回json,判斷json數據裏每一項中isFix屬性是0仍是1,0表示不輪播,1表示須要輪播。ajax

2. 當isFix屬性爲0的時候,表示該圖片不輪播,相反,isFix爲1的時候,表示該圖片須要輪播json

3. 屏幕最多容納6個圖片,而且每一個圖片都有邊距。不固定高度,自適應寬度。瀏覽器

4. 不輪播的圖片固定在左邊,輪播的圖片須要在右邊輪播,每次輪播的距離爲一張圖片的寬度和間距服務器

5. 圖片寬高不固定,反正一行最多6個。app

6. 兼容IE8異步

個人思路是:async

1. ajax請求的時候,分兩次把輪播和不輪播的圖片append到100%寬度的div中,函數

2. 從要輪播圖片的第一張開始到最後一張,把這些圖片append到100%減去不輪播圖片所佔據的寬度的div中spa

3. 最後再用margin-left來實現輪播效果。

實現的效果:

總共10個圖片,請求到的數據是其中三個不輪播,剩下7個輪播,因爲一行只能顯示6個,因此顯示的應該是3個在輪播。

 

在實現的過程當中,我須要去獲取裝輪播圖div的高度。而獲取高度確定須要在圖片加載完才能正確獲取到,因此我選擇了在window.onload=function(){} 操做獲取圖片高度。

然而,遇到了以下的問題:

第一個問題:第一次運行程序時居然不執行window.onload裏面的內容???why???

產生緣由:無論是外鏈js仍是頁面中的js,全部的window.onload=function(){}都只有一個且是最後一個生效後面的會覆蓋前面的。我其它js文件裏有window.onload,而這個輪播的js文件要比另外一個先引入,因此這個不執行。

解決辦法:既然只能有一個window.onload,那麼我換成$(window).load(function (){})不就好了嗎?真機智。。。。。。

 

第二個問題:換成$(window).load(function (){})以後,在其它瀏覽器中能正確獲取高度,而在火狐瀏覽器中,有時候能獲取到高度,有時候卻給我返回null。。。???這又是什麼鬼

產生緣由:返回null,說明並無找到該元素。而ajax請求是異步,意思就是在請求成功以前,還能執行下面的代碼。因此在ajax請求成功,把圖片append到div中以前就已經執行到獲取高度的js代碼了。

解決辦法:把ajax的async屬性設置爲false即同步請求數據。啊。。。。。。真個世界清靜了。

爲了防止ajax同步請求時不能執行下面的js,因此我把這個js文件放到最後,以避免請求時間過長時,阻塞下面的js加載。。

 

總結:

  1. window.onload=function(){}是等待全部的內容都加載完以後執行,好比圖片,內容,js,css等。

  2. $(function(){}),是等待DOM加載完以後執行(個人理解是標籤繪製完畢以後),圖片未加載完時也能執行。

  3. $(function(){})是$(document).ready(function(){})的簡寫方式,功能是同樣的。

  4. $(window).load(function (){})也是等待全部的內容都加載完以後執行

  5. 無論是外鏈js仍是頁面中的js的window.onload都只執行最後的一個

  6. $(window).load(function (){})能夠有多個,並且都是順序執行

 

擴展:

若是要js實現多個window.onload的方式

1.在body中調用多個函數

<body onload="f1();f2();f3();">
</body>

   這種方式和下面這種方式是同樣的。

function f1(){...}
function f2(){...}
window.onload=function(){
    f1();
    f2();
}

   顯然,這種方式不太可取。畢竟不能把全部頁面的function都聚在一堆。

 

2. 判斷window.onload是否已經執行了一次,若是是的話,就把原來執行的window.onload函數按照方式1來處理。這樣就不會覆蓋了

function f1(){...}
function f2(){...}

function moreLoad(fn) {
    var winLoad = window.onload;
    if (typeof window.onload != 'function') {
        window.onload = fn;
    } else {
        window.onload = function() {
            winLoad ();
            fn();
        }
    }
}

moreLoad(f1)
moreLoad(f2)

 

 3. 採用事件監聽,ie8以及ie8如下爲attachEvent,其它的爲addEventListener。這樣也不會覆蓋

function f3(){
    alert("f3")
}
function f4(){
    alert("f4")
}
function win_load(callBack){
    if (window.attachEvent) {
        window.attachEvent("onload", callBack);
    } else if (window.addEventListener) {
        window.addEventListener("load", callBack);
    }
}
win_load(f3)
win_load(f4)

  注意:

    1.attachEvent的第二個參數,須要在事件前面加「on」,因此這裏加載事件是onload  。而addEventListener第二個參數不用再事件前面加「on」,因此這裏是load;原本還有第三個參數,可選,表示指定事件是否在捕獲或冒泡階段執行。默認爲false,因此這裏就不用寫上去。

    2. ie的attachEvent裏面綁定多個事件的執行順序是不同的,如上面的例子,IE中是先執行f4函數,再執行f3函數,倒着執行的。而addEventListener是正常的

 

最後說一下加載順序:假如我在當前頁面引入了兩個js文件,一個a.js  一個b.js,分別都有window.onload$(function(){}) $(window).load(function (){})

執行的順序是:

  1. 先以a.js,b.js的順序執行a.js中未包含在window.onload與$(function(){})和$(window).load(function (){})中的代碼。

  2. 而後再執行$(function(){})裏面的代碼,

  3. 而後以a.js,b.js的順序,執行$(window).load(function (){})裏面的代碼,

  4. 最後執行最後一個js中window.onload裏面的代碼 

  可是!!!在火狐和IE瀏覽器中,window.onload的執行順序要高於$(window).load(function (){}),其它瀏覽器的加載順序都是同樣的。這個我就理解不了了。。。。。。

相關文章
相關標籤/搜索