如果下一个和上一个按钮点击得太快,为什么这个简单的内容滑块会偏离轨道?

Why does this simple content slider get off track if the next and previous buttons are clicked too quickly?

本文关键字:简单 轨道 按钮 上一个 下一个 为什么 如果      更新时间:2023-09-26

我有一个简单的JavaScript内容滑块,它显示纯文本。它工作得相当好,除非你点击上一步和下一步太快。很难完全复制,但如果你随机反复地前后点击,会发生两件奇怪的事情:

  1. 空白幻灯片将间歇性出现并且…
  2. 两个幻灯片将重叠并作为一个。如有任何帮助,不胜感激。
http://jsfiddle.net/n52xmwLn/

// Testimonials
var thisItem = 1, nextItem = 0, range = 0
//for each content item, set an id, and hide.
$('.testimonial-item').each(function () {
  nextItem++;
  $(this).attr('id', nextItem).hide();
});
//range contains how many content items exist
range = nextItem, nextItem = 2, prevItem = range;
//display the first content item
thisHeight = $('#' + thisItem).height();
$('#' + thisItem).show();
$('.testimonials').css('height', thisHeight);
//hide old content item, show next item, resize content container
$('.testimonial-control.next').click(function () {
  prevItem = thisItem;
  //get height of next content item to resize container
  thisHeight = $('#' + nextItem).height();
  //resize content container
  $('.testimonials').animate({
    height: (thisHeight + 'px')
  }, 250, 'swing');
  //hide old content item
  $('#' + thisItem).fadeToggle(500, "linear");
  //show next content item
  $('#' + nextItem).fadeToggle(500, "linear");
  //set old content item to current item
  thisItem = nextItem;
  //loop to first item if range reached
  if (thisItem >= range) {
    nextItem = 1; prevItem = range - 1;
  } else {
    nextItem++; prevItem = thisItem - 1;
  }
});
//end next click function
//hide current content item, resize content container, show previous item 
$('.testimonial-control.prev').click(function () {
  //If we have reached the end range, the next item will be item #1
  if (nextItem == 1) {//so set the current item to the last
    thisItem = range;
  } else thisItem = nextItem - 1;
  //get height of next content item to resize container
  thisHeight = $('#' + prevItem).height();
  //resize content container
  $('.testimonials').animate({
    height: (thisHeight + 'px')
  }, 250, 'swing');
  //hide old content item
  $('#' + thisItem).fadeToggle(500, "linear");
  //show next content item
  $('#' + prevItem).fadeToggle(500, "linear");
  //set next content item to current item
  nextItem = thisItem;
  if (prevItem >= range) {//if at end of items
    nextItem = 1;//first
    prevItem = range - 1;
    thisItem = range;
  } else if (prevItem <= 1) {//if at start of items
    prevItem = range;
    thisItem = 1;
    nextItem = 2;
  } else {//if in the middle of items
    prevItem--;
    thisItem--;
  }
});

//结束预点击功能

这很可能发生,因为动画/fadetoggle代码在另一个点击发生之前没有完成。

你应该阻止你的点击函数的处理,直到动画完成。为了完成这个任务,我将执行以下操作:

添加一个全局布尔变量来跟踪动画的状态,比如…var animating = false;

将所有的click函数封装在if块中,这样它们就不会运行

animating为真。在if( ! animating ) { animating = true; ... }

块内设置animating为true最后一步是在fadeToggle的完整回调中设置animating为false: $('#' + thisItem).fadeToggle(500, "linear", function() { animating = false; });

您需要将.stop().stopPropagation()添加到您的所有动画函数中,以防止它们相互"碰撞":JSFiddle

另外,不要忘记CSS中的结束括号},它会把一切都搞砸。

// Testimonials
var thisItem = 1, nextItem = 0, range = 0
//for each content item, set an id, and hide.
$('.testimonial-item').each(function () {
  nextItem++;
  $(this).attr('id', nextItem).stop().hide();
});
//range contains how many content items exist
range = nextItem, nextItem = 2, prevItem = range;
//display the first content item
thisHeight = $('#' + thisItem).stop().height();
$('#' + thisItem).stop().show();
$('.testimonials').css('height', thisHeight);
//hide old content item, show next item, resize content container
$('.testimonial-control.next').click(function (e) {
    e.stopPropagation();
  prevItem = thisItem;
  //get height of next content item to resize container
  thisHeight = $('#' + nextItem).stop().height();
  //resize content container
  $('.testimonials').stop().animate({
    height: (thisHeight + 'px')
  }, 250, 'swing');
  //hide old content item
  $('#' + thisItem).stop().fadeToggle(500, "linear");
  //show next content item
  $('#' + nextItem).stop().fadeToggle(500, "linear");
  //set old content item to current item
  thisItem = nextItem;
  //loop to first item if range reached
  if (thisItem >= range) {
    nextItem = 1; prevItem = range - 1;
  } else {
    nextItem++; prevItem = thisItem - 1;
  }
});
//end next click function
//hide current content item, resize content container, show previous item 
$('.testimonial-control.prev').click(function (e) {
    e.stopPropagation();
  //If we have reached the end range, the next item will be item #1
  if (nextItem == 1) {//so set the current item to the last
    thisItem = range;
  } else thisItem = nextItem - 1;
  //get height of next content item to resize container
  thisHeight = $('#' + prevItem).stop().height();
  //resize content container
  $('.testimonials').stop().animate({
    height: (thisHeight + 'px')
  }, 250, 'swing');
  //hide old content item
  $('#' + thisItem).stop().fadeToggle(500, "linear");
  //show next content item
  $('#' + prevItem).stop().fadeToggle(500, "linear");
  //set next content item to current item
  nextItem = thisItem;
  if (prevItem >= range) {//if at end of items
    nextItem = 1;//first
    prevItem = range - 1;
    thisItem = range;
  } else if (prevItem <= 1) {//if at start of items
    prevItem = range;
    thisItem = 1;
    nextItem = 2;
  } else {//if in the middle of items
    prevItem--;
    thisItem--;
  }
});
//end prev click function