轮播图点击按钮不能切换图片,绑定的onclick事件中this却指向了window?

新手上路,请多包涵

HTML代码

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Carousel</title>
    <link rel="stylesheet" href="css/reset.css">
    <link rel="stylesheet" href="css/13/index.css">
    <link rel="shortcut icon" href="#" />
    <script src="js/13.inde.js"></script>
</head>

<body>
    <div id="banner-wraper">
        <div id="outer">
            <ul id="img-list">
                <li class="fig"><a href=""><img src="../mi.html/img/banner-1.png" alt=""></a></li>
                <li class="fig"><a href=""><img src="../mi.html/img/banner-2.webp" alt=""></a></li>
                <li class="fig"><a href=""><img src="../mi.html/img/banner-3.webp" alt=""></a></li>
                <li class="fig"><a href=""><img src="../mi.html/img/banner-4.webp" alt=""></a></li>
                <li class="fig"><a href=""><img src="../mi.html/img/banner-5.webp" alt=""></a></li>
            </ul>
            <div id="points">
                <a class="highlight" href=""></a>
                <a class="hd" href=""></a>
                <a class="hd" href=""></a>
                <a class="hd" href=""></a>
                <a class="hd" href=""></a>
            </div>
          
            <a class="btn-left btn" href=""></a>
            <a class="btn-right btn" href=""></a>
           
        </div>
    </div>

</body>

</html>

CSS代码

#outer {
  width: 1226px;
  height: 460px;
  margin: 100px auto;
  position: relative;
}
#outer #img-list {
  width: 100%;
  height: 100%;
}
#outer #img-list li {
  position: absolute;
  opacity: 0;
  transition: all 1s;
}
#outer #img-list li:nth-child(1) {
  opacity: 1;
}
#outer #img-list img {
  width: 100%;
  vertical-align: top;
}
#outer #points {
  position: absolute;
  bottom: 35px;
  right: 30px;
  display: flex;
}
#outer #points a {
  width: 8px;
  height: 8px;
  border: 2px solid rgba(255, 255, 255, 0.4);
  background-color: rgba(0, 0, 0, 0.4);
  border-radius: 50%;
  margin: 0 3px;
}
#outer #points a:hover {
  background-clip: content-box;
  background-color: #b6b4b4;
}
#outer #points .highlight {
  background-clip: content-box;
  background-color: #b6b4b4;
}
#outer .btn-left {
  width: 41px;
  height: 69px;
  background: url(//i1.mifile.cn/f/i/2014/cn/icon/icon-slides.png) no-repeat -84px;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  margin: auto 0;
}
#outer .btn-left:hover {
  background: url(//i1.mifile.cn/f/i/2014/cn/icon/icon-slides.png) no-repeat;
}
#outer .btn-right {
  width: 41px;
  height: 69px;
  background: url(//i1.mifile.cn/f/i/2014/cn/icon/icon-slides.png) no-repeat -123px;
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  margin: auto 0;
}
#outer .btn-right:hover {
  background: url(//i1.mifile.cn/f/i/2014/cn/icon/icon-slides.png) no-repeat -41px;
}
/*# sourceMappingURL=./index.css.map */

