gpt4 book ai didi

javascript - 如何防止 setInterval() 倍增?

转载 作者:行者123 更新时间:2023-12-03 07:38:51 30 4
gpt4 key购买 nike

我正在修改A Better Simple Slideshow具有暂停能力。我已经设法将 autoCycle() 中的暂停和取消暂停分离到它们自己的方法中(pauseCycle 和 unpauseCycle),因此我可以将它们用于暂停控制以及 autoCycle()。我创建了 addPause() 方法来生成暂停控件。 addPause() 方法成功地暂停了幻灯片放映,但在取消暂停幻灯片放映时使用 setInterval() 或传递给它的间隔变量做了一些奇怪的事情。它似乎导致另外一个 setInterval() 同时运行。代码如下:

var aFSlides = function(el, options) {
var $slideshows = document.querySelectorAll(el), // a collection of all of the slideshows
$slideshow = {},
Slideshow = {
init: function(el, options) {
this.counter = 0; // to keep track of current slide
this.interval = 0; // to control autoCycle
this.paused = 0; // to keep track of whether paused or not
this.el = el; // current slideshow container
this.$items = el.querySelectorAll('figure'); // a collection of all of the slides, caching for performance
this.numItems = this.$items.length; // total number of slides
options = options || {}; // if options object not passed in, then set to empty object
// options.auto = options.auto || false; // if options.auto object is not passed in, then set to false
this.opts = {
auto: (typeof options.auto === "undefined") ? false : options.auto,
speed: (typeof options.speed === "undefined") ? 6000 : options.speed,
pause: (typeof options.pause === "undefined") ? false : options.pause,
pauseOnHover: (typeof options.pauseOnHover === "undefined") ? true : options.pauseOnHover,
};
this.$items[0].classList.add('current'); // add .current class to first figure
if (this.opts.auto) {
this.autoCycle(this.el, this.opts.speed, this.opts.pauseOnHover);
}
if (this.opts.pause) {
this.addPause(this.el);
}
},
showCurrent: function(i) {
// increment or decrement this.counter depending on whether i === 1 or i === -1
if (i > 0) {
this.counter = (this.counter + 1 === this.numItems) ? 0 : this.counter + 1;
} else {
this.counter = (this.counter - 1 < 0) ? this.numItems - 1 : this.counter - 1;
}
// remove .show from whichever element currently has it
// http://stackoverflow.com/a/16053538/2006057
[].forEach.call(this.$items, function(el) {
el.classList.remove('current');
});
// add .show to the one item that's supposed to have it
this.$items[this.counter].classList.add('current');
},
pauseCycle: function(el, speed) {
var that = this;
interval = clearInterval(interval);
el.classList.add('paused');
},
unpauseCycle: function(el, speed) {
var that = this;
interval = window.setInterval(function() {
that.showCurrent(1); // increment & show
}, speed);
el.classList.remove('paused');
},
addPause: function(el, speed) {
var spanPause = document.createElement("span"),
docFrag2 = document.createDocumentFragment(),
that = this,
thatSpeed = speed;
spanPause.classList.add('pause');
spanPause.innerHTML = 'Pause';
docFrag2.appendChild(spanPause);
el.appendChild(docFrag2);
togglePause = function(el, speed) {
if (that.paused == 1) {
var speed = that.opts.speed;
that.unpauseCycle(el, speed);
that.paused = 0;
return that.paused;
} else if (that.paused == 0) {
var speed = that.opts.speed;
interval = clearInterval(interval);
that.pauseCycle(el, speed);
that.paused = 1;
return that.paused;
}
}
el.querySelector('.pause').addEventListener('click', function() {
togglePause(el, speed);
}, false);
},
autoCycle: function(el, speed, pauseOnHover) {
var that = this;
if (that.paused == 0) {
that.unpauseCycle(el, speed);
}
if (pauseOnHover) {
el.addEventListener('mouseover', function() {
if (that.paused == 0) {
that.pauseCycle(el, speed);
}
}, false);
el.addEventListener('mouseout', function() {
if (that.paused == 0) {
that.unpauseCycle(el, speed);
}
}, false);
} // end pauseonhover
} // end autoCycle
}; // end Slideshow object .....
// make instances of Slideshow as needed
[].forEach.call($slideshows, function(el) {
$slideshow = Object.create(Slideshow);
$slideshow.init(el, options);
});
};

