Snap-Points.js – Add snap-to functionality to your page

If you want to add snap-to functionality to your web page, check out this ridiculously easy-to-use JavaScript library.

Just add it (and jQuery) to your page, then define which HTML elements you want to make the snap points. I love simple-to-use code, don’t you?

I’ll add onto it later as new ideas pop into my head. Right now, it’s using a timeout to account for the fact that there’s no scroll-end event in the DOM or jQuery. I’m not a huge fan of timeouts, but in this case it seems to work. I’d like something more elegant going forward.

Get the Code on GitHub

The Code

/*
  Snap-Points.js
  Copyright 2016 by Brian Rollins (me at brianrollins.com)
  Released under a Creative Commons, Attribution 4.0 International License.
  Requires JQuery (jquery.com)
  Just add the attribute data-snap="true" to the elements you want the browser to snap to.
  You can adjust the scroll speed (scrollSpeed) in your code or override it here.
  If you don't feel like coding it into the HTML, use the snapAll() function and
  pass a string (or array of strings) in for the element(s) you want affected.
  Ex: snapAll("p") will add the data-snap="true" attribute to all <p> tags.
  Ex: snapAll(["h1", "h2", "h3", "h4", "h5", "h6"]) gets all the various header tags.
*/

var scrollSpeed = 250; //Default scroll speed.
var scrollWait = 250; //Waiting time to make sure the user is done scrolling.
$(window).scroll(function() {
    clearTimeout($.data(this, 'scrollTimer'));
    $.data(this, 'scrollTimer', setTimeout(function() {
      var cutoff = $(window).scrollTop();
      $('[data-snap="true"]').each(function() {
          if ($(this).offset().top+10 > cutoff) {
              clearTimeout($.data(this, 'scrollTimer'));
              $('html, body').animate({
                scrollTop: $(this).offset().top
              }, scrollSpeed);
              return false; // stops the iteration after the first one on screen
          }
      });
    }, scrollWait));
});

var snapAll = function(el) {
  if (typeof el === "string") {
    $(el).attr('data-snap', 'true');
  } else if (Array.isArray(el)) {
    for (var i in el) {
      $(el[i]).attr('data-snap', 'true');
    }
  }
}

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.