JS代码

 /*
  * 需求
        1. 默认自动轮播状态  小圆点跟随推片变化而变化
        2. 触发状态  当鼠标悬浮小圆点发生样式改变并且不在轮播
                当鼠标进行点击的时候,对应小圆点的图片发生改变
        3.鼠标悬浮左右按键的时候,图片不在轮播
            当点击的时候,会根据当前图片的位置发生往后或往前的变化        
  */
 window.onload = function(){

//1.进行元素的获取 
// 获取图片
let imgs = document.querySelectorAll("#img-list li ");
// 获取小圆点
let points = document.querySelectorAll("#points a");
// 获取左右按钮
let btns = document.querySelectorAll(".btn");
// 定义当前显示的下标
let index = 0;
// 定义timer
let timer;

//2.设计方法让所有的图片隐藏
 function hiddenImages(){
    for(let i = 0; i < imgs.length; i++){
        imgs[i].style.opacity = 0;
    }
 }


//  3.设计方法让所有的小圆点处于隐藏的状态
function hiddenPoints(){
    for(let i = 0 ; i < points.length ; i++){
        points[i].className = "hd";
    }
}


// 4.设计方法让小圆点显示和图片的显示都处于隐藏状态并且根据当前设置的下标来进行显示
function chageAll(){
    hiddenImages();
    hiddenPoints();
    imgs[index].style.opacity = 1;
    points[index].className = "highlight";
}


// 5.设计轮播方法
function carousel(){
    timer = setInterval(function(){
        chageAll();
        index++;
        // 判断如果下标超出了就回到第一张
        if(index > imgs.length-1){
            index = 0;
        }

    },3000)
}
carousel();

// 6.进行小圆点的触发
for(let i = 0 ; i < points.length ; i++){

    // 悬浮进行定时器停止
    points[i].onmouseover = function(){
        clearInterval(timer);
    };
    // 鼠标离开继续轮播
    points[i].onmouseout = function () {
        carousel();
    };

    points[i].index = i;

    points[i].onclick = function(){
       index = this.index
       chageAll();
       
    };
}



};

点击小圆点不能切换对应图片,不清楚哪里出现了问题

调试过程中,按钮绑定的单击响应函数中的this永远的是window,this.index的值一直为Undefined

请问大神们可以帮忙看下哪里出了问题吗?
阅读 850
avatarAI BotBETA

你在设置小圆点点击事件时,遇到了this指向错误的问题。这是因为在事件处理函数中,this的指向可能会因为函数的调用方式而改变。在你的代码中,你使用了points[i].onclick = function(){...}的方式绑定事件,这种方式的this在事件触发时,往往会指向全局对象window,而不是你期望的DOM元素。

为了修复这个问题,你需要确保this在事件处理函数中正确指向了DOM元素。这可以通过使用Function.prototype.bind()方法来实现。bind()方法会创建一个新的函数,当这个新函数被调用时,bind()的第一个参数将作为它运行时的this值,之后的一序列参数将会在传递的实参前传入作为它的参数。

所以你的代码可以修改为:

// 6.进行小圆点的触发
for(let i = 0 ; i < points.length ; i++){

    // 悬浮进行定时器停止
    points[i].onmouseover = function(){
        clearInterval(timer);
    }.bind(points[i]);

    // 鼠标离开继续轮播
    points[i].onmouseout = function () {
        carousel();
    }.bind(points[i]);

    points[i].index = i;

    points[i].onclick = function(){
       index = this.index;
       chageAll();
    }.bind(points[i]);
}

在这段修改后的代码中,.bind(points[i])确保了在事件处理函数被调用时,this将指向points[i],因此this.index将能正确获取到小圆点的索引。

2 个回答
✓ 已被采纳

试了一下 Chrome,没有遇到 thiswindow 的情况。
有一个问题:
a 标签的 href 不设置内容的话,点击就会刷新页面。可以把值改成 # 试试,看是不是刷新页面了,导致没有切换图片。

