问题
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/
- Just click question num 36
- click "previous" button 10-15 times.
- 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