JavaScript之共享onload

我们知道,当我们将JS代码脚本放到<head></head>标签之间时,这是的js代码加载要先于DOM加载,而我们往往会在JS代码脚本中写一些获取DOM元素的代码,而此时的DOM是不完整的,

所以我们通常的解决方法是将函数放入到window.onload里面去,window.load事件是网页加载完毕时会触发的一个事件,如果将我们的函数与之绑定,我们的函数也会在页面加载完毕之后执行.

如下代码:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
        var aa = document.getElementById("target");
        alert(aa.nodeName);
    </script>
</head>
<body>
  <div id="target"></div>
</body>
</html>

这段代码在浏览器执行时就会报错,aa is null;因为在js获取id=target的div时,该div还没有加载完毕。所以我们需要这样来解决这个问题,代码如下:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
        window.onload = bb;
        function bb() {
            var aa = document.getElementById("target");
            alert(aa.nodeName);
        }
    </script>
</head>
<body>
  <div id="target"></div>
</body>
</html>

这个时候代码正常输出:DIV;  nodeName默认输出标签名的大写形式;

这似乎已经解决了我们的问题,但是不够perfect,如下代码:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
        window.onload = bb;
        cc();
        function bb() {
            var aa = document.getElementById("target");
            alert(aa.nodeName);
        }
        function cc() {
            var dd = document.getElementById("Div1");
            alert(dd);
        }
    </script>
</head>
<body>
  <div id="target"></div>
  <div id="Div1"></div>
</body>
</html>

这个时候任然会报错:dd id null;错误原因和上面一样;

解决办法有两个:

1、将需要绑定window.onload事件的两个函数写到一个匿名函数里面,在将该匿名函数与window.onload事件绑定,ok,问题解决!

但是这个方法只能解决需要绑定window.onload事件的函数较少的情况,一旦那些函数有很多,这个方法就不是很好!

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
        window.onload = ee;
        function bb() {
            var aa = document.getElementById("target");
            alert(aa.nodeName);
        }
        function cc() {
            var dd = document.getElementById("Div1");
            alert(dd.firstChild.nodeValue);
        }
        function ee() {
            bb();
            cc();
        }
    </script>
</head>
<body>
  <div id="target"></div>
  <div id="Div1">asdas</div>
</body>
</html>

2、这是一个弹性最佳的解决方案       不管你打算在页面加载完毕是执行多少个函数,他都能应付自如;代码如下:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
        addOnLoadEvent(aa);
        addOnLoadEvent(bb);
        function aa() {
          var aa=document.getElementById("ab");
          alert(aa.firstChild.nodeValue);
        }
        function bb() {
            var bb = document.getElementById("abc");
            alert(bb.firstChild.nodeValue);
        }
        //定义一个addOnLoadEvent的函数 
        function addOnLoadEvent(func) {
            var oldonload = window.onload;
            if (typeof window.onload != "function") {
                window.onload = func;   //如果window.onload事件没有绑定任何function则正常绑定
            }
            else {
                //如果window.onload事件已经绑定了函数,则在原来的基础上,继续添加新的函数
                window.onload = function () {
                    oldonload();
                    func();
                };
            }
        }
    </script>
</head>
<body>
<div id="ab">1</div>
<div id="abc">2</div>
</body>
</html>

上面的addOnloadEvent()方法解决了我们的问题,但是还不够全面,因为当需要绑定的方法过多时,我们就要写多条addOnLoadEvent(方法);所以为了减少代码量这里的代码还可以这样改,

代码如下:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript">
        var onloadlist = [aa,bb];//定义一个数组,数组里面都是需要在页面加载完毕之后才执行的函数引用
        addOnLoadEvent(onloadlist);
        function aa() {
          alert(1);
        }
        function bb() {
            alert(2);
        }
        function addOnLoadEvent(eventlist) {
             //循环遍历数组依次加到队列中
            window.onload = function () {
                for (var i = 0; i < eventlist.length; i++) {
                    eventlist[i]();
                }
            }
        }
    </script>
</head>
<body>
<div id="ab">1</div>
<div id="abc">2</div>
</body>
</html>

这样就一定程度上减少了代码量,还便于管理方法的执行先后顺序。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏柠檬先生

VUE 入门基础(3)

三,模板语法   Vue将模板编译成虚拟DOM渲染函数,结合响应系统,在应用状态改变时,vue能够智能地计算出重新渲染组件的最小代价并DOM操作上。   插值,...

2296
来自专栏Golang语言社区

Go-指针、传值与传引用、垃圾回收

要点 Go使用的*、&、new()这些运算符,和C++的用法完全一样。 有传值和传引用/传地址的概念,和C++一样。 Go没有new对应的delete操作,而是...

36010
来自专栏IT派

Python爬虫库-BeautifulSoup的使用

Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库,简单来说,它能将HTML的标签文件解析成树形结构,然后方便地获取到指定标...

943
来自专栏无所事事者爱嘲笑

vue要点记录(待更新)

1653
来自专栏Golang语言社区

go 切片使用小结

最新项目使用go语言开发,因此有机会结识了go语言。在写代码时,无意间发现了同事代码的一个bug。今天拿来一起学习一下。 首先go语言有个强大的基本数据结构,那...

3378
来自专栏前端知识分享

第22天:js改变样式效果

1、alert:弹出警示框(用的非常少,用户体验不好) 完整写法:window.alert(“执行语句”); window对象,窗口,一般情况可省略 alert...

1221
来自专栏小程序的道路

小程序渲染

在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。通过遍历数据,将数据展示,类似vue中的 v-for。 wx:for-...

1502
来自专栏SHERlocked93的前端小站

JS 活学活用正则表达式

网上的帖子大多深浅不一,甚至有些前后矛盾,在下的文章都是学习过程中的总结,如果发现错误,欢迎留言指出~

2672
来自专栏Golang语言社区

Go-指针、传值与传引用、垃圾回收

要点 Go使用的*、&、new()这些运算符,和C++的用法完全一样。 有传值和传引用/传地址的概念,和C++一样。 Go没有new对应的delete操作,而是...

3325
来自专栏技术博文

js去掉字符串前后空格的五种方法

第一种:循环检查替换 [javascript] //供使用者调用   function trim(s){   return trimRight(trimLeft...

3935

扫码关注云+社区

领取腾讯云代金券