如何在不中断前一次执行的情况下多次执行相同的单击事件?

时间:2016-10-12 17:44:14

标签: javascript

我有一个移动元素的按钮(将top位置改为100px)并且转换需要时间(1.5秒)。
我发现,如果用户点击几次并且非常快,则在按钮中最终位置不会是预期的,因为当它仍然在前一个位置的中间时会开始新的转换。
我的目标是确保每次按钮点击都会使元素移动100px,无论用户点击按钮的速度有多快,因此下一次移动只会在上一次移动后开始,依此类推。 我的代码是:

    var extHeight = parseInt($(this).siblings('.screen').css('height'), 10);
    var intHeight = parseInt($(this).children('.wrap').css('height'), 10);
    var maxScroll = intHeight - extHeight;
    var pos = parseInt($(this).children('.wrap').css('top'), 10);
    if (maxScroll - 100 > -pos) {
      $(this).children('.wrap').css({'top': pos-100+'px'});
    }

我尝试过使用setTimeout和计数器但没有成功。 PS:我正在使用这个内联。

3 个答案:

答案 0 :(得分:0)

尝试这样的事情:

$(this).children('.wrap').stop(true, true).css({'top': pos-100+'px'});

或其他停止参数

  

我们可以在没有常见问题的情况下创建漂亮的淡入淡出效果   通过将.stop(true,true)添加到链中来添加多个排队动画:

来自here

Stop the currently-running animation on the matched elements.

  

如果clearQueue参数的值为true,则队列中的其余动画将被删除,并且永远不会运行。

答案 1 :(得分:0)

此示例等待一定的时间来处理下一个单击事件。您可能希望将其设置为1.5秒。它显示了去抖方法的使用。它基本上取消了按钮的所有点击事件一段时间,直到事件(处理css定位)结束。

function debounce(func, wait, immediate){
	var timeout;
	return function(){
		var context = this, args = arguments;

		var callNow = immediate && !timeout;

		clearTimeout(timeout);
		timeout = setTimeout(function(){
			timeout = null;

			if(!immediate){
				func.apply(context, args);
			}
		}, wait);

		if(callNow) func.apply(context, args)
	}
}

var myEfficientFn = debounce(function(){
	$(".box").css({"top": "+=100"})
}, 5000, true)

$("button").on("click", myEfficientFn)
.box{
  width:50px;
  height:50px;
  background: pink;
  position:relative;
  left: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<div class="box"></div>
<button>button</button>

答案 2 :(得分:0)

我找到了一个满足我所有要求的解决方案(其他响应在正在进行的转换结束后没有处理所有点击的执行)。 我在全局范围内定义控制变量:

var upClick = 0; var timelineIsMoving = false;

然后代码是(我使用内联事件):

onclick="$this = $(this);
        if (timelineIsMoving == true) {upClick = upClick + 1} else {upClickF()};
        function upClickF(){
          timelineIsMoving = true;
          if(upClick > 0) {upClick = upClick - 1};
          var pos = parseInt($this.children('.layer3.wrap').css('top'), 10);
          if (pos < 0) {
             $this.children('.layer3.wrap').css({'top': pos-100+'px'});
          };
          setTimeout(function(){
            timelineIsMoving = false;
            if (upClick > 0) {upClickF()}
          }, 1500)
        }

这使用递归函数,该函数仅在移动结束时以及如果要执行排队点击时运行。