Search code examples
javascriptjqueryparallax

Translate JQuery Parallax to Pure JavaScript


I have a page that only uses this excellent parallax function and I don't want to load jQuery just for that.

Can you write this function in plain javascript and keep it small and readable? (Has to work in IE10+, modern browsers)

$(document).ready(function(){

    function draw() {
        requestAnimationFrame(draw);
        // Drawing code goes here
        scrollEvent();
    }
    draw();

});

function scrollEvent(){

    if(!is_touch_device()){
        viewportTop = $(window).scrollTop();
        windowHeight = $(window).height();
        viewportBottom = windowHeight+viewportTop;

        if($(window).width())

        $('[data-parallax="true"]').each(function(){
            distance = viewportTop * $(this).attr('data-speed');
            if($(this).attr('data-direction') === 'up'){ sym = '-'; } else { sym = ''; }
            $(this).css('transform','translate3d(0, ' + sym + distance +'px,0)');
        });

    }
}   

function is_touch_device() {
  return 'ontouchstart' in window // works on most browsers 
      || 'onmsgesturechange' in window; // works on ie10
}

Solution

  • You can do what you're asking here by looking at You Might Not Need jQuery.

    Your code, translated to vanilla javascript, should be something like this:

    document.addEventListener('DOMContentLoaded', function() {
      function draw() {
        requestAnimationFrame(draw);
        // Drawing code goes here
        scrollEvent();
      }
      draw();
    });
    
    function scrollEvent() {
      if (!is_touch_device()){
        var viewportTop = window.scrollY;
        var windowHeight = document.documentElement.clientHeight;
        var viewportBottom = windowHeight + viewportTop;
    
        if (document.documentElement.clientWidth) {
          var parallax = document.querySelectorAll('[data-parallax="true"]');
          for (var i = 0; i < parallax.length; i++) {
            var item = parallax[i];
            var distance = viewportTop * item.getAttribute('data-speed');
            var sym = item.getAttribute('data-direction') === 'up' ? '-' : '';
            item.style.transform = 'translate3d(0, ' + sym + distance +'px,0)';
          }    
        }
      }
    }
    
    function is_touch_device() {
      return 'ontouchstart' in window || 'onmsgesturechange' in window;
    }