如何在不同的函数中引用clearInterval的变量



我有一个圆形图像,我想点击一个按钮旋转,然后点击另一个按钮停止。

spin((函数有效,但stop((不起作用,因为值在spin(((函数之外死亡(如果我错了,请纠正我(。我应该如何解决这个问题?我对使用相同的按钮旋转和停止持开放态度,但我的if-else语句产生了相同的结果——旋转图像有效,但我无法停止它

另一个意想不到的错误是,如果我多次点击旋转按钮,旋转会更快。

这是我的代码:

var spinImage;  
function spin(){
spinImage = document.getElementById('spinImage'), degree = 0;
setInterval(function() {
spinImage.style.transform = "rotate(" + ++degree + "deg)";}, 1);
}
function stop(){
clearInterval(spinImage);
}

我需要坚持使用纯javascript,并使用setInterval/clearInterval方法。

您要查找的值是setInterval:的返回值

var intervalId;
function spin() {
var spinImage = document.getElementById('spinImage');
var degree = 0;
intervalId = setInterval(function() {
spinImage.style.transform = 'rotate(' + ++degree + 'deg)';
}, 1);
}
function stop() {
clearInterval(intervalId);
}

初始化setInterval时需要获取id(此处存储在spin变量中(。该变量将引用setInterval,以便您可以使用stop函数清除它。

另一个意外的错误(faster spinning on consecutive clicks(是由于以前的setInterval id没有被清除,而是创建了一个新的。所以,你点击的次数;你会有那么多setIntervals。为了避免这种情况,您需要清除现有的id,然后使用新的设置间隔重新初始化。

已修复代码。请参阅:

var spinImage;
var spin;  
function spin(){
spinImage = document.getElementById('spinImage');
degree = 0;
if(spin) stop();
spin = setInterval(function() {
spinImage.style.transform = "rotate(" + ++degree + "deg)";
}, 1);
}
function stop(){
clearInterval(spin);
}

希望能有所帮助。回复任何疑问/澄清

您需要记住间隔id,这样才能停止它。

let intervalId = null;
function spin() {
spinImage = document.getElementById('spinImage'), degree = 0;
intervalId = setInterval(function() {
spinImage.style.transform = "rotate(" + ++degree + "deg)";
}, 1);
}
function stop() {
clearInterval(intervalId);
}

ES6级

您可以将这个逻辑封装到一个可重用的类对象中,即ImageSpinner

const main = () => {
const spinner = new ImageSpinner('#spinImage');
addEventListeners('.btn-toggle', 'click', (e) => {
spinner.toggle();
let attr = `data-text-${spinner.isRunning() ? 'off' : 'on'}`;
e.currentTarget.textContent = e.currentTarget.getAttribute(attr);
});
addEventListeners('.btn-reset', 'click', (e) => {
spinner.reset();
let btn = document.querySelector('.btn-toggle');
btn.textContent = btn.getAttribute('data-text-on');
});
}
class ImageSpinner {
constructor(selector, rate) {
/* @protected */ this.image = document.querySelector(selector);
/* @protected */ this.rate = rate;
/* @private   */ this.__intervalId = null;
/* @private   */ this.__degree = 0;
}
/* @public */ isRunning() {
return this.__intervalId != null;
}
/* @public */ reset() {
if (this.isRunning()) this.stop();
this.__degree = 0;
this.__rotate();
}
/* @public */ start() {
if (!this.isRunning()) {
this.__intervalId = setInterval(() => { this.update() }, this.rate);
} else {
console.log('Already running...');
}
}
/* @public */ stop() {
if (this.isRunning()) {
clearInterval(this.__intervalId);
this.__intervalId = null;
} else {
console.log('Not currently running...');
}
}
/* @public */ toggle() {
this.isRunning() ? this.stop() : this.start();
}
/* @protected */ update() {
this.__degree = (this.__degree + 1) % 360;
this.__rotate();
}
/* @private */ __rotate() {
this.image.style.transform = "rotate(" + this.__degree + "deg)";
}
}
/*
* Can either be an object of event handlers,
* or an event name followed by a function.
*/
function addEventListeners(elementsOrSelector, events) {
((els) => els.forEach(el => 
(typeof events === 'string' && arguments.length > 2)
? el.addEventListener(arguments[1], arguments[2])
: Object.keys(events)
.forEach(name => el.addEventListener(name, events[name]))))
(Array.from((typeof elementsOrSelector === 'string')
? document.querySelectorAll(elementsOrSelector)
: elementsOrSelector.entries
? elementsOrSelector
: [elementsOrSelector]));
}
main(); // Execute main function
body {
background: #222;
padding: 1.25em;
}
img {
border: 2px dotted white;
margin-left: 0.5em;
}
.btn-wrapper {
margin-top: 1.75em;
}
.btn-toggle {
display: inline-block;
width: 64px;
cursor: pointer;
}
<img id="spinImage" src="https://lh5.googleusercontent.com/-ajlbNdBMWwA/AAAAAAAAAAI/AAAAAAAAAAo/ND2LpoxaqAQ/photo.jpg?sz=96" alt="" width="96" height="96"/>
<div class="btn-wrapper">
<button class="btn btn-toggle" data-text-on="Start" data-text-off="Pause">Start</button>
<button class="btn btn-reset">Reset</button>
</div>

<!DOCTYPE html>
<head>
<title>Spin</title>
</head>
<body>
<button id='spinStart'>Start</button>
<button id='spinStop'>Stop</button>
<script>
var spinning = false;
var handle;
var counter = 0;
// Add click event listener to the start button
window.document.getElementById('spinStart').addEventListener("click", start);
// Add click event listener to the stop button
window.document.getElementById('spinStop').addEventListener("click", stop);
function start() {
if(spinning === true) {
console.log('spinning already')
// Do nothing here as it's already spinning.
spinning = !spinning;
} 
if(spinning === false) {
// Not spinning here, so we have to init the setInterval
handle = setInterval(() => {
console.log(counter);
counter++;
}, 1000);
spinning = !spinning;
}
}
function stop() {
//We only want to stop the spinner if it's actually spinning
if(spinning === true){
console.log('clearing the interval now!');
clearInterval(handle);
}
}
</script>
</body>
</html>

根据需要替换代码。

最新更新