20180911 关于页面加载顺序引发的JS的undefined/null错误
引用: 百度知道-html+javascript执行顺序问题
这是我在学习js滚动播放图片案例意外遇到的一个问题,代码完成后console弹出错误警告: uncaught typeerror: cannot read property 'style' of undefined.
后来我查找了原因,起初我认为是第二行代码showslides(slideindex)调用函数失败,导致取值失败。但我无法解释这个问题。
之后有朋友提示我注意js预编译问题,我开始往预编译的方向去检索代码问题,发现也不是因为预编译或变量提升等js执行顺序导致underfined的问题。
(引用: 1.js的预编译和执行顺序by runforlove 2.javascript变量提升)
最后折腾了一晚,有外网的朋友提示我这是页面加载顺序导致的问题,我顺着这个思路才查找出了原因。
其实原因很简单,但作为新人我自身对代码的编写原理不够深刻,新人也容易碰到这类问题无法解释清楚。所以我想做一点简单的描述。
之所以出现这类错误,是因为我们知道javascript的代码顺序是至上而下的,但javascript不会等到页面加载完毕才执行。这是javascript的强大之处,也是我这次碰到问题的症结。
下面通过两个简单的案例解释:
1.javascript执行在html前导致null
1 <!doctype html> 2 <html> 3 <head> 4 <title>page title</title> 5 <script> 6 myfunction(); 7 8 function myfunction() 9 { 10 var a = 4; 11 var b = 3; 12 document.getelementbyid("demo").innerhtml = a*b; //1. javascript在页面加载前执行,所以获取不到id为"demo"的元素 13 } 14 </script> 15 </head> 16 <body> 17 <p id="demo"></p> 18 19 </body> 20 </html> <!-- 执行结果为null -->
1 <!doctype html> 2 <html> 3 <head> 4 <title>page title</title> 5 <script> 6 myfunction(); 7 8 function myfunction() 9 { 10 var a = 4; 11 var b = 3; 12 document.write(a*b); //2. javascript直接向页面输出了结果,与dom无关 13 } 14 </script> 15 </head> 16 <body> 17 <p id="demo"></p> 18 19 </body> 20 </html> <!-- 执行结果为12 -->
1 <!doctype html> 2 <html> 3 <head> 4 <title>page title</title> 5 6 </head> 7 <body> 8 <p id="demo"></p> 9 10 <script> 11 myfunction(); 12 13 function myfunction() 14 { 15 var a = 4; 16 var b = 3; 17 document.getelementbyid("demo").innerhtml = a*b; //script标签执行在p标签之后,因此javascript运行时元素已加载 18 } 19 </script> 20 </body> 21 </html> <!-- 执行结果为12 -->
2. javascript执行在html前导致undefined
1 <!doctype html> 2 <html> 3 <head> 4 <title>page title</title> 5 6 <style> 7 .myslides { 8 width : 50px; 9 height: 50px; 10 background-color: red; 11 margin: 2px 0; 12 } 13 </style> 14 15 <script> 16 var x = document.getelementsbyclassname("slides")[0]; //javascript执行在html前,无法获取classname的元素 17 x.getelementsbyclassname("myslides")[0].style.backgroundcolor = "blue"; 18 </script> 19 </head> 20 <body> 21 <div class="slides"> 22 <div class="myslides"></div> 23 <div class="myslides"></div> 24 <div class="myslides"></div> 25 </div> 26 </body> 27 </html> <!-- 执行结果为undefined,无法修改元素的底色 -->
回到前面的翻滚图片案例,案例中出现undefined的原因,其实就是因为showslides()在html加载完之前就已经调用了函数,所以在函数中定义变量的值其实是一个空值。自然一个空值是无法改变它的css style的。这就是错误的原因。
除了前面把script标签加到元素后面外,最好的方法是通过dom事件引导javascript关联html元素,比如在body中加入onload事件
另外,jquery也通过$(document).ready(function(){})实现页面加载后再运行函数。
1 <!doctype html> 2 <html> 3 <head> 4 <title>page title</title> 5 6 <style> 7 .myslides { 8 width : 50px; 9 height: 50px; 10 background-color: red; 11 margin: 2px 0; 12 } 13 </style> 14 15 <script> 16 function myfunction(){ 17 var x = document.getelementsbyclassname("slides")[0]; 18 x.getelementsbyclassname("myslides")[0].style.backgroundcolor = "blue"; 19 } 20 </script> 21 </head> 22 <body onload="myfunction()"> <!-- 当页面加载时触发onload事件调用函数 --> 23 <div class="slides"> 24 <div class="myslides"></div> 25 <div class="myslides"></div> 26 <div class="myslides"></div> 27 </div> 28 </body> 29 </html> <!-- 第一个div元素被更改为红色 -->
之所以以前一直没有意识过这个问题,是因为大部分我都习惯把js函数写在html后面,或者一般我都加入了onload和onclick事件所以才第一次碰到这个问题。。
上一篇: 来吧还剩两只
下一篇: 吃什么补肾 12种最补肾的食物推荐