zoukankan      html  css  js  c++  java
  • 从一个例子了解window.onload、$(function(){})、$(window).load(function(){})的加载顺序

    最近遇到一个轮播需求

    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 (){}),其它浏览器的加载顺序都是一样的。这个我就理解不了了。。。。。。

      

  • 相关阅读:
    动态规划算法介绍——概念、意义及应用、例题
    两个大数相减
    删除apache的签名的shell脚本
    C++中智能指针的设计和使用
    eclipse save action不起作用
    [leetcode]51. N-QueensN皇后
    [leetcode]33. Search in Rotated Sorted Array旋转过有序数组里找目标值
    [leetcode]88. Merge Sorted Array归并有序数组
    [leetcode]636. Exclusive Time of Functions函数独占时间
    [leetcode]257. Binary Tree Paths二叉树路径
  • 原文地址:https://www.cnblogs.com/zjjDaily/p/9077736.html
Copyright © 2011-2022 走看看