/* Init for this example snippet */

var aFS56c641d29d032 = {
auto: true,
speed: 2000,
pause: true,
};
aFSlides('.aFS56c641d29d032', aFS56c641d29d032);
body {
font: 400 10px/1.3 Menlo, Courier, sans-serif;
}
figure {
display: none;
}
figure.current {
display: block;
}
figure pre {
font: 700 24px/1.3 Menlo, Courier, sans-serif;
white-space: pre;
}
span {
background: #f66;
color: #fff;
font: 700 16px/1.3 Menlo, Courier, sans-serif;
padding: 10px 20px;
display: inline-block;
}
<div id="smile-gallery" class="aFS56c641d29d032 ">
<div class="slides">
<figure class="slide" id="bna-1">
<div class="slide-content">
<pre>
________________________
| |
| |
| 0 0 |
| |
| \________/ |
| |
|________________________|
</pre>
</div>
</figure>
<figure class="slide" id="bna-2">
<div class="slide-content">
<pre>
________________________
| |
| |
| o O |
| |
| |
| ______/ |
|________________________|
</pre>
</div>
</figure>
<figure class="slide" id="bna-3">
<div class="slide-content">
<pre>
________________________
| |
| |
| ^ ^ |
| |
| |
| (EEEEE) |
|________________________|
</pre>
</div>
</figure>
<figure class="slide" id="bna-4">
<div class="slide-content">
<pre>
________________________
| |
| |
| | | |
| ____________ |
| \ / |
| \________/ |
|________________________|
</pre>
</div>
</figure>
</div>
<!-- /.slides -->
</div>
<!-- /#smile-gallery -->
<p>
Taken from <a href="https://github.com/leemark/better-simple-slideshow" target="_blank">A Better Simple Slideshow</a>.
</p>

当您运行此脚本时,如果您使用“暂停”控件,则会发生一些奇怪的事情。首先,它会暂停并禁用pauseOnHover 条件,就像它应该做的那样。然后您再次单击它,它会取消暂停并开始一次前进两张幻灯片。 PauseOnHover 再次起作用,但仅在悬停时暂停一张幻灯片的前进,因此幻灯片仍然一次前进一张幻灯片。再次单击“暂停”,它会停止前进两次,但会继续一次前进一张幻灯片(现在应该暂停)。再次单击 ,它开始一次前进三帧(如果您再次将鼠标悬停在其上,则前进两帧),依此类推。每次都会不断添加一些东西,但我不知道它是什么。请帮忙。

谢谢!

2016 年 2 月 22 日更新

Here's a JSFiddle我一直在为这个项目工作。让pause和pauseOnHover同时工作是一场噩梦。

最佳答案

区间变量需要绑定(bind)到正确的范围(this)。因此,无论您在何处引用变量“interval”,都需要在其前面加上“this”前缀。

在代码中搜索“CHANGED”以查看我在何处进行了更改。

