引用: 百度知道-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

 <!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script>
myFunction(); function myFunction()
{
var a = 4;
var b = 3;
document.getElementById("demo").innerHTML = a*b; //1. JavaScript在页面加载前执行,所以获取不到id为"demo"的元素
}
</script>
</head>
<body>
<p id="demo"></p> </body>
</html> <!-- 执行结果为null -->
 <!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<script>
myFunction(); function myFunction()
{
var a = 4;
var b = 3;
document.write(a*b); //2. JavaScript直接向页面输出了结果,与DOM无关
}
</script>
</head>
<body>
<p id="demo"></p> </body>
</html> <!-- 执行结果为12 -->

 <!DOCTYPE html>
<html>
<head>
<title>Page Title</title> </head>
<body>
<p id="demo"></p> <script>
myFunction(); function myFunction()
{
var a = 4;
var b = 3;
document.getElementById("demo").innerHTML = a*b; //script标签执行在p标签之后,因此JavaScript运行时元素已加载
}
</script>
</body>
</html> <!-- 执行结果为12 -->

2. JavaScript执行在HTML前导致undefined

 <!DOCTYPE html>
<html>
<head>
<title>Page Title</title> <style>
.mySlides {
width : 50px;
height: 50px;
background-color: red;
margin: 2px 0;
}
</style> <script>
var x = document.getElementsByClassName("slides")[0]; //JavaScript执行在HTML前,无法获取classname的元素
x.getElementsByClassName("mySlides")[0].style.backgroundColor = "blue";
</script>
</head>
<body>
<div class="slides">
<div class="mySlides"></div>
<div class="mySlides"></div>
<div class="mySlides"></div>
</div>
</body>
</html> <!-- 执行结果为undefined,无法修改元素的底色 -->

回到前面的翻滚图片案例,案例中出现undefined的原因,其实就是因为showSlides()在HTML加载完之前就已经调用了函数,所以在函数中定义变量的值其实是一个空值。自然一个空值是无法改变它的css style的。这就是错误的原因。

除了前面把script标签加到元素后面外,最好的方法是通过DOM事件引导JavaScript关联HTML元素,比如在body中加入onload事件

另外,jQuery也通过$(document).ready(function(){})实现页面加载后再运行函数。

 <!DOCTYPE html>
<html>
<head>
<title>Page Title</title> <style>
.mySlides {
width : 50px;
height: 50px;
background-color: red;
margin: 2px 0;
}
</style> <script>
function myFunction(){
var x = document.getElementsByClassName("slides")[0];
x.getElementsByClassName("mySlides")[0].style.backgroundColor = "blue";
}
</script>
</head>
<body onload="myFunction()"> <!-- 当页面加载时触发onload事件调用函数 -->
<div class="slides">
<div class="mySlides"></div>
<div class="mySlides"></div>
<div class="mySlides"></div>
</div>
</body>
</html> <!-- 第一个div元素被更改为红色 -->

之所以以前一直没有意识过这个问题,是因为大部分我都习惯把JS函数写在HTML后面,或者一般我都加入了onload和onclick事件所以才第一次碰到这个问题。。

