0

How can I create two buttons ("next" and "prev") that will scroll the browser to the article's title?

<div id="cycle-posts">
    <a id="next" href="#next"></a>
    <a id="prev" href="#prev"></a>
</div>

<article>My first post</article>
<article>My second post</article>
<article>My third post</article>
<article>My fourth post</article>

If it's relevant: after the first few, my articles are loaded in using "infinite scroll".

This is what I got so far, but it's not even close:

$('#cycle-posts a').bind('click', function (e) {
    $articles = $('article');
    e.preventDefault();
    var totalArticles = $articles.length;


    if ($(this).attr("id") == "next") {
        new_index = ++current_index;
    } else if ($(this).attr("id") == "prev") {
        new_index = --current_index;
    }

    if (new_index > totalArticles) {
        new_index = 0;
    }   

    $articles.removeClass('current').eq(new_index).addClass('current');

    console.log(new_index+' / '+totalArticles);

    // now scroll offset, find offset based on .current?

});
thv20
  • 986
  • 4
  • 13
  • 26

2 Answers2

1

On the handler we remove the current class to the element that it actually has it and then we select the next (or previous) element and we add the current class to it (only if it's not the first or last element).

Then we scroll to that element, animating scrollTop, as described here.

(function() {
    var scrollTo = function(element) {
        $('html, body').animate({
            scrollTop: element.offset().top
        }, 500);
    }
    $('#next').click(function(event) {
        event.preventDefault();
        var $current = $('#container > .current');
        if ($current.index() != $('#container > div').length - 1) {
            $current.removeClass('current').next().addClass('current');
            scrollTo($current.next());
        }
    });
    $('#prev').click(function(event) {
        event.preventDefault();
        var $current = $('#container > .current');
        if (!$current.index() == 0) {
            $current.removeClass('current').prev().addClass('current');
            scrollTo($current.prev());
        }
    });
})();

You have a fiddle here

Community
  • 1
  • 1
Alessandro Vendruscolo
  • 14,493
  • 4
  • 32
  • 41
0

Instead of trying to calculate the current index on every single click, I find it's much better to use a function to produce both the forward and back click handlers that also stores the index as a local. This way both can reference the index and it doesn't have to be calculated on the fly.

Try the following

(function() { 
  var index = 0;
  $('article:first').addClass('current');
  var moveOne = function (forward) {
    var articles = $('article');
    articles.eq(index).removeClass('current');
    if (forward) {
      index++;
      if (index === articles.length) {
        index = 0;
      }
    } else { 
      index--;
      if (index < 0) {
        index = articles.length - 1;
      }
    }
    articles.eq(index).addClass('current');
  }

  $('#next').click(function () { moveOne(true); });
  $('#prev').click(function () { moveOne(false); });

})();

Fiddle: http://jsfiddle.net/5f74F/

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454