引用: 百度知道-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事件所以才第一次碰到这个问题。。

 

内容来源于网络如有侵权请私信删除
你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!

相关课程