欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

20180911 关于页面加载顺序引发的JS的undefined/null错误

程序员文章站 2022-07-07 20:22:50
引用: 百度知道-HTML+JavaScript执行顺序问题 这是我在学习JS滚动播放图片案例意外遇到的一个问题,代码完成后console弹出错误警告: Uncaught TypeError: Cannot read property 'style' of undefined. 后来我查找了原因,起 ......

 引用: 百度知道-html+javascript执行顺序问题

这是我在学习js滚动播放图片案例意外遇到的一个问题,代码完成后console弹出错误警告: uncaught typeerror: cannot read property 'style' of undefined.

20180911 关于页面加载顺序引发的JS的undefined/null错误

20180911 关于页面加载顺序引发的JS的undefined/null错误

后来我查找了原因,起初我认为是第二行代码showslides(slideindex)调用函数失败,导致取值失败。但我无法解释这个问题。

20180911 关于页面加载顺序引发的JS的undefined/null错误

 

之后有朋友提示我注意js预编译问题,我开始往预编译的方向去检索代码问题,发现也不是因为预编译或变量提升等js执行顺序导致underfined的问题。

(引用: 1.js的预编译和执行顺序by runforlove   2.javascript变量提升)

最后折腾了一晚,有外网的朋友提示我这是页面加载顺序导致的问题,我顺着这个思路才查找出了原因。

20180911 关于页面加载顺序引发的JS的undefined/null错误

其实原因很简单,但作为新人我自身对代码的编写原理不够深刻,新人也容易碰到这类问题无法解释清楚。所以我想做一点简单的描述。

 

之所以出现这类错误,是因为我们知道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的。这就是错误的原因。

20180911 关于页面加载顺序引发的JS的undefined/null错误

 

除了前面把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事件所以才第一次碰到这个问题。。