This website uses cookies to personalise ads and to analyse traffic ok
web design

Page scroll to id with mousewheel and keyboard

Code sample which should scroll between page sections created with Page scroll to id plugin, using the mouse-wheel and keyboard arrows.

In order to scroll between page sections via mouse-wheel and/or keyboard you’d normally need custom javascript code made specifically for your site layout/markup but I’ve created a more generic script that works along Page scroll to id plugin. The script uses a special plugin class (_mPS2id-h) in order to work independently from most layouts. This class is related to plugin’s highlight feature, meaning that it should work in most cases.

The script should be placed after Page scroll to id plugin files and function call. If you’re using the WordPress version of the plugin, you should place it wherever your theme allows you to add custom javascript or directly in the footer.php template inside a script (<script>...</script>) tag after wp_footer();

The script

(function($){
  $(window).on("load",function(){

    if(!$(document).data("mPS2id")){
      console.log("Error: 'Page scroll to id' plugin not present or activated. Please run the code after plugin is loaded.");
      return;
    }

    $(document).data("mPS2idExtend",{
      selector:"._mPS2id-h",
      currentSelector:function(){
        return this.index($(".mPS2id-highlight-first").length ? $(".mPS2id-highlight-first") : $(".mPS2id-highlight"));
      },
      input:{y:null,x:null},
      i:null,
      time:null
    }).on("scrollSection",function(e,dlt,i){
      var d=$(this).data("mPS2idExtend"),
        sel=$(d.selector);
      if(!$("html,body").is(":animated")){
        if(!i) i=d.currentSelector.call(sel);
        if(!(i===0 && dlt>0) && !(i===sel.length-1 && dlt<0)) sel.eq(i-dlt).trigger("click.mPS2id");
      }
    }).on("mousewheel DOMMouseScroll",function(e){ //mousewheel
      if($($(this).data("mPS2idExtend").selector).length) e.preventDefault();
      $(this).trigger("scrollSection",((e.originalEvent.detail<0 || e.originalEvent.wheelDelta>0) ? 1 : -1));
    }).on("keydown",function(e){ //keyboard
      var code=e.keyCode ? e.keyCode : e.which,
        keys=$(this).data("mPS2id").layout==="horizontal" ? [37,39] : [38,40];
      if(code===keys[0] || code===keys[1]){
        if($($(this).data("mPS2idExtend").selector).length) e.preventDefault();
        $(this).trigger("scrollSection",(code===keys[0] ? 1 : -1));
      }
    });

  });
})(jQuery);

You can change the selector value to a more specific one if you need. This selector should be your “Page scroll to id” main navigation links, so instead of using simply selector:"._mPS2id-h" you could use for example selector:".menu-item ._mPS2id-h"

Important: Please note that you do not have to add the ._mPS2id-h to your elements. This class is added automatically by the plugin.

The script works best when your sections have the same height (or width for horizontal layouts) as the viewport, which is something that most page layouts with this kind of functionality have.

Extending the script with touch events (optional)

If you want to have the same functionality in touch-devices, you can extend the script above like this:

