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 () { } / ...
随机推荐
- 主键约束 primary key
主键的作用: 可以唯一标识 一条数据,每张表里面只能有一个主键,.主键特性: 非空且唯一.当表里没有主键的时,第一个出现的非空且为唯一的列,被当成主键. 例子:create table tb3( ...
- C# Task任务详解及其使用方式
https://blog.csdn.net/younghaiqing/article/details/81455410 C#多线程编程笔记(4.3)-Task任务中实现取消选项 https://blo ...
- UnityError 动画系统中anystate跳转重复播放当前动画解决方案
- 3 - EventLoop和线程模型-事件循环
a). EventLoopGroup为每个新创建的channel分配一个EventLoop,多个channel对应一个EventLoop. b). 一个EventLoop由一个不变的thread驱动, ...
- 屏蔽“您目前使用的Discuz!程序有新版本发布,请及时升级!”提示
在/discuz/source/admincp目录下找到文件:admincp_main.php 找到第49行: if($_G['uid'] && $_G['member']['allo ...
- <Openssl下hash函数>
hash函数:是不可逆的函数,它的输入可以是任意长度的字节流.它的输出是固定大小的,hash函数的作用就是给你的文件产生一个摘要,它是独一无二的. 例如:y=f(x) x代表输入 y代表输出 输 ...
- 整理:sql server 中sql语句执行顺序
SQL Server 查询处理中的各个阶段(SQL执行顺序) SQL 不同于与其他编程语言的最明显特征是处理代码的顺序.在大数编程语言中,代码按编码顺序被处理,但是在SQL语言中,第一个被处理的子句是 ...
- Oracle存储函数jdbc调用
package com.jckb.procedure; import java.sql.CallableStatement; import java.sql.Connection; import ja ...
- 固定ip地址
IP. 配置文件写数据库文件连接时,之前一直是就写个. ; 毕竟之前就自己本地用.现在需要,写ip地址,但是公司点的ip的都是自动获得的.并且过一段时间还会改变. 所以,需要固定一下啊. 首先cm ...
- 19.CentOS7下PostgreSQL安装过程
CentOS7下PostgreSQL安装过程 装包 sudo yum install postgresql-server postgresql-contrib 说明: 这种方式直接明了,其他方法也可以 ...