var aFSlides = function(el, options) {
var $slideshows = document.querySelectorAll(el), // a collection of all of the slideshows
$slideshow = {},
Slideshow = {
init: function(el, options) {
this.counter = 0; // to keep track of current slide
this.interval = 0; // to control autoCycle
this.paused = 0; // to keep track of whether paused or not
this.el = el; // current slideshow container
this.$items = el.querySelectorAll('figure'); // a collection of all of the slides, caching for performance
this.numItems = this.$items.length; // total number of slides
options = options || {}; // if options object not passed in, then set to empty object
// options.auto = options.auto || false; // if options.auto object is not passed in, then set to false
this.opts = {
auto: (typeof options.auto === "undefined") ? false : options.auto,
speed: 300, // CHANGED: faster for development
//speed: (typeof options.speed === "undefined") ? 6000 : options.speed,
pause: (typeof options.pause === "undefined") ? false : options.pause,
pauseOnHover: (typeof options.pauseOnHover === "undefined") ? true : options.pauseOnHover,
};
this.$items[0].classList.add('current'); // add .current class to first figure
if (this.opts.auto) {
this.autoCycle(this.el, this.opts.speed, this.opts.pauseOnHover);
}
if (this.opts.pause) {
this.addPause(this.el);
}
},
showCurrent: function(i) {
// increment or decrement this.counter depending on whether i === 1 or i === -1
if (i > 0) {
this.counter = (this.counter + 1 === this.numItems) ? 0 : this.counter + 1;
} else {
this.counter = (this.counter - 1 < 0) ? this.numItems - 1 : this.counter - 1;
}
// remove .show from whichever element currently has it
// http://stackoverflow.com/a/16053538/2006057
[].forEach.call(this.$items, function(el) {
el.classList.remove('current');
});
// add .show to the one item that's supposed to have it
this.$items[this.counter].classList.add('current');
},
pauseCycle: function(el, speed) {
var that = this;
clearInterval(this.interval); // CHANGED: clearInterval doesn't return anything usefull
el.classList.add('paused');
},
unpauseCycle: function(el, speed) {
var that = this;
// CHANGED x2:
window.clearInterval(this.interval);
this.interval = window.setInterval(function() {
that.showCurrent(1); // increment & show
}, speed);
el.classList.remove('paused');
},
addPause: function(el, speed) {
var spanPause = document.createElement("span"),
docFrag2 = document.createDocumentFragment(),
that = this,
thatSpeed = speed;
spanPause.classList.add('pause');
spanPause.innerHTML = 'Pause';
docFrag2.appendChild(spanPause);
el.appendChild(docFrag2);
togglePause = function(el, speed) {

if (that.paused == 1) {
var speed = that.opts.speed;
that.unpauseCycle(el, speed);
that.paused = 0;
return that.paused;
} else if (that.paused == 0) {
var speed = that.opts.speed;
// CHANGED
clearInterval(that.interval);
//interval = clearInterval(that.interval);
that.pauseCycle(el, speed);
that.paused = 1;
return that.paused;
}
}
el.querySelector('.pause').addEventListener('click', function() {
togglePause(el, speed);
}, false);
},
autoCycle: function(el, speed, pauseOnHover) {
var that = this;
if (that.paused == 0) {
that.unpauseCycle(el, speed);
}
if (pauseOnHover) {
el.addEventListener('mouseover', function() {
if (that.paused == 0) {
that.pauseCycle(el, speed);
}
}, false);
el.addEventListener('mouseout', function() {
if (that.paused == 0) {
that.unpauseCycle(el, speed);
}
}, false);
} // end pauseonhover
} // end autoCycle
}; // end Slideshow object .....
// make instances of Slideshow as needed
[].forEach.call($slideshows, function(el) {
$slideshow = Object.create(Slideshow);
$slideshow.init(el, options);
});
};

/* Init for this example snippet */

var aFS56c641d29d032 = {
auto: true,
speed: 2000,
pause: true,
};
aFSlides('.aFS56c641d29d032', aFS56c641d29d032);
body {
font: 400 10px/1.3 Menlo, Courier, sans-serif;
}
figure {
display: none;
}
figure.current {
display: block;
}
figure pre {
font: 700 24px/1.3 Menlo, Courier, sans-serif;
white-space: pre;
}
span {
background: #f66;
color: #fff;
font: 700 16px/1.3 Menlo, Courier, sans-serif;
padding: 10px 20px;
display: inline-block;
}
<div id="smile-gallery" class="aFS56c641d29d032 ">
<div class="slides">
<figure class="slide" id="bna-1">
<div class="slide-content">
<pre>
________________________
| |
| |
| 0 0 |
| |
| \________/ |
| |
|________________________|
</pre>
</div>
</figure>
<figure class="slide" id="bna-2">
<div class="slide-content">
<pre>
________________________
| |
| |
| o O |
| |
| |
| ______/ |
|________________________|
</pre>
</div>
</figure>
<figure class="slide" id="bna-3">
<div class="slide-content">
<pre>
________________________
| |
| |
| ^ ^ |
| |
| |
| (EEEEE) |
|________________________|
</pre>
</div>
</figure>
<figure class="slide" id="bna-4">
<div class="slide-content">
<pre>
________________________
| |
| |
| | | |
| ____________ |
| \ / |
| \________/ |
|________________________|
</pre>
</div>
</figure>
</div>
<!-- /.slides -->
</div>
<!-- /#smile-gallery -->
<p>
Taken from <a href="https://github.com/leemark/better-simple-slideshow" target="_blank">A Better Simple Slideshow</a>.
</p>

关于javascript - 如何防止 setInterval() 倍增?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35496761/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com