引用: 百度知道-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. 解决Nginx启动失败

    一.Nginx下载http://nginx.org/en/download.html 二.Nginx启动失败原因1.本人下载的是nginx-1.12.1(稳定版),下载完解压后,进入路径中,start ...

  2. (反NIM)

    题目大意是和普通的NIM游戏一样,但是却是取到最后一个是输的,天真的以为就是反过来,其实并不是这样的 结论 先手必胜的条件为 ①:所有堆的石子数均=1,且有偶数堆. ②:至少有一个堆的石子数>1 ...

  3. Restful 3 -- 序列化组件(GET/PUT/DELETE接口设计)、视图优化组件

    一.序列化组件 基于上篇随笔的表结构,通过序列化组件的ModelSerializer设计如下三个接口: GET 127.0.0.1:8000/books/{id} # 获取一条数据,返回值:{} PU ...

  4. 使用C#连接 MyCat 链接串

    所属专栏: mycat的安装部署以及监控和运维    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u014180504/article/detai ...

  5. Pandas处理数据常用方法

    # -*- coding: utf-8 -*-import pandas as pd"""(1)利用pandas读取csv文件"""def ...

  6. Hive 基本语法操练(一):表操作

    Hive 和 Mysql 的表操作语句类似,如果熟悉 Mysql,学习Hive 的表操作就非常容易了,下面对 Hive 的表操作进行深入讲解. **(1)先来创建一个表名为student的内部表** ...

  7. {ldelim},{rdelim} - smarty 内建函数

    {ldelim}和{rdelim}用来转义模板的分隔符,缺省为{和}.你也可以用{literal}{/literal}来转义文本块(如Javascript或CSS). 例: {* 在模板外将原样打印分 ...

  8. HDU 5445——Food Problem——————【多重背包】

    Food Problem Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)To ...

  9. idea代码生成功能 live template

    一 界面 二 添加 三 编写模板 模板可以通过看其他的模板学习相应语法,难不倒程序员的 四 选择适应范围 五 本人常用的模板 log private static final Logger log = ...

  10. npm install appium

    先安装node.js npm config set registry http://registry.npm.taobao.org/   // 设置淘宝镜像 npm install chromedri ...