首页 > 解决方案 > Alpine JS 使用 window.setInterval() 函数以间隔更改图像

问题描述

我正在尝试使用 Alpine JS 和标准 JS 函数 setInterval 解决琐碎的任务。因此,我正在尝试构建一个图像选择器,其中图像将每秒(1000 毫秒)更改一次。

这是我得到的:

<div x-data="imgFunc()">
        <h1 class="text-xl py-3">Chosing the picture</h1>

        <div class="w-1/2">
            <img x-show = "img === 'img1'" src="{{ asset('images/training/img1.jpg') }}" alt="Main Image">
            <img x-show = "img === 'img2'" src="{{ asset('images/training/img2.jpg') }}" alt="Main Image">
            <img x-show = "img === 'img3'" src="{{ asset('images/training/img3.jpg') }}" alt="Main Image">
        </div>

        <div>
            <ul class="flex">
                <li class="w-1/6 p-3" :class="{ 'border' : img==='img1' }"><img src=" {{ asset('images/training/img1.jpg') }} " alt="image1" @click = "startImg"></li>
                <li class="w-1/6 p-3" :class="{ 'border' : img==='img2' }"><img src=" {{ asset('images/training/img2.jpg') }} " alt="image2" @click = "img='img2'"></li>
                <li class="w-1/6 p-3" :class="{ 'border' : img==='img3' }"><img src=" {{ asset('images/training/img3.jpg') }} " alt="image3" @click = "img='img3'"></li>
            </ul>
        </div>



    </div>



<script>
    function imgFunc(){
            var i = 1;
            var img ='img'+i;
            return {
            i,
            img,
            startImg(){
                var myvar = window.setInterval(function(){
                    this.img = 'img'+this.i;
                    if(this.i<3){
                        this.i++;
                    }else{
                        this.i=1;
                    }    
                }, 1000);
            },
            changeImg() {
                this.img = 'img'+this.i;
                if(this.i<3){
                    this.i++;
                }else{
                    this.i=1;
                }                       
            }

        }
        
    }

</script>

单击列表中的 image#1 时,图像应该开始更改,但它永远不会发生。为什么?

我还尝试在 @click 事件中传递函数名称 changeImg() 并且它工作得很好,通过按下一个图像正在一个一个地改变。

我还尝试将函数名称 changeImg() 传递给 setInerval() ,如下所示:

startImg(){
     var myvar = window.setInterval(this.changeImg, 1000);
},

或者像这样:

startImg(){
     var myvar = window.setInterval(changeImg, 1000);
},

我试图将“this”更改为“self”

<script>
    function imgFunc(){
            var i = 1;
            var img ='img'+i;
            var self=this;
            return {
            i,
            img,
            startImg(){
                var myvar = window.setInterval(function(){
                    self.img = 'img'+self.i;
                    if(self.i<3){
                        self.i++;
                    }else{
                        self.i=1;
                    }    
                }, 1000);
            },
            changeImg() {
                this.img = 'img'+this.i;
                if(this.i<3){
                    this.i++;
                }else{
                    this.i=1;
                }                       
            }

        }
        
    }

</script>

但没有什么真正有效。

标签: javascriptsetintervalalpine.js

解决方案


您的问题是使用,function所以this函数内部不是 Alpine.js this。内部也不是 Alpine.js this(对此的快速解释是在初始化 Alpine.js 以生成初始“状态”之前运行,窗口也是如此)imgFuncthisimgFuncthis

有 2 种方法可以修复它,或者使用this但使用内部的箭头函数setInterval

<script>
    function imgFunc(){
            var i = 1;
            var img ='img'+i;
            return {
            i,
            img,
            startImg(){
                var myvar = window.setInterval(() => {
                    this.img = 'img'+this.i;
                    if(this.i<3){
                        this.i++;
                    }else{
                        this.i=1;
                    }    
                }, 1000);
            },
            changeImg() {
                this.img = 'img'+this.i;
                if(this.i<3){
                    this.i++;
                }else{
                    this.i=1;
                }                       
            }

        }
        
    }

</script>

或者,您可以self = this在 startImg 函数中设置

<script>
    function imgFunc(){
            var i = 1;
            var img ='img'+i;
            return {
            i,
            img,
            startImg(){
                var self=this;
                var myvar = window.setInterval(function(){
                    self.img = 'img'+self.i;
                    if(self.i<3){
                        self.i++;
                    }else{
                        self.i=1;
                    }    
                }, 1000);
            },
            changeImg() {
                this.img = 'img'+this.i;
                if(this.i<3){
                    this.i++;
                }else{
                    this.i=1;
                }                       
            }

        }
        
    }

</script>

还有另一种方法是.bindsetInterval回调上使用,但它更冗长和复杂。


推荐阅读