引用: 百度知道-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. Unity 行为树-节点间数据传递

    一.引言 有以下小场景: 节点A:发现了 敌人. 节点B:追逐敌人. 对于同一个敌人物体,节点AB之间是如何传递数据 的呢? 二.数据传递的3种方式 1.共享变量:面板中创建局部或者全局的共享变量Te ...

  2. shiro 重定向 后 带有 sessionId 的 解决 办法

    http://blog.csdn.net/aofavx/article/details/51701012

  3. Django基础(5) ----基于双下划线的跨表查询,聚合查询,分组查询,F查询,Q查询

    一.基于双下划线的跨表查询 Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系.要做跨关系查询,就使用两个下划线来链接模型(mode ...

  4. Docker从入门到实战(三)

    Docker从入门到实战(三) 一:安装Docker 1. linux系统脚本安装 Docker基于linux容器技术,面向服务器端,Docker只能安装运行在64位计算机上(社区有对32位的支持), ...

  5. mysql 主从复制以及binlog 测试

    ###mysql查看binlog日志内容 https://blog.csdn.net/nuli888/article/details/52106910 mysql的binlog日志位置可通过show ...

  6. SPOJ 3267: DQUERY 树状数组,离线算法

    给出q个询问,询问一段区间里面的不同元素的个数有多少个. 离线做,用树状数组. 设树状数组的意义是:1--pos这个段区间的不用元素的种类数.怎么做?就是add(pos,1);在这个位置中+1,就是说 ...

  7. 机器学习框架ML.NET学习笔记【2】入门之二元分类

    一.准备样本 接上一篇文章提到的问题:根据一个人的身高.体重来判断一个人的身材是否很好.但我手上没有样本数据,只能伪造一批数据了,伪造的数据比较标准,用来学习还是蛮合适的. 下面是我用来伪造数据的代码 ...

  8. java程序中路径问题

    JAVA中获取路径: 1.在web中取得路径:   以工程名为TEST为例: (1)得到包含工程名的当前页面全路径:request.getRequestURI() 结果:/TEST/test.jsp  ...

  9. mysql数据库忘记密码时如何修改(二)

    第一步:找到mysql数据库的my.ini配置文件,在[mysqld]下面添加一行代码:skip-grant-tables 第二步:运行services.msc进入服务管理界面,重启mysql服务. ...

  10. 《C#高效编程》读书笔记09-避免在API中使用转换操作符

    转换操作符为类之间引入了一种"可替换性"(substitutability)."可替换性"表示一个类的实例可以替换为另一个类的实例. public class ...