(function($){
  $(window).on("load",function(){

    if(!$(document).data("mPS2id")){
      console.log("Error: 'Page scroll to id' plugin not present or activated. Please run the code after plugin is loaded.");
      return;
    }

    $(document).data("mPS2idExtend",{
      selector:"._mPS2id-h",
      currentSelector:function(){
        return this.index($(".mPS2id-highlight-first").length ? $(".mPS2id-highlight-first") : $(".mPS2id-highlight"));
      },
      input:{y:null,x:null},
      i:null,
      time:null
    }).on("scrollSection",function(e,dlt,i){
      var d=$(this).data("mPS2idExtend"),
        sel=$(d.selector);
      if(!$("html,body").is(":animated")){
        if(!i) i=d.currentSelector.call(sel);
        if(!(i===0 && dlt>0) && !(i===sel.length-1 && dlt<0)) sel.eq(i-dlt).trigger("click.mPS2id");
      }
    }).on("mousewheel DOMMouseScroll",function(e){ //mousewheel
      if($($(this).data("mPS2idExtend").selector).length) e.preventDefault();
      $(this).trigger("scrollSection",((e.originalEvent.detail<0 || e.originalEvent.wheelDelta>0) ? 1 : -1));
    }).on("keydown",function(e){ //keyboard
      var code=e.keyCode ? e.keyCode : e.which,
        keys=$(this).data("mPS2id").layout==="horizontal" ? [37,39] : [38,40];
      if(code===keys[0] || code===keys[1]){
        if($($(this).data("mPS2idExtend").selector).length) e.preventDefault();
        $(this).trigger("scrollSection",(code===keys[0] ? 1 : -1));
      }
    }).on("pointerdown touchstart",function(e){ //touch (optional)
      var o=e.originalEvent,
        d=$(this).data("mPS2idExtend");
      if(o.pointerType==="touch" || e.type==="touchstart"){
        var y=o.screenY || o.changedTouches[0].screenY;
        d.input.y=y;
        if($(this).data("mPS2id").layout==="horizontal"){
          var x=o.screenX || o.changedTouches[0].screenX;
          d.input.x=x;
        }
        d.time=o.timeStamp;
        d.i=d.currentSelector.call($(d.selector));
      }
    }).on("touchmove",function(e){
      if($("html,body").is(":animated")) e.preventDefault();
    }).on("pointerup touchend",function(e){
      var o=e.originalEvent;
      if(o.pointerType==="touch" || e.type==="touchend"){
        var y=o.screenY || o.changedTouches[0].screenY,
          d=$(this).data("mPS2idExtend"),
          diff=d.input.y-y,
          time=o.timeStamp-d.time,
          i=d.currentSelector.call($(d.selector));
        if($(this).data("mPS2id").layout==="horizontal"){
          var x=o.screenX || o.changedTouches[0].screenX,
            diff=d.input.x-x;
        }
        if(Math.abs(diff)<2) return;
        var _switch=function(){
            return time<200 && i===d.i;
          };
        $(this).trigger("scrollSection",[(diff>0 && _switch() ? -1 : diff<0 && _switch() ? 1 : 0),(_switch() ? d.i : i)]);
      }
    });

  });
})(jQuery);

You should also add the following rule to your stylesheet:

body{ -ms-touch-action: none; touch-action: none; }

Please note that using such functionality with touch devices can be (very) tricky and might not work exactly the same across all devices, browsers etc. A good way would be to keep such behavior for mouse and keyboard and let touch devices scroll the page normally.

Auto-generating aside bullet indicators (optional)

If you see the script demo, in addition to the main navigation menu, you’ll notice few bullets at the right which act as links and visual indicators of the sections. You can create those by hand or you can use a small function like this:

$("body").append("<div id='sections-bullets' />").find($(document).data("mPS2idExtend").selector).each(function(){
  $("#sections-bullets").append("<a href='"+$(this).attr("href")+"' class='section-bullet' rel='m_PageScroll2id'></a>");
});

This should be placed within the window load function:

(function($){
  $(window).on("load",function(){

    //the script above goes here code...

    //still inside window load we add the function that auto-generates the bullets 
    $("body").append("<div id='sections-bullets' />").find($(document).data("mPS2idExtend").selector).each(function(){
      $("#sections-bullets").append("<a href='"+$(this).attr("href")+"' class='section-bullet' rel='m_PageScroll2id'></a>");
    });

  });
})(jQuery);

If you need help or the code customized for some specific layout let me know in the comments or contact me.

 


7 Comments

Post a comment
  1. Elzbieta
    Posted on March 22, 2017 at 22:16 Permalink

    Hello.
    This script is awesome. How can I add this to my joomla on gantry framework website?

    Reply
    • malihu
      Posted on March 22, 2017 at 22:38 Permalink

      This is a standard javascript/jQuery script, so you’d add it just like any other js script in your page or template.
      I’m not familiar with gantry and I rarely work with joomla so I can’t really say how/where to add it. You should ask this on joomla/gantry forums or perhaps Google “how to add js script in joomla” for a tutorial.

      Reply
    • Elzbieta
      Posted on March 22, 2017 at 23:00 Permalink

      I just send You an email. Will You help?

      Reply
      • malihu
        Posted on March 22, 2017 at 23:22 Permalink

        Check your email 🙂

        Reply
  2. z
    Posted on January 12, 2017 at 12:26 Permalink

    i was trying to do mousewheel scroll from one row to another in wordpress, im using page to id scroll plugin + i have put the Jquery script in the footer but i cannot seem to make it scroll to sections,
    can you post here the settings you have set up in the settings page on page scroll to ID and what class names should i put in the row class and row id, i have no section id and section class i can only work with row id and row class, hit me up on email (admin: edited email address)

    Reply
    • malihu
      Posted on January 12, 2017 at 15:48 Permalink

      No special settings needed. Send me your link so I can check it.

      Reply

Post a comment

Your e-mail is never published nor shared. Required fields are marked *

You may use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
You can write or copy/paste code directly in your comment using the <code> tag:
<code>code here...</code>
You may also use the data-lang attribute to determine the code language like so:
<code data-lang-html>, <code data-lang-css>, <code data-lang-js> and <code data-lang-php>

css.php