首页 > 一个JQ问题,左右移动问题

一个JQ问题,左右移动问题

下面代码,点击一次向左,等完成后,再点击没问题,如果一直点,快速点,到头后还能跑过,这个怎么处理,是不是应该让点击执行完后才可再次点击,应该怎么写

http://jsfiddle.net/N72mP/1/

<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');
        }
    });
});

这问题我也碰到过,当时研究了github的一些轮播的源码。
终于找到了通用的解决办法啊。
同沙渺所说的算法。
可以参考本人写的一个图片轮播插件:https://github.com/xiaomingming/easySwitch/blob/master/js/easySwitch.js 中的scroll方法实现。

实际上,解决当前的动画累积问题,需要使用stop方法,而对于当前动画和其他动画的先后执行,则需要stop方法配合设置动画标志位来共同协调的。

因此楼上举例stop太过片面了。




<script> $(".banpic li:first").clone(true).appendTo(".banpic") $(".banpic li:last").prev("li").clone(true).prependTo(".banpic") $(function () { var container = $('.banner'); var list = $('.banpic'); var prev = $('.prev'); var next = $('.next'); var len = $(".banpic li").length-2; var index = 1; var interval = 5000; var timer; list.width(1000*(len+2)); function animate (offset) { var left = parseInt(list.css('left')) + offset; if (offset>0) { offset = '+=' + offset; } else { offset = '-=' + Math.abs(offset); } list.animate({'left': offset}, 1000, function () { if(left > -200){ list.css('left', -1000 * len); } if(left < (-1000 * len)) { list.css('left', -1000); } }); } function play() { timer = setTimeout(function () { next.trigger('click'); play(); }, interval); } function stop() { clearTimeout(timer); } next.bind('click', function () { if (list.is(':animated')) { return; } if (index == len) { index = 1; } else { index += 1; } animate(-1000); }); prev.bind('click', function () { if (list.is(':animated')) { return; } if (index == 1) { index = len; } else { index -= 1; } animate(1000); }); container.hover(stop, play); play(); }); </script>

有jsfiddle就很容易调了。

第一想法当然是“让mousedown事件在执行完毕之前不能重复触发”。但千万小心——这个显然的思路完全不对:因为jQuery的动画过程是异步的!无论动画多长,这个mousedown事件都会立刻执行完毕。控制这个事件的重复触发必然是错误的。

正确的方法是:让动画效果的播放过程中,不再触发mousedown事件

我用了个简单的方法:

  1. 并不刻意反复的启用/禁止事件响应。
  2. 动画开始前,设定容器元素的一个标志。
  3. 使用.animate()的回调函数,控制动画结束后把标志去掉。
  4. 如果mousedown事件执行时看到了标志,则直接跳出,不做实际动作。

http://jsfiddle.net/N72mP/5/

标志数据打在容器父元素上(而不是打在this上)的意义,是因为动画效果是针对容器而言唯一,而不是针对按钮而言。这样做可以防止先按【右】,赶在动画结束前再迅速按【左】引发的bug。


加个计数器,默认为0,然后在绑定的事件里加判断。
为0时,不执行左翻,为N(tab个数)-1时不执行右翻。

或用第三方库,省去自己写了,站在巨人肩上,这就是开源的意义所在。
我用阿里系的:http://aralejs.org/switchable/examples/carousel.html

用过Requirejs之类的模块加载器会很容易上手,没用过看一遍文档也基本会了。


题主把一个简单的幻灯片弄得太复杂了

    var $ImgsLeft=$('.no-select .left .arrow-img')
  var n=$('li img').size();
            $ImgsLeft.click(function(){
                if(n>=0)
        {
            $('ul').stop(true,true).animate({left:'-=46px'});
            n--
        }
})
【热门文章】
【热门文章】