Alex Borsody
Alex Borsody

Reputation: 2070

Sticky div on scroll with plain javascript

I wrote this sticky div effect in Jquery but was wondering a way to do the same thing with vanilla javascript

.stick {
    position: fixed;
    top: 0;
}



$(document).ready(function () {  
  var top = $('#a8').offset().top;
  $(window).scroll(function (event) {
    var y = $(this).scrollTop();
    if (y >= top)
      $('#a8').addClass('stick');
    else
      $('#a8').removeClass('stick');

  });
});

Upvotes: 3

Views: 8588

Answers (3)

Miguel
Miguel

Reputation: 20633

In vanilla JavaScript:

function ready() {
    var box = document.getElementById('box'),
        top = box.offsetTop;

    function scroll(event) {
        var y = document['documentElement' || 'body'].scrollTop;

        if (y >= top) box.classList.add('stick');
        else box.classList.remove('stick');

    }

    window.addEventListener('scroll', scroll);
}

if (document.readyState == 'complete' || document.readyState == 'loaded') {
    ready();
} else {
    window.addEventListener('DOMContentLoaded', ready);
}

JSFiddle example:

http://jsfiddle.net/869fqgds/4/

Upvotes: 5

J0ANMM
J0ANMM

Reputation: 8551

Here is an adapted version from dfsq's answer, which is the most elegant and simple solution I've found so far:

    var myTop = document.getElementById('freeze').offsetTop;
    var origClass = freeze.className;
    window.onscroll = function() {
        var y = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
        if (y >= myTop) {
            freeze.className = origClass +' stick';
        }
        else {
            freeze.className = origClass;
        }
    };

// Note that I barely have javascript knowledge, so the modification, even if it works, might be far from optimal. I'm open to improvements.

Main differences are:

  • variable name changed to avoid ambiguity (see comments of that answer).
  • additional variable and modification inside if/else in order to allow using it with tags with an existing class already assigned.

The only issue remaining is that at the moment when the div is fixed, there is a kind of 'jump' in the flow. This is easily seen in the original jsfiddle if adding any text (for instance <p>See how I jump!</p>) a few lines below the div that is sticked.

Upvotes: 0

dfsq
dfsq

Reputation: 193301

Sure you can do the same in pure JS. Here is simple example:

var top = document.getElementById('a8').offsetTop;

window.onscroll = function() {
    var y = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
    if (y >= top) {
        a8.className = 'stick';
    }
    else {
        a8.className = '';
    }
};

Demo: http://jsfiddle.net/hd3uyf68/1/

Note, that in this simple example I don't actually implement addClass/removeClass functionality. If you need it it's quite easy to add.

Upvotes: 5

Related Questions