完整代码。

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Carousel</title>
    <style>
        #outer {
            width: 1226px;
            height: 460px;
            margin: 100px auto;
            position: relative;
        }

        #outer #img-list {
            width: 100%;
            height: 100%;
        }

        #outer #img-list li {
            position: absolute;
            opacity: 0;
            transition: all 1s;
        }

        #outer #img-list li:nth-child(1) {
            opacity: 1;
        }

        #outer #img-list img {
            width: 100%;
            vertical-align: top;
        }

        #outer #points {
            position: absolute;
            bottom: 35px;
            right: 30px;
            display: flex;
        }

        #outer #points a {
            width: 8px;
            height: 8px;
            border: 2px solid rgba(255, 255, 255, 0.4);
            background-color: rgba(0, 0, 0, 0.4);
            border-radius: 50%;
            margin: 0 3px;
        }

        #outer #points a:hover {
            background-clip: content-box;
            background-color: #b6b4b4;
        }

        #outer #points .highlight {
            background-clip: content-box;
            background-color: #b6b4b4;
        }

        #outer .btn-left {
            width: 41px;
            height: 69px;
            background: url(//i1.mifile.cn/f/i/2014/cn/icon/icon-slides.png) no-repeat -84px;
            position: absolute;
            top: 0;
            bottom: 0;
            left: 0;
            margin: auto 0;
        }

        #outer .btn-left:hover {
            background: url(//i1.mifile.cn/f/i/2014/cn/icon/icon-slides.png) no-repeat;
        }

        #outer .btn-right {
            width: 41px;
            height: 69px;
            background: url(//i1.mifile.cn/f/i/2014/cn/icon/icon-slides.png) no-repeat -123px;
            position: absolute;
            top: 0;
            bottom: 0;
            right: 0;
            margin: auto 0;
        }

        #outer .btn-right:hover {
            background: url(//i1.mifile.cn/f/i/2014/cn/icon/icon-slides.png) no-repeat -41px;
        }

        /*# sourceMappingURL=./index.css.map */
    </style>

    <script>
        /*
 * 需求
       1. 默认自动轮播状态  小圆点跟随推片变化而变化
       2. 触发状态  当鼠标悬浮小圆点发生样式改变并且不在轮播
               当鼠标进行点击的时候,对应小圆点的图片发生改变
       3.鼠标悬浮左右按键的时候,图片不在轮播
           当点击的时候,会根据当前图片的位置发生往后或往前的变化        
 */
        window.onload = function () {

            //1.进行元素的获取 
            // 获取图片
            let imgs = document.querySelectorAll("#img-list li ");
            // 获取小圆点
            let points = document.querySelectorAll("#points a");
            // 获取左右按钮
            let btns = document.querySelectorAll(".btn");
            // 定义当前显示的下标
            let index = 0;
            // 定义timer
            let timer;

            //2.设计方法让所有的图片隐藏
            function hiddenImages() {
                for (let i = 0; i < imgs.length; i++) {
                    imgs[i].style.opacity = 0;
                }
            }


            //  3.设计方法让所有的小圆点处于隐藏的状态
            function hiddenPoints() {
                for (let i = 0; i < points.length; i++) {
                    points[i].className = "hd";
                }
            }


            // 4.设计方法让小圆点显示和图片的显示都处于隐藏状态并且根据当前设置的下标来进行显示
            function chageAll() {
                hiddenImages();
                hiddenPoints();
                imgs[index].style.opacity = 1;
                points[index].className = "highlight";
            }


            // 5.设计轮播方法
            function carousel() {
                timer = setInterval(function () {
                    chageAll();
                    index++;
                    // 判断如果下标超出了就回到第一张
                    if (index > imgs.length - 1) {
                        index = 0;
                    }

                }, 3000)
            }
            carousel();

            // 6.进行小圆点的触发
            for (let i = 0; i < points.length; i++) {

                // 悬浮进行定时器停止
                points[i].onmouseover = function () {
                    clearInterval(timer);
                };
                // 鼠标离开继续轮播
                points[i].onmouseout = function () {
                    carousel();
                };

                points[i].index = i;

                points[i].onclick = function () {
                    index = this.index
                    chageAll();

                };
            }



        };
    </script>
</head>

<body>
    <div id="banner-wraper">
        <div id="outer">
            <ul id="img-list">
                <li class="fig"><a href="#"><img src="../mi.html/img/banner-1.png" alt=""></a></li>
                <li class="fig"><a href="#"><img src="../mi.html/img/banner-2.webp" alt=""></a></li>
                <li class="fig"><a href="#"><img src="../mi.html/img/banner-3.webp" alt=""></a></li>
                <li class="fig"><a href="#"><img src="../mi.html/img/banner-4.webp" alt=""></a></li>
                <li class="fig"><a href="#"><img src="../mi.html/img/banner-5.webp" alt=""></a></li>
            </ul>
            <div id="points">
                <a class="highlight" href="#"></a>
                <a class="hd" href="#"></a>
                <a class="hd" href="#"></a>
                <a class="hd" href="#"></a>
                <a class="hd" href="#"></a>
            </div>

            <a class="btn-left btn" href=""></a>
            <a class="btn-right btn" href=""></a>

        </div>
    </div>

</body>

</html>

this.index 替换成 i就行了

points[i].onclick = function(){
       index = i
       chageAll();
       
    };
推荐问题