最近遇到一個輪播需求: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 (){}),其它瀏覽器的加載順序都是同樣的。這個我就理解不了了。。。。。。