最近遇到一個輪播需求:
1. ajax請求服務器,返回json,判斷json數據里每一項中isFix屬性是0還是1,0表示不輪播,1表示需要輪播。
2. 當isFix屬性為0的時候,表示該圖片不輪播,相反,isFix為1的時候,表示該圖片需要輪播
3. 屏幕最多容納6個圖片,並且每個圖片都有邊距。不固定高度,自適應寬度。
4. 不輪播的圖片固定在左邊,輪播的圖片需要在右邊輪播,每次輪播的距離為一張圖片的寬度和間距
5. 圖片寬高不固定,反正一行最多6個。
6. 兼容IE8
我的思路是:
1. ajax請求的時候,分兩次把輪播和不輪播的圖片append到100%寬度的div中,
2. 從要輪播圖片的第一張開始到最后一張,把這些圖片append到100%減去不輪播圖片所占據的寬度的div中
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 (){}),其它瀏覽器的加載順序都是一樣的。這個我就理解不了了。。。。。。