Alpine JS 使用 window.setInterval() 函数以间隔更改图像
Alpine JS changing images with interval with window.setInterval() function
我正在尝试使用 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>
当单击列表中的图像 #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>
但没有任何效果。
你的问题是 function
的使用,所以函数内部的 this
不是 Alpine.js this
。 imgFunc
内部的 this
也不是 Alpine.js this
(对此的快速解释是 imgFunc
在 Alpine.js 初始化之前运行以生成初始“状态”所以 this
是 window)
有两种方法可以修复它,要么使用 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>
或者您可以在 startImg 函数中设置 self = this
<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>
还有另一种方法可以做到这一点,即在 setInterval
回调中使用 .bind
,但这更加冗长和复杂。
正如 hugo 所提到的,this
的上下文无法解析为外部函数,因此您需要使用箭头函数,因为它没有上下文。
我做了一些更改以使用 alpine.js 来实现。
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.0.1/tailwind.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/alpinejs/2.7.3/alpine.js"></script>
<div x-data="imgFunc()">
<h1 class="text-xl py-3">Chosing the picture</h1>
<div class="w-1/2">
<img :src="currentImage" alt="Main Image">
</div>
<div>
<ul class="flex">
<template x-for='(image,index) in images'>
<li class="w-1/6 p-3" :class="{'border': currentImage===image}">
<img :src="image" alt="image1" @click="startImg(index)">
</li>
</template>
</ul>
</div>
</div>
<script>
function imgFunc() {
return {
currentImage: 'https://images.pexels.com/photos/5549634/pexels-photo-5549634.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=200&w=400',
images: [
'https://images.pexels.com/photos/5549634/pexels-photo-5549634.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=200&w=400',
'https://images.pexels.com/photos/5101387/pexels-photo-5101387.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
'https://images.pexels.com/photos/2363832/pexels-photo-2363832.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260'
],
startImg(index) {
this.currentImage = this.images[index];
if (index > 0)
return;
let i = 0;
var myvar = setInterval(() => {
i = (i >= this.images.length - 1) ? 0 : ++i;
this.currentImage = this.images[i];
}, 1000);
},
}
}
</script>
我正在尝试使用 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>
当单击列表中的图像 #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>
但没有任何效果。
你的问题是 function
的使用,所以函数内部的 this
不是 Alpine.js this
。 imgFunc
内部的 this
也不是 Alpine.js this
(对此的快速解释是 imgFunc
在 Alpine.js 初始化之前运行以生成初始“状态”所以 this
是 window)
有两种方法可以修复它,要么使用 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>
或者您可以在 startImg 函数中设置 self = this
<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>
还有另一种方法可以做到这一点,即在 setInterval
回调中使用 .bind
,但这更加冗长和复杂。
正如 hugo 所提到的,this
的上下文无法解析为外部函数,因此您需要使用箭头函数,因为它没有上下文。
我做了一些更改以使用 alpine.js 来实现。
<link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.0.1/tailwind.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/alpinejs/2.7.3/alpine.js"></script>
<div x-data="imgFunc()">
<h1 class="text-xl py-3">Chosing the picture</h1>
<div class="w-1/2">
<img :src="currentImage" alt="Main Image">
</div>
<div>
<ul class="flex">
<template x-for='(image,index) in images'>
<li class="w-1/6 p-3" :class="{'border': currentImage===image}">
<img :src="image" alt="image1" @click="startImg(index)">
</li>
</template>
</ul>
</div>
</div>
<script>
function imgFunc() {
return {
currentImage: 'https://images.pexels.com/photos/5549634/pexels-photo-5549634.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=200&w=400',
images: [
'https://images.pexels.com/photos/5549634/pexels-photo-5549634.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=200&w=400',
'https://images.pexels.com/photos/5101387/pexels-photo-5101387.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
'https://images.pexels.com/photos/2363832/pexels-photo-2363832.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260'
],
startImg(index) {
this.currentImage = this.images[index];
if (index > 0)
return;
let i = 0;
var myvar = setInterval(() => {
i = (i >= this.images.length - 1) ? 0 : ++i;
this.currentImage = this.images[i];
}, 1000);
},
}
}
</script>