Crooksyard
Crooksyard

Reputation: 39

Simple previous and next button for horizontal scrolling to next div jQuery

(I'm aware that there previously have been some questions on this topic, but I can't seem to make this work in my situation.) I want to both be able to scroll horizontal through some text, as well as using 'previous' and 'next' buttons to help navigate through the text (the text is split up into numerous divs). I want the user to be able to switch at all times. I know that some solutions offer setting an active class to the div in view, but that doesn't seem to work with scrolling.

Creating a 'next' button doesn't seem to be the problem, but I can't figure out how to make the previous button work correctly.

This is what I have so far on jsfiddle

$(document).ready(function(){
$('#next').click(function() {
   var target;
   $(".section").each(function(i, element) {
     target = $(element).offset().left;
     if (target - 10 > $(document).scrollLeft()) {
       return false; 
     }});
   $("html, body").animate({
     scrollLeft: target
}, 500);
});
});

I also found this solution in which the next button doesn't work, but it seems to overcomplicate it (or maybe it really is necessary to add more divs and make the jQuery extremely difficult for me to comprehend) jsfiddle

    var currentElement = $("#bodytext > div:nth-child(2)");
var onScroll = function () {
    var container = $("#main");
    var bodytext = $("#bodytext");
    var children = $(".section");
    var position = 0;
    for (var i = 0; i < children.length; i++) {
        var child = $(children[i]);
        var childLeft = container.offset().left < child.offset().left;
        if (childLeft) {
            currentElement = child;
            console.log(currentElement);
            return;
        }
    }
};

var scrollToElement = function ($element) {
    var container = $("#main");
    var bodytext = $("#bodytext");
    var children = $(".section");
    var width = 0;
    for (var i = 0; i < children.length; i++) {
        var child = $(children[i]);
        if (child.get(0) == $element.get(0)) {
            if (i === 0) {
                width = 0;
            }
            container.animate({
                scrollLeft: width
            }, 500);
            onScroll();
        }
        if (child.next().length > 0) {
            width += child.next().offset().left - child.offset().left;
        } else {
            width += child.width();
        }
    }
};

var next = function (e) {
    scrollToElement(currentElement);
}

var previous = function (e) {
    var container = $("#main");
    if (currentElement.prev().length > 0) {
        if (container.offset().left == currentElement.prev().offset().left) {
            currentElement = currentElement.prev().prev().length > 0 ? currentElement.prev().prev() : currentElement.prev();
        } else {
            currentElement = currentElement.prev();
        }
    }
    scrollToElement(currentElement);
};

$("#main").scroll(onScroll);
$("#next").click(next);
$("#previous").click(previous);

You would think that I can combine both solutions, which for some reason isn't really working at the moment, but ideally I would like to find a fairly simple/clean jQuery solution. If anyone has any idea, that would be much appreciated. Thanks!

Upvotes: 1

Views: 4140

Answers (1)

Sze-Hung Daniel Tsui
Sze-Hung Daniel Tsui

Reputation: 2332

scrollLeft() and scrollTop() work by orienting scroll to the number of pixels left or top. So if you host up your fiddle and go $(document).scrollLeft(500), you'll see movement left. Same for scrolling down with $(document).scrollTop().

So I would try something like this:

Give the prev and next buttons the same class, like #scrollButton, and keep track of where your user has scrolled in your JavaScript.

$('#scrollButton').click(function() {
//logic to find out which button you clicked, perhaps from an ID

//logic here to find out where the user is
   var target = //that location;

//scroll to that location +/- X pixels, depending on which button you clicked...then just use your reassigned target

   $("html, body").animate({
     scrollLeft: target
}, 500);
});

This will break if the user uses two kinds of scrolling, but if you start listening for scroll events, you'll be able to track both.

Your question is not clear on how you want to do scrolling. It doesn't look like you've given it a solid shot yet, but perhaps this can get you started. https://api.jquery.com/scroll/

You're basically looking for the events and doing the same thing. You're most of the way there!

Upvotes: 2

Related Questions