Horizontal scroll moving left and right when clicking previous button

微笑、不失礼 提交于 2020-01-03 02:32:06

问题


I was trying to move the horizontal scroll left and right when clicking the next and previous button. The problem I'm facing is that the scrolling moves left and right fast when clicking the next or previous buttons.

To reproduce my issue : https://jsfiddle.net/arunslb123/gzaLydkd/

  1. Just click question num 36
  2. click "previous" button 10-15 times.
  3. You can see the horizontal scroll moves here and there.

How to fix this issue?

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

回答1:


If you change your function to the following, it should keep the next / previous number in the middle of your view:

$(".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);
});

Updated fiddle

Edit

Scrap the previous stuff as you are mixing moving an absolutely positioned div with a scrolling it's outer div and that will lead to all sorts of problems. If you just change your js to the following, it should achieve what you want:

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

Updated fiddle




回答2:


The animation is getting called each time the button is clicked to before the animation queue declares a stop

You can use .stop() before .animate() to acheive this

$("#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);
});


来源:https://stackoverflow.com/questions/32118723/horizontal-scroll-moving-left-and-right-when-clicking-previous-button

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!