javascript - ES6 for 循环 let 改 var 作用域出错如何解决?

查看:218
本文介绍了javascript - ES6 for 循环 let 改 var 作用域出错如何解决?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
    * {
        padding: 0;
        margin: 0;
    }
    
    div.slider {
        width: 730px;
        height: 454px;
        position: relative;
        overflow: scroll;
    }
    
    div.slider li.slider-panel {
        position: absolute;
        transition-duration: 0.5s;
        transition-property: all;
    }
    
    div.slider ul.slider-extra {
        position: absolute;
        text-align: center;
        width: 730px;
        height: 0;
        cursor: default;
        bottom: 26px;
    }
    
    div.slider li.slider-nav {
        display: inline-block;
        width: 18px;
        height: 18px;
        line-height: 18px;
        border-radius: 50%;
        background-color: #3e3e3e;
        color: white;
        font-size: 12px;
        cursor: pointer;
    }
    
    div.slider-page a.slider-prev {
        position: absolute;
        font-size: 22px;
        height: 62px;
        width: 28px;
        top: 200px;
        background-color: rgba(0, 0, 0, 0.2);
        text-align: center;
        line-height: 62px;
        color: white;
        text-decoration: none;
    }
    
    div.slider-page a.slider-next {
        position: absolute;
        font-size: 22px;
        height: 62px;
        width: 28px;
        top: 200px;
        right: 0;
        background-color: rgba(0, 0, 0, 0.2);
        text-align: center;
        line-height: 62px;
        color: white;
        text-decoration: none;
    }
    </style>
</head>

<body>
    <div class="slider">
        <ul class="slider-main">
            <li class="slider-panel"><img src="1.jpg" alt=""></li>
            <li class="slider-panel"><img src="2.jpg" alt=""></li>
            <li class="slider-panel"><img src="3.jpg" alt=""></li>
            <li class="slider-panel"><img src="4.jpg" alt=""></li>
            <li class="slider-panel"><img src="5.jpg" alt=""></li>
            <li class="slider-panel"><img src="6.jpg" alt=""></li>
        </ul>
        <ul class="slider-extra">
            <li class="slider-nav">1</li>
            <li class="slider-nav">2</li>
            <li class="slider-nav">3</li>
            <li class="slider-nav">4</li>
            <li class="slider-nav">5</li>
            <li class="slider-nav">6</li>
        </ul>
        <div class="slider-page">
            <a href="" class="slider-prev">&#60;</a>
            <a href="" class="slider-next">&#62;</a>
        </div>
    </div>
    <script>
    window.onload = function() {
        var sliderPanels = document.querySelector("ul.slider-main").getElementsByTagName("li");
        var sliderNavs = document.querySelector("ul.slider-extra").getElementsByTagName("li");
        var sliderPage = document.querySelector("div.slider-page");
        var sliderPageButtons = document.querySelector("div.slider-page").getElementsByTagName("a");
        var timer = null;
        var currentPoint;

        /*init function*/
        changeImg(0);
        autoChange(0);

        /*slider navigator dots*/
        for (var i = 0; i < sliderNavs.length; i++) {
            sliderNavs[i].onmouseover = function() {
                if (timer) clearInterval(timer);
                changeImg(i);
            };

            sliderNavs[i].onmouseout = function() {
                autoChange(currentPoint);
            };
            sliderPanels[i].onmouseover = function() {
                if (timer) clearInterval(timer);
                sliderPage.style.display = "";

            };
            sliderPage.onmouseover = function() {
                sliderPage.style.display = "";
            };
            sliderPanels[i].onmouseout = function() {
                autoChange(currentPoint);
                sliderPage.style.display = "none";
            };
        }

        /*page slider button*/
        sliderPageButtons[0].onmouseover = function() {
            if (timer) clearInterval(timer);
        };
        sliderPageButtons[1].onmouseover = function() {
            if (timer) clearInterval(timer);
        };
        sliderPageButtons[0].onclick = function() {
            event.preventDefault();
            currentPoint--;
            if (currentPoint < 0) currentPoint = 5;
            changeImg(currentPoint);
        };
        sliderPageButtons[1].onclick = function() {
            event.preventDefault();
            currentPoint++;
            if (currentPoint >= sliderNavs.length) currentPoint = 0;
            changeImg(currentPoint);
        };

        /*change images function*/
        function changeImg(id) {
            for (var j = 0, len = sliderNavs.length; j < len; j++) {
                sliderNavs[j].style.backgroundColor = "#3e3e3e";
                sliderPanels[j].style.opacity = 0;
            }
            sliderNavs[id].style.backgroundColor = "red";
            sliderPanels[id].style.opacity = 1;
            currentPoint = id;
        }
        /*auto change images function*/
        function autoChange(currentPoint) {
            timer = setInterval(function() {
                currentPoint++
                if (currentPoint >= sliderNavs.length) currentPoint = 0;
                changeImg(currentPoint);
            }, 1000);
        }
    };
    </script>
</body>

</html>

上面是全部代码,其中第一个for循环处:

/*slider navigator dots*/
for (let /*在这里*/ i = 0; i < sliderNavs.length; i++) {
    sliderNavs[i].onmouseover = function() {
        if (timer) clearInterval(timer);
        changeImg(i);
    };

如果改为let 则不会报错,如果是var 则出现如下错误:

3js轮播3.html:162 Uncaught TypeError: Cannot read property 'style' of undefined

请问为了改为var而不是let,我应该如果修改代码?

解决方案

因为使用let定义的变量只在当前的块级作用域有效,所以,使用let就能够避免你的for循环的函数在循环结束之后执行。但是,使用var就不同了。使用var定义的变量,是不存在块级作用域的。所以,当你使用var的时候,其实循环已经执行完了,你的i的值就是sliderNavs.length,当然就会报错。所以,你需要一个闭包来保存i的值。

所以,把你的for循环的代码改成这样:

/*slider navigator dots*/
for (var i = 0; i < sliderNavs.length; i++) {
    (function ( i ) {
        sliderNavs[i].onmouseover = function() {
            if (timer) clearInterval(timer);
            changeImg(i);
        };

        sliderNavs[i].onmouseout = function() {
            autoChange(currentPoint);
        };
        sliderPanels[i].onmouseover = function() {
            if (timer) clearInterval(timer);
            sliderPage.style.display = "";

        };
        sliderPage.onmouseover = function() {
            sliderPage.style.display = "";
        };
        sliderPanels[i].onmouseout = function() {
            autoChange(currentPoint);
            sliderPage.style.display = "none";
        };
    })( i );
}

这篇关于javascript - ES6 for 循环 let 改 var 作用域出错如何解决?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