老师,为什么调用函数写在上面会出BUG,写在下面却没有问题

老师,为什么调用函数写在上面会出BUG,写在下面却没有问题

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="css/轮播图.css">
<script src="js/轮播图.js"></script>
</head>
<body>
<div class="main" id="main">
<!-- 图片轮播 -->
<div class="banner" id="banner">
<a href="" class="banner-slide slide1 slide-active"></a>
<a href="" class="banner-slide slide2"></a>
<a href="" class="banner-slide slide3"></a>
</div>
<!-- 上一张、下一张按钮 -->
<a href="javascript:;" class="button prev"></a>
<a href="javascript:;" class="button next"></a>
<!-- 圆点导航 -->
<div class="dots" id="dots">
<span class="active"></span>
<span></span>
<span></span>
</div>
</div>
</body>
</html>
* {
margin: 0;
padding: 0;
}

ul {
list-style: none;
}

body {
font-family: '微软雅黑';
color: #14191e;
}

.main {
position: relative;
margin: 30px auto;
width: 1200px;
height: 460px;
overflow: hidden;
}
/* 图片轮播 */
.banner {
position: relative;
width: 1200px;
height: 460px;
overflow: hidden;
}
.banner-slide {
position:absolute;
display: none;
width: 1200px;
height: 460px;
background-repeat: no-repeat;
}
.slide1 {
background-image: url(../img/bg1.jpg);
}
.slide2 {
background-image: url(../img/bg2.jpg);
}
.slide3 {
background-image: url(../img/bg3.jpg);
}
/* 当前图片显示 */
.slide-active {
display: block;
}
/* 上一张、下一张按钮 */
.button {
position: absolute;
top: 50%;
right: 0;
background: url(../img/arrow.png) no-repeat center;
margin-top: -40px;
width: 40px;
height: 80px;
}
.button:hover {
background-color: #333;
opacity: .3;
filter: alpha(opacity=30);  /*兼容IE浏览器*/
}
.prev {
left: 244px;
transform: rotate(180deg);
}

/* 圆点导航 */
.dots {
position: absolute;
bottom: 12px;
right: 8px;
text-align: right;
}
.dots span {
display: inline-block;
width: 12px;
height: 12px;
line-height: 12px;
border-radius: 50%;
background: rgba(7,17,17,.4);
margin-right: 4px;
box-shadow: 0 0 0 2px rgba(255,255,255,.8) inset;
cursor: pointer;
}
.dots span.active {
background: #fff;
box-shadow: 0 0 0 2px rgba(7,17,17,.4) inset;
}
window.onload = function () {
// 封装一个代替ElementById()的方法
function byId(id) {
return typeof(id) === 'string' ? document.getElementById(id) : id;
}
// 调用函数写在这里,鼠标移入图片,定时器不会停止
// slideImg();

var index = 0;
var timer = null;
var pics = byId('banner').getElementsByTagName('a');
var len = pics.length;
var dots = byId('dots').getElementsByTagName('span');

function slideImg() {
var main = byId('main');

// 当鼠标移动到main上,轮播图停止
main.onmouseover = function () {
// 清除定时器
if(timer) {
clearInterval(timer);
console.log(timer);
}
}
// 当鼠标移出main,轮播图继续
main.onmouseout = function () {            // 调用onmouseout事件
timer = setInterval(function () {
index++;
if(index >= len) {
index = 0;
}
// 切换图片
changeImg();
},2000);
}
// 调用onmouseout方法
main.onmouseout();

// 绑定点击事件,点击圆点切换图片
for(var j = 0; j < len; j++) {
dots[j].onclick = function () {
}
}
}
// 切换图片
function changeImg() {
// 隐藏所有的图片
for(var i = 0; i < len; i++) {
pics[i].style.display = 'none';
dots[i].className = '';
}
// 根据index索引显示当前图片
pics[index].style.display = 'block';
dots[index].className = 'active';
}

// 调用函数写在最后,鼠标移入图片,定时器会关闭
slideImg();
}

还有当浏览器遇到一个定义好的函数,但是还没有遇到调用这个函数的代码,那么浏览器是直接跳过这个函数继续读取下面的代码,还是先读取一次这个函数,等到遇到调用这个函数的代码,再回头调用它?

正在回答

登陆购买课程后可参与讨论,去登陆

2回答

你好 ,老师上个回复中说过 , 因为变量存在预解析的 , 所以变量的定义在函数执行的时候就已经定义好了 , 但是赋值会在原来的位置上赋值 , 所以赋值为null ,和什么都不赋值相当于如下:

预解析的过程 :

http://img1.sycdn.imooc.com//climg/5c11bb620001539f07540222.jpg

所以什么都不赋值的情况下 ,是直接把变量定义给提升到最上面 , timer被赋值为定时器不会被覆盖

http://img1.sycdn.imooc.com//climg/5c11bb980001399a07340223.jpg

以上都属于高级课程中的知识了, 目前先了解一下即可 . 还是建议同学以后学习了高级阶段 , 有了基础才能更好的去理解 .目前阶段练习 , 建议同学按照代码顺序去写代码 , 把函数调用写在后面 , 以避免不必要的错误 .

祝学习愉快 ,望采纳 .

  • qq_深海_35 提问者 #1
    谢谢老师!
    2018-12-13 11:59:30
好帮手慕夭夭 2018-12-12 19:18:07

你好同学 , 问题如下:

http://img1.sycdn.imooc.com//climg/5c10ed9400013f3e11200784.jpg

关于同学的第二个问题 , 因为在js中 ,变量和函数是会预解析的 , 也就是当你打开页面时 , 不管变量和函数写在哪个位置 ,都会提前定义 ,然后才会执行后面的代码 . 所以即使函数调用写在了函数前面 ,也会先执行函数里面的内容 , 然后在顺序执行下面的代码 . 这个属于高级课程的知识 , 建议同学本阶段在练习时 , 尽量按照顺序去写代码 .等以后有了高级课程的基础 , 再来回头思考这个问题就会更加理解了 . 

祝学习愉快 ,望采纳 .

  • 提问者 qq_深海_35 #1
    老师,为什么timer不赋值null,条件就成立,赋值了就不成立呢,不赋值的话不应该是undefined吗?是读取代码的顺序问题吗?执行了定时器再被赋值null?但是我在条件里面console.log(timer)会进行输出,只有定时器不会被关闭
    2018-12-12 22:02:27
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
前端小白入门系列课程
  • 参与学习           人
  • 提交作业       11218    份
  • 解答问题       36713    个

从一个不会编程的小白到一个老司机是需要过程的,首先得入门,学习基础知识,然后才能进阶,最后再到精通,本专题是你走进前端世界的不二选择!

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师