下面代码,点击一次向左,等完成后,再点击没问题,如果一直点,快速点,到头后还能跑过,这个怎么处理,是不是应该让点击执行完后才可再次点击,应该怎么写
<div class="cover no-select">
<ul style="left:226px;" class="cover-imgs">
<li><img src="img.jpg" data-id="106851470"></li>
<li><img src="img.jpg" data-id="101810541"></li>
<li><img src="img.jpg" data-id="101810525"></li>
<li><img src="img.jpg" data-id="101810507"></li>
</ul>
<div class="left arrow none">
<div class="arrow-img"></div>
</div>
<div class="right arrow">
<div class="arrow-img"></div>
</div>
</div>
$(document).ready(function () {
var $Imgs=$('.no-select .cover-imgs'),
$ImgsLi=$Imgs.children('li'),
$ImgsLen=$ImgsLi.length,
$ImgsLeft=$('.no-select .left .arrow-img'),
$ImgsRight=$('.no-select .right .arrow-img');
$ImgsLeft.bind('mousedown',function(){
if( ($Imgs.position().left >= 0) ){
$(this).parent().addClass('none');
}
if( ($Imgs.position().left < 226) ){
var nowLeft = $Imgs.position().left+226;
$ImgsRight.parent().removeClass('none');
$Imgs.animate({'left':nowLeft},300);
}
});
$ImgsRight.bind('mousedown',function(){
if( ($Imgs.position().left <= 226) && ($Imgs.position().left >= (-($ImgsLen-3)*226)) ){
var nowLeft = $Imgs.position().left-226;
$ImgsLeft.parent().removeClass('none');
$Imgs.animate({'left':nowLeft},300);
}
if( $Imgs.position().left <= (-($ImgsLen-3)*226) ){
$(this).parent().addClass('none');
}
});
});
有jsfiddle就很容易调了。
第一想法当然是“让
mousedown
事件在执行完毕之前不能重复触发”。但千万小心——这个显然的思路完全不对:因为jQuery的动画过程是异步的!无论动画多长,这个mousedown
事件都会立刻执行完毕。控制这个事件的重复触发必然是错误的。正确的方法是:让动画效果的播放过程中,不再触发
mousedown
事件。我用了个简单的方法:
.animate()
的回调函数,控制动画结束后把标志去掉。mousedown
事件执行时看到了标志,则直接跳出,不做实际动作。http://jsfiddle.net/N72mP/5/
标志数据打在容器父元素上(而不是打在
this
上)的意义,是因为动画效果是针对容器而言唯一,而不是针对按钮而言。这样做可以防止先按【右】,赶在动画结束前再迅速按【左】引发的bug。