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
<!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错误的更多相关文章
- 从html页面加载顺序来更好的理解jquery初始化
一,html页面加载顺序 1,用户输入网址(假设是个html页面,并且是第一次访问),浏览器向服务器发出请求,服务器返回html文件:2,浏览器开始载入html代码,发现<head>标签内 ...
- 使用 v-cloak 防止页面加载时出现 vue.js 的变量名
知识点:使用 v-cloak 防止页面加载时出现 vue.js 的变量名 场景:在使用vue语法,实现下拉框功能时,展示数据列表之前,出现对应的 vuejs 变量名 代码: var vm = new ...
- 页面加载完毕后调用js方法进行布局操控 已实验
页面加载完毕后调用js方法进行布局操控 已实验 $(function(){ var check1 = $("[id$=SMS]").is(':checked'); var bl=$ ...
- 前后端分离 导致的 静态页面 加载 <script type="module" > 报CORS 跨域错误,提示 blocked by CORS policy
1.前言 静态页面 加载 <script type="module" > 报CORS 跨域错误,提示Access to script at ftp:///xxx.js ...
- C# 问题解决思路--《数组bytes未定义》,ASP.NET页面加载顺序
好久没写博客了,废话不多说,直接说问题. 问题发生情况,首先这个是老项目,然后我是第一次修改.当我解决了各种引用,数据库配置之后等类似的问题,我启动的项目的时候,无任何问题,但是当我点击页面的按钮的时 ...
- html页面加载顺序
页面总是从上往下执行 CSS为什么要放在头部 1.CSS可以和html一起同时进行解析和渲染 2.如果你把CSS放到body后面,不但没有跟html一起进行加载渲染,还要花费额外时间去加载CSS,这样 ...
- 两种方法实现在HTML页面加载完毕后运行JS
JS默认方法: <script type=”text/javascript”> window.onload=function (){ /*代码区域*/ } </script> ...
- 插件二之页面加载进度条pace.js
关于pace.js pace.js包含14样式,每种样式可以自定义颜色,官方下载中提供了几种颜色的主题,使用方式也很简单,引入pace的js文件跟所需样式文件即可 <link rel=" ...
- html页面的加载顺序
页面加载顺序: 解析HTML结构加载外部脚本和样式表文件解析并执行脚本代码构造HTML DOM模型加载图片等外部文件页面加载完毕 window.onload = function () { } / ...
随机推荐
- mysql执行计划 const eq_ref ref range index all
explain:查询查询性能或者需要查看使用索引状态 一.type:连接类型 最关键的一列 效率(const>eq_ref>ref>range>index>all) ...
- Jetty项目解压目录设置
Ubuntu14.04 没有在Jetty的根目录下建立work文件夹时,Jetty会默认将项目解压到/var/cache/jetty/data/下,如果在Jetty的根目录下建立work文件夹,jet ...
- C# this索引器
- Java面向对象_抽象类应用——模板方法模式
概念:定义一个操作中的算法的骨架,而将一些可变部分的实现延迟到子类中.模板方法模式使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定的步骤. 去个例子分析一下这个概念: public cla ...
- SpringBoot | 第零章:前言
缘起 前段时间公司领导叫编写一两课关于springboot的基础知识培训课程,说实话,也是今年年初才开始接触了SpringBoot这个脚手架,使用了之后才发现打开了一个新世界.再之后也没有一些系统的学 ...
- InteliJ idea import project 找不到文件结构解决办法
一.按下列步骤操作: 1. 关闭IDEA, 2.然后删除项目文件夹下的.idea文件夹 3.重新用IDEA工具打开项目: 二.import新项目之后,可能需要等1 ...
- python中函数的定义与调用
1.为什么要用函数? (1)代码重复太多(2)可读性差 使用函数的好处: (1)代码重用 (2)保持一致性,易维护 (2)可扩展性 2.初始函数定义与调用 函数的定义 def test(x): ...
- table-列组
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 50道CSS基础面试题(附答案)
1 介绍一下标准的CSS的盒子模型?与低版本IE的盒子模型有什么不同的? 标准盒子模型:宽度=内容的宽度(content)+ border + padding + margin低版本IE盒子模型:宽度 ...
- laydate 显示结束时间不小于开始时间
jsp: <div class="form-group"> <label >交易时间:</label> <input ...