水平滚动在点击上一个按钮时左右移动

Horizontal scroll moving left and right when clicking previous button

本文关键字:按钮 左右 移动 上一个 滚动 水平      更新时间:2023-09-26

我试图在点击下一个和上一个按钮时左右移动水平滚动条。我面临的问题是,当点击下一个或上一个按钮时,滚动向左和向右移动得很快。

重现我的问题:https://jsfiddle.net/arunslb123/gzaLydkd/

  1. 点击问题编号36
  2. 点击"上一步"按钮10-15次。
  3. 你可以看到水平滚动条到处移动。

如何解决这个问题?

function select($elem) {
$(".numberItem").removeClass("selected");
$elem.addClass("visited").addClass("selected");
focus($elem[0]);
}
function focus(elem) {
var stripPos = $strip.position(),
    numPos = $(elem).offset(),
    elemWidth = $(elem).width() + margin,
    numRight = numPos.left + elemWidth;
if (numRight > wrapWidth) {
    $strip.css({"left": stripPos.left - elemWidth});
  }
if (numPos.left < (margin + $leftArrow.width()))  {
    $strip.css({"left": stripPos.left + elemWidth});
 }
}
$(".controls").on("click", ".button", function() {
var $sel = $(".selected"), numPos, $sel, elemWidth;
  $elem = $sel.length > 0 ? $sel.first() : $(".numberItem").first();
if (this.id == "lft") {
    $sel = $elem.prev().length > 0 ? $elem.prev() : $elem;
    select($sel);
} else {
    $sel = $elem.next().length > 0 ? $elem.next() : $elem;
    select($sel);
}
numPos = $sel.offset(); elemWidth = $sel.width() + margin;
numRight = numPos.left + elemWidth;
if (numPos.left > wrapWidth) {
    $strip.css({"left": -($sel.text()) * $sel.width() });
}
if (numRight < 0) {
    $strip.css({"left": +($sel.text()) * $sel.width() });
}
});

在动画队列声明停止之前,每次按钮被点击动画都会被调用

您可以在.animate()之前使用.stop()来实现此

$("#left-arrow").click(function () {
  var leftPos = $('#numWrap').scrollLeft();
$("#numWrap").stop().animate({scrollLeft: leftPos - 200}, 800);
});
$("#right-arrow").click(function () {
  var leftPos = $('#numWrap').scrollLeft();
$("#numWrap").stop().animate({scrollLeft: leftPos + 200}, 800);
});

如果您将函数更改为以下内容,它应该在视图中间保留下一个/上一个数字:

$(".controls").on("click", ".button", function() {
    var $sel = $(".selected"), numPos, $sel, elemWidth;
      $elem = $sel.length > 0 ? $sel.first() : $(".numberItem").first();
    if (this.id == "lft") {
        $sel = $elem.prev().length > 0 ? $elem.prev() : $elem;
        select($sel);
    } else {
        $sel = $elem.next().length > 0 ? $elem.next() : $elem;
        select($sel);
    }
    numPos = $sel.position(); 
    elemWidth = $sel.width() / 2;
    scroll = numPos.left + elemWidth - ($('#numWrap').width() / 2);
    $strip.animate({left: -scroll}, 800);
});

更新小提琴

编辑

废弃之前的东西,因为你是混合移动一个绝对定位的div与滚动它的外部div,这将导致各种各样的问题。如果你把js改成下面的代码,它应该能达到你想要的效果:

// same as before
fillQuestion(40);
function fillQuestion(num){
    for (var i = 1; i <= num; i++) {
        var $d = $("<a href='#' class='numberItem'>" + i + "</a>");
        $("#strip").append($d);
    }
}
// after you have done your usual stuff, this is where the new code begins
var items = $('.numberItem'),
    selectedIndex = 0,
    scroller = $("#numWrap"),
    scrollerWidth = scroller.width();
selectItem();  // select first item - change the selected index var above to start on a different number
items.on('click', function(e) {
    e.preventDefault();  // prevent default action of link
    selectedIndex = items.index($(this)); // set new selected index to this index
    selectItem();
});
$('.controls .btn').on('click', function() {
    var button = $(this);
    if (button.hasClass('prev') && selectedIndex > 0) {
        selectedIndex--;
    } else if (button.hasClass('next') && selectedIndex < items.length - 1) {
        selectedIndex++;
    }
   selectItem();
});
function selectItem() {
    var selected = items.eq(selectedIndex); // set selected item to current selected index
    items.removeClass('selected');  // remove selected from any items
    selected.addClass('visited selected');  // add selected to current item
    focus(selected.position().left);
}
function focus(originalLeft) {
    scroll = originalLeft - (scrollerWidth / 2);
    scroller.stop().animate({
        scrollLeft: scroll
    }, 800);
}

更新小提琴