20180911 关于页面加载顺序引发的JS的undefined/null错误的更多相关文章

  1. 从html页面加载顺序来更好的理解jquery初始化

    一,html页面加载顺序 1,用户输入网址(假设是个html页面,并且是第一次访问),浏览器向服务器发出请求,服务器返回html文件:2,浏览器开始载入html代码,发现<head>标签内 ...

  2. 使用 v-cloak 防止页面加载时出现 vue.js 的变量名

    知识点:使用 v-cloak 防止页面加载时出现 vue.js 的变量名 场景:在使用vue语法,实现下拉框功能时,展示数据列表之前,出现对应的 vuejs 变量名 代码: var vm = new ...

  3. 页面加载完毕后调用js方法进行布局操控 已实验

    页面加载完毕后调用js方法进行布局操控 已实验 $(function(){ var check1 = $("[id$=SMS]").is(':checked'); var bl=$ ...

  4. 前后端分离 导致的 静态页面 加载 <script type="module" > 报CORS 跨域错误,提示 blocked by CORS policy

    1.前言 静态页面 加载 <script type="module" > 报CORS 跨域错误,提示Access to script at ftp:///xxx.js ...

  5. C# 问题解决思路--《数组bytes未定义》,ASP.NET页面加载顺序

    好久没写博客了,废话不多说,直接说问题. 问题发生情况,首先这个是老项目,然后我是第一次修改.当我解决了各种引用,数据库配置之后等类似的问题,我启动的项目的时候,无任何问题,但是当我点击页面的按钮的时 ...

  6. html页面加载顺序

    页面总是从上往下执行 CSS为什么要放在头部 1.CSS可以和html一起同时进行解析和渲染 2.如果你把CSS放到body后面,不但没有跟html一起进行加载渲染,还要花费额外时间去加载CSS,这样 ...

  7. 两种方法实现在HTML页面加载完毕后运行JS

    JS默认方法: <script type=”text/javascript”> window.onload=function (){ /*代码区域*/ } </script> ...

  8. 插件二之页面加载进度条pace.js

    关于pace.js pace.js包含14样式,每种样式可以自定义颜色,官方下载中提供了几种颜色的主题,使用方式也很简单,引入pace的js文件跟所需样式文件即可 <link rel=" ...

  9. html页面的加载顺序

    页面加载顺序: 解析HTML结构加载外部脚本和样式表文件解析并执行脚本代码构造HTML DOM模型加载图片等外部文件页面加载完毕 window.onload = function () {  }  / ...

随机推荐

  1. P2746 [USACO5.3]校园网Network of Schools

    传送门 把所有学校的关系构成一个图,显然一个强联通分量的所有学校只要有一个有新软件,其他学校也都会有 考虑缩点,发现入度为 0 的块一定要给,因为没有其他人给它 入度不为 0 的块一定有其他人给,我们 ...

  2. DM设备的创建与管理

    DM(Device Mapper)即设备映射(逻辑设备). MD和DM是Linux内核上2种工作机制(实现逻辑设备)不同的模块. Physical Volume(PV): 物理卷         底层 ...

  3. 前后端API交互数据加密——AES与RSA混合加密完整实例

    前言 前段时间看到一篇文章讲如何保证API调用时数据的安全性(传送门:https://blog.csdn.net/ityouknow/article/details/80603617),文中讲到利用R ...

  4. .Net core使用XRPC创建远程接口的Actor对象

    Actor是一种高并发处理模型,每个Actor都有着自己的状态有序消息处理机制,所以在业务处理的情况并不需要制定锁的机制,从而达到更高效的处理能性.XRPC是一个基于远程接口调用的RPC组件,它可以简 ...

  5. css相关知识

    display: block; "块级元素". display: inline; "行内元素". display: none; "在不删除元素的情况下 ...

  6. js小数点后保留几位方法:toFixed

    (0.22223343534).toFixed(2) 结果:0.22

  7. Linux查找文件内容(grep)

    转载链接:http://www.eguidedog.net/linux-tutorial/05-grep.php grep是Linux命令行下常用于查找过滤文本文件内容的命令.最简单的用法是: gre ...

  8. jquery初始

    今天我们来学习Jquery的一些基本知识,jquery相对来说还是比较重要的,所以还是要好好学习的. 首先要了解什么是jQuery? l类似于python里面的模块,可以看成是一种库或者插件. 在学习 ...

  9. node安装启动服务

    一.下载安装包: node下载地址:https://nodejs.org/en/download/,根据自己电脑的配置下载相应的windows64位安装包,下载完成后,进行安装.下面我用的8.9.0版 ...

  10. oracle 查询之前的表数据

    SELECT * FROM Student  AS OF TIMESTAMP SYSDATE - 3/1440 对SQL的解释说明: SYSDATE :当前时间 1440 :24h*60m=1440m ...