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.

Script for WordPress

“Page scroll to id” WordPress plugin version 1.6.7 or greater must be installed and activated on your site.

After you create your page(s) target sections, edit your theme’s or child-theme’s functions.php and paste the following code

/* 
---------------------------------------- 
"Page scroll to id" with mousewheel and keyboard custom script
The following requires "Page scroll to id" WordPress plugin version 1.6.7 or greater 
---------------------------------------- 
*/

//----- SETUP -----

//set the options for the mousewheel scrolling 

function ps2id_mousewheel_options($opt){
  $opts = array(
        //set the ids of pages or posts that you want the mousewheel functionality to be enabled 
        //and set the target sections URLs for each of your sections of each page
        'ps2id_mousewheel_pages' => array( 
            //page with id 1 and its target sections URLs
            '1' => array(
                //page mousewheel sections URLs (e.g. #section-1 or http://site.com/#section-1 or /page/#section-1)
                '#section-1', 
                '#section-2', 
                '#section-3', 
                '#section-4', 
                '#section-5', 
            ),
            //page with id 2 and its target sections URLs
            '2' => array(
                //page mousewheel sections URLs
                '#section-1', 
                '#section-2', 
            ),
        ),
        //set the default target sections URLs
        'ps2id_mousewheel_default_sections' => array( 
            '#section-1',
            '#section-2', 
        ),
        //Special options for the mouse-wheel smooth scrolling (these overwrite the ones in plugin settings)
        //Scroll type/easing
        'ps2id_mousewheel_scroll_easing' => "easeOutQuint",
        //Scroll duration (in milliseconds)
        'ps2id_mousewheel_scroll_duration' => 1000,
        //Keep the current element highlighted until the next one comes into view (this is needed if the page has non-adjacent sections, i.e. when not all sections are next to one another)
        'ps2id_mousewheel_keep_highlight_until_next' => true,
        //Allow only one highlighted element at a time (should be disabled when $ps2id_mousewheel_keep_highlight_until_next is set to true)
        'ps2id_mousewheel_force_single_highlight' => false,
        //Append the clicked link’s hash value (e.g. #id) to browser’s URL/address bar (this should normally be disabled for better UX)
        'ps2id_mousewheel_append_hash' => false
  );
  $r = (isset($opt) && !empty($opt)) ? $opts[$opt] : $opts;
  return $r;
}

function ps2id_mw_condition($pages_arr){
  //set the condition for the mousewheel functionality 
  //add the WordPress conditional tags you want (https://codex.wordpress.org/Conditional_Tags)
  return is_single( $pages_arr ) || is_page( $pages_arr )
         //|| is_category() //example: uncomment to enable for categories (with the default target sections URLs set in ps2id_mousewheel_default_sections option)
         //|| is_home() //example: uncomment to enable for homepage (with the default target sections URLs set in ps2id_mousewheel_default_sections option)
    ;
}
  
//----- HTML -----

add_action('wp_footer', 'ps2id_mw_html');

function ps2id_mw_html(){
?>
    <?php if(class_exists('malihuPageScroll2id')) : ?>
        <?php
        $pages_arr = ps2id_mw_get_pages();
        $page_id = get_queried_object_id();
        $sections_arr = is_singular() && in_array($page_id, $pages_arr) ? ps2id_mousewheel_options('ps2id_mousewheel_pages')[$page_id] : ps2id_mousewheel_options('ps2id_mousewheel_default_sections');
        ?>
        <?php if(ps2id_mw_condition($pages_arr)) : ?>
            <?php if(!is_null($sections_arr)) : ?>
                <div id="ps2id-mw-sections-bullets">
                <?php 
                foreach($sections_arr as $section){
                    ?>
                    <a href="<?php echo $section; ?>" class="ps2id-mw-section-bullet"></a>
                    <?php
                }
                ?>
                </div>
            <?php endif; ?>
            <style>
                body{ -ms-touch-action: none; touch-action: none; } /* optional for touch/pointer events */

                /* aside bullets section */
                    #ps2id-mw-sections-bullets{
                    position: fixed;
                    right: 2em;
                    height: auto;
                    top: 50%;
                    transform: translateY(-50%);
                    z-index: 2;
                }

                /* aside bullets */
                .ps2id-mw-section-bullet{
                    display: block;
                    position: relative;
                    width: 1.5em;
                    height: 1.5em;
                    border-radius: 100%;
                    margin: 0 auto;
                    opacity: .6;
                }

                .ps2id-mw-section-bullet::before{
                    content: "";
                    display: block;
                    position: absolute;
                    top: 0;
                    right: 0;
                    bottom: 0;
                    left: 0;
                    margin: .4em;
                    border-radius: 100%;
                    border: 1px solid;
                }

                .ps2id-mw-section-bullet:hover, 
                .ps2id-mw-section-bullet.mPS2id-highlight:not(.mPS2id-highlight-first):not(.mPS2id-highlight-last), 
                .ps2id-mw-section-bullet.mPS2id-highlight-first{
                    opacity: 1;
                }
            </style>
        <?php endif; ?>
    <?php endif; ?>
<?php
};

//----- Javascript -----

add_action( 'wp_enqueue_scripts', 'ps2id_special_params', 1 );

function ps2id_special_params(){
    if(class_exists('malihuPageScroll2id')){
        $pages_arr = ps2id_mw_get_pages();
        if(ps2id_mw_condition($pages_arr)) : 
            wp_register_script( 'page-scroll-to-id-mw-js-init', '', array(), '0.0.1', false );
            wp_enqueue_script( 'page-scroll-to-id-mw-js-init' );
            wp_add_inline_script( 'page-scroll-to-id-mw-js-init', 'window.ps2id_special_params={
                highlightSelector: ".ps2id-mw-section-bullet", //mouse-wheel script highlight selector
                scrollEasing: "'.ps2id_mousewheel_options('ps2id_mousewheel_scroll_easing').'", //set a more fitting scroll easing for mousewheel smooth scrolling
                scrollSpeed: '.ps2id_mousewheel_options('ps2id_mousewheel_scroll_duration').', //set a more fitting scrolling duration for mousewheel smooth scrolling
                keepHighlightUntilNext: "'.json_encode(ps2id_mousewheel_options('ps2id_mousewheel_keep_highlight_until_next')).'", //this is needed if the page has non-adjacent sections (i.e. when not all sections are next to one another)
                forceSingleHighlight: "'.json_encode(ps2id_mousewheel_options('ps2id_mousewheel_force_single_highlight')).'", //should be disabled when keepHighlightUntilNext is enabled
                appendHash: "'.json_encode(ps2id_mousewheel_options('ps2id_mousewheel_append_hash')).'" //should normally be disabled for better UX
            };');
        endif;
    }
}

add_action( 'wp_enqueue_scripts', 'ps2id_mw_js', 99 );

function ps2id_mw_js(){
    if(class_exists('malihuPageScroll2id')){
        $pages_arr = ps2id_mw_get_pages();
        if(ps2id_mw_condition($pages_arr)) : 
            if(PS2ID_MINIFIED_JS){
                $deps = array('jquery','page-scroll-to-id-mw-js-init','page-scroll-to-id-plugin-script');
            }else{
                $deps = array('jquery','page-scroll-to-id-mw-js-init','page-scroll-to-id-plugin-init-script','page-scroll-to-id-plugin-script');
            }
            wp_register_script( 'page-scroll-to-id-mw-js', '', $deps, '0.0.1', true );
            wp_enqueue_script( 'page-scroll-to-id-mw-js' );
            wp_add_inline_script( 'page-scroll-to-id-mw-js', '(function($){
                $(window).on("load",function(){
            
                    var doc=$(document),
                        mPS2idData=doc.data("mPS2id"),
                        mPS2idExt;
                
                    if(!mPS2idData){
                        console.log("Error: \'Page scroll to id\' plugin not present or activated. Please run the code after plugin is loaded.");
                        return;
                    }

                    if(!$("._mPS2id-t").length) return;
                
                    doc.data("mPS2idExtend",{
                        selector: "._mPS2id-h",
                        currentSelector: function(){
                            return this.index($(".mPS2id-highlight-first").length ? $(".mPS2id-highlight-first") : $(".mPS2id-highlight").length ? $(".mPS2id-highlight") : $(".mPS2id-wheel-init"));
                        },
                        target: function(){
                            var curr=$(".mPS2id-target-first").length ? $(".mPS2id-target-first") : $(".mPS2id-target").length ? $(".mPS2id-target") : $(".mPS2id-clicked").length ? $("#"+$(".mPS2id-clicked").attr("href").split("#")[1]) : false;
                            if(!curr.length){
                                //if no current target exists, get the next and previous closest sections
                                var max=999999999,
                                    min=-999999999;
                                $("._mPS2id-t").each(function(){
                                    var pos=mPS2idData.layout==="horizontal" ? this.getBoundingClientRect().left : this.getBoundingClientRect().top;
                                    if(pos < 0 && pos > min){
                                        min=pos; 
                                        curr=$("._mPS2id-t[data-psid-wheel-section=\'"+($(this).data("psid-wheel-section")+1)+"\']");
                                    }else if(pos > 0 && pos < max){
                                        max=pos; 
                                        curr=$("._mPS2id-t[data-psid-wheel-section=\'"+($(this).data("psid-wheel-section")-1)+"\']");
                                    }
                                });
                                $("._mPS2id-h[data-psid-wheel-link=\'"+curr.data("psid-wheel-section")+"\']").addClass("mPS2id-wheel-init");
                            }
                            return [
                                $("._mPS2id-t[data-psid-wheel-section=\'"+(curr.data("psid-wheel-section")-1)+"\']"), //previous target
                                curr, //current target
                                $("._mPS2id-t[data-psid-wheel-section=\'"+(curr.data("psid-wheel-section")+1)+"\']"), //next target
                            ];
                        },
                        needScroll: function(dir){
                            if($("html,body").is(":animated")) return;
                            if(dir > 0){ //scrolled fw
                                var el=mPS2idExt.target.call()[2][0]; //next adjacent target
                                if(mPS2idData.layout==="horizontal"){
                                    return el ? el.getBoundingClientRect().left > (window.innerWidth || document.documentElement.clientWidth) : true; //next target is after viewport
                                }else{
                                    return el ? el.getBoundingClientRect().top > (window.innerHeight || document.documentElement.clientHeight) : true; //next target is below viewport
                                }
                            }else if(dir < 0){ //scrolled bw
                                var el=mPS2idExt.target.call()[0][0]; //previous adjacent target
                                if(mPS2idData.layout==="horizontal"){
                                    return el ? el.getBoundingClientRect().right < 0 : true; //previous target is before viewport
                                }else{
                                    return el ? el.getBoundingClientRect().bottom < 0 : true; //previous target is above viewport
                                }
                            }
                        },
                        input:{
                            y: null,
                            x: null
                        },
                        i: null,
                        time: null,
                        debounce:{
                            prevTime: 0
                        },
                        support:{
                            wheel: false
                        }
                    }).on("ps2id-scrollSection",function(e,dlt,i){
                        var sel=$(mPS2idExt.selector);
                        if(!$("html,body").is(":animated")){
                            if(!i) i=mPS2idExt.currentSelector.call(sel);
                            if(!(i===0 && dlt>0) && !(i===sel.length-1 && dlt<0)) sel.eq(i-dlt).trigger("click.mPS2id");
                        }
                    }).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(!mPS2idExt.needScroll((code > 38 ? 1 : -1))){ //check if normal scrolling is needed to reach adjacent targets
                                if($(mPS2idExt.selector).length) e.preventDefault();
                                $(this).trigger("ps2id-scrollSection",(code===keys[0] ? 1 : -1));
                            }
                        }
                    })
                    //touch events (remove the following code if you don\'t want to apply the touch functionality)
                    .on("pointerdown touchstart",function(e){ //touch (optional)
                        var o=e.originalEvent;
                        if(o.pointerType==="touch" || e.type==="touchstart"){
                            var y=o.screenY || o.changedTouches[0].screenY;
                            mPS2idExt.input.y=y;
                            if($(this).data("mPS2id").layout==="horizontal"){
                                var x=o.screenX || o.changedTouches[0].screenX;
                                mPS2idExt.input.x=x;
                            }
                            mPS2idExt.time=o.timeStamp;
                            mPS2idExt.i=mPS2idExt.currentSelector.call($(mPS2idExt.selector));
                        }
                    }).on("pointerup touchend",function(e){
                        var o=e.originalEvent;
                        if(o.pointerType==="touch" || e.type==="touchend"){
                            var y=o.screenY || o.changedTouches[0].screenY,
                                diff=mPS2idExt.input.y-y,
                                time=o.timeStamp-mPS2idExt.time,
                                i=mPS2idExt.currentSelector.call($(mPS2idExt.selector));
                            if($(this).data("mPS2id").layout==="horizontal"){
                                var x=o.screenX || o.changedTouches[0].screenX,
                                    diff=mPS2idExt.input.x-x;
                            }
                            if(Math.abs(diff)<2) return;
                            var _switch=function(){
                                return time<200 && i===mPS2idExt.i;
                            };
                            var dir=diff > 0 ? 1 : -1;
                            if(time < 500 && Math.abs(diff) > 50) $(this).trigger("ps2id-scrollSection",[(diff>0 && _switch() ? -1 : diff<0 && _switch() ? 1 : 0),(_switch() ? mPS2idExt.i : i)]);
                        }
                    })
                    // -----
                    .on("ps2id-wheel-init",function(){
                        //script initialization
                        mPS2idExt=$(this).data("mPS2idExtend");
                        $("._mPS2id-t").each(function(index){
                            $(this).attr("data-psid-wheel-section",index);
                        });
                        $("._mPS2id-h").each(function(index){
                            $(this).attr("data-psid-wheel-link",index);
                        });
                        //vanilla js mousewheel event (https://github.com/jquery/jquery/issues/2871)
                        document.addEventListener(\'wheel\', wheel, {passive: false}, false);
                        document.addEventListener(\'mousewheel\', wheel, {passive: false}, false);
                        document.addEventListener(\'DOMMouseScroll\', wheel, {passive: false}, false);
                        function wheel(e){
                            if(e.type == "wheel"){
                                mPS2idExt.support.wheel = true;
                            }else if(mPS2idExt.support.wheel){
                                return;
                            }
                            if(!mPS2idExt.needScroll((mPS2idData.layout==="horizontal" ? e.deltaX : e.deltaY))){ //check if normal scrolling is needed to reach adjacent targets
                                if($(mPS2idExt.selector).length) e.preventDefault();
                                if((mPS2idData.layout==="vertical" && e.deltaY==-0) || (mPS2idData.layout==="horizontal" && e.deltaX==-0)) return;
                                //trackpad fix (https://stackoverflow.com/a/26514147)
                                var curTime=new Date().getTime();
                                if(typeof mPS2idExt.debounce.prevTime !== "undefined"){
                                    if((curTime-mPS2idExt.debounce.prevTime)>200) doc.trigger("ps2id-scrollSection",((e.detail<0 || e.wheelDelta>0 || e.deltaY<0 || e.deltaX<0) ? 1 : -1));
                                }
                                mPS2idExt.debounce.prevTime=curTime;
                            }
                        };
                    }).trigger("ps2id-wheel-init");
                });

            })(jQuery);');
        endif;
    }
}

function ps2id_mw_get_pages(){
    //get pages ids as array
    $pages_arr = array();
    foreach(ps2id_mousewheel_options('ps2id_mousewheel_pages') as $k => $v) {
        $pages_arr[] = $k;
    }
    return $pages_arr;
}
/* ---------------------------------------- */

Edit ps2id_mousewheel_options function in the code above to setup the pages or posts that you want the mousewheel functionality to be enabled and the target sections URLs for each page. For example, the code below will enable the mousewheel functionality on the posts or pages with id 25, 148 and 3. For each post/page we add its sections URLs:

'ps2id_mousewheel_pages' => array( 
    '25' => array(
        //page mousewheel sections URLs (e.g. #section-1 or http://site.com/#section-1 or /page/#section-1)
        '#section-1', 
        '#section-2', 
        '#section-3', 
        '#section-4', 
        '#section-5', 
    ),
    '148' => array(
        //page mousewheel sections URLs
        '#section-1', 
        '#section-2', 
        '#section-3', 
        '#section-4', 
    ),
    '3' => array(
        //page mousewheel sections URLs
        '#section-1',
        '#section-2', 
        '#section-3', 
        '#section-4', 
        '#section-5', 
        '#section-6', 
        '#section-7', 
        '#section-8', 
    ),
),

Add as many pages as you want 😉

Add the default target sections URLs for pages like homepage, category, archive etc.:

'ps2id_mousewheel_default_sections' => array( 
    '#section-1',
    '#section-2', 
    '#section-3', 
)

Optionally set the condition for the mousewheel functionality in ps2id_mw_condition function:

return is_single( $pages_arr ) || is_page( $pages_arr )
       //|| is_category() //example: uncomment to enable for categories (with the default target sections URLs set in ps2id_mousewheel_default_sections option)
       //|| is_home() //example: uncomment to enable for homepage (with the default target sections URLs set in ps2id_mousewheel_default_sections option)
       ;

You may also want to set few specific plugin option for these pages. These options will overwrite the ones in plugin settings:

//Scroll type/easing
'ps2id_mousewheel_scroll_easing' => "easeOutQuint",
//Scroll duration (in milliseconds)
'ps2id_mousewheel_scroll_duration' => 1000,
//Keep the current element highlighted until the next one comes into view (this is needed if the page has non-adjacent sections, i.e. when not all sections are next to one another)
'ps2id_mousewheel_keep_highlight_until_next' =>  true,
//Allow only one highlighted element at a time (should be disabled when $ps2id_mousewheel_keep_highlight_until_next is set to true)
'ps2id_mousewheel_force_single_highlight' => false,
//Append the clicked link’s hash value (e.g. #id) to browser’s URL/address bar (this should normally be disabled for better UX)
'ps2id_mousewheel_append_hash' => false

How to disable the script on mobile and touch devices?

To disable the script on mobile/touch devices, remove the part from the comment:

//touch events (remove the following code if you don't want to apply the touch functionality)

to the next:

// -----

Also remove the CSS part:

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

Version 2.0 script

You need 3 steps in order to make this work: Add the HTML (1), set few plugin options to specific values (2) and add the custom javascript for the mousewheel (3).

1.The HTML

Add the HTML and CSS for the bullet indicators, changing the links href/URL to your sections ids

<div id="sections-bullets">
  <a href="#section-1" class="section-bullet"></a>
  <a href="#section-2" class="section-bullet"></a>
  <a href="#section-3" class="section-bullet"></a>
  <a href="#section-4" class="section-bullet"></a>
  <a href="#section-5" class="section-bullet"></a>
  <a href="#section-6" class="section-bullet"></a>
  <a href="#section-7" class="section-bullet"></a>
</div>
body{ -ms-touch-action: none; touch-action: none; } /* optional for touch/pointer events */

/* aside indicators */
#sections-bullets{
  position: fixed;
  right: 2em;
  height: auto;
  top: 50%;
  transform: translateY(-50%);
}

.section-bullet{
  display: block;
  position: relative;
  width: 9px;
  height: 9px;
  border-radius: 100%;
  background: #fff;
  margin: 12px auto;
  opacity: .6;
}

.section-bullet:hover, .section-bullet.mPS2id-highlight{
  opacity: 1;
  background: #e6842c;
}

Change the CSS styling to your liking. To disable the script on mobile/touch devices, remove the touch-action css rule in the CSS above.

2.Plugin function call and options

You need to set a few specific options in order for the mousewheel script to work properly. You mainly need to set the highlightSelector option to "#sections-bullets a" and enable keepHighlightUntilNext. You should also set the scroll easing option parameter to a value like "easeOutQuint", "easeOutQuart" etc.:

<script>
    (function($){
        $(window).on("load",function(){
            $("a[rel='m_PageScroll2id']").mPageScroll2id({
                highlightSelector: "#sections-bullets a",
                keepHighlightUntilNext: true,
                scrollEasing:"easeOutQuint",
                scrollSpeed:1200
            });
        });
    })(jQuery);
</script>

3.The script

The following script should be placed after Page scroll to id plugin files and function call.

<script>
    (function($){
      $(window).on("load",function(){
  
        var doc=$(document),
            mPS2idData=doc.data("mPS2id"),
            mPS2idExt;
  
        if(!mPS2idData){
          console.log("Error: 'Page scroll to id' plugin not present or activated. Please run the code after plugin is loaded.");
          return;
        }

        if(!$("._mPS2id-t").length) return;
  
        doc.data("mPS2idExtend",{
          selector: "._mPS2id-h",
          currentSelector: function(){
            return this.index($(".mPS2id-highlight-first").length ? $(".mPS2id-highlight-first") : $(".mPS2id-highlight").length ? $(".mPS2id-highlight") : $(".mPS2id-wheel-init"));
          },
          target: function(){
            var curr=$(".mPS2id-target-first").length ? $(".mPS2id-target-first") : $(".mPS2id-target").length ? $(".mPS2id-target") : $(".mPS2id-clicked").length ? $("#"+$(".mPS2id-clicked").attr("href").split("#")[1]) : false;
            if(!curr.length){
              //if no current target exists, get the next and previous closest sections
              var max=999999999,
                  min=-999999999;
              $("._mPS2id-t").each(function(){
                var pos=mPS2idData.layout==="horizontal" ? this.getBoundingClientRect().left : this.getBoundingClientRect().top;
                if(pos < 0 && pos > min){
                  min=pos; 
                  curr=$("._mPS2id-t[data-psid-wheel-section='"+($(this).data("psid-wheel-section")+1)+"']");
                }else if(pos > 0 && pos < max){
                  max=pos; 
                  curr=$("._mPS2id-t[data-psid-wheel-section='"+($(this).data("psid-wheel-section")-1)+"']");
                }
              });
              $("._mPS2id-h[data-psid-wheel-link='"+curr.data("psid-wheel-section")+"']").addClass("mPS2id-wheel-init");
            }
            return [
              $("._mPS2id-t[data-psid-wheel-section='"+(curr.data("psid-wheel-section")-1)+"']"), //previous target
              curr, //current target
              $("._mPS2id-t[data-psid-wheel-section='"+(curr.data("psid-wheel-section")+1)+"']"), //next target
            ];
          },
          needScroll: function(dir){
            if($("html,body").is(":animated")) return;
            if(dir > 0){ //scrolled fw
              var el=mPS2idExt.target.call()[2][0]; //next adjacent target
              if(mPS2idData.layout==="horizontal"){
                return el ? el.getBoundingClientRect().left > (window.innerWidth || document.documentElement.clientWidth) : true; //next target is after viewport
              }else{
                return el ? el.getBoundingClientRect().top > (window.innerHeight || document.documentElement.clientHeight) : true; //next target is below viewport
              }
            }else if(dir < 0){ //scrolled bw
              var el=mPS2idExt.target.call()[0][0]; //previous adjacent target
              if(mPS2idData.layout==="horizontal"){
                return el ? el.getBoundingClientRect().right < 0 : true; //previous target is before viewport
              }else{
                return el ? el.getBoundingClientRect().bottom < 0 : true; //previous target is above viewport
              }
            }
          },
          input:{
            y: null,
            x: null
          },
          i: null,
          time: null,
          debounce:{
            prevTime: 0
          },
          support:{
            wheel: false
          }
        }).on("ps2id-scrollSection",function(e,dlt,i){
          var sel=$(mPS2idExt.selector);
          if(!$("html,body").is(":animated")){
            if(!i) i=mPS2idExt.currentSelector.call(sel);
            if(!(i===0 && dlt>0) && !(i===sel.length-1 && dlt<0)) sel.eq(i-dlt).trigger("click.mPS2id");
          }
        }).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(!mPS2idExt.needScroll((code > 38 ? 1 : -1))){ //check if normal scrolling is needed to reach adjacent targets
              if($(mPS2idExt.selector).length) e.preventDefault();
              $(this).trigger("ps2id-scrollSection",(code===keys[0] ? 1 : -1));
            }
          }
        })
        //touch events (remove the following code if you don't want to apply the touch functionality)
        .on("pointerdown touchstart",function(e){ //touch (optional)
          var o=e.originalEvent;
          if(o.pointerType==="touch" || e.type==="touchstart"){
            var y=o.screenY || o.changedTouches[0].screenY;
            mPS2idExt.input.y=y;
            if($(this).data("mPS2id").layout==="horizontal"){
              var x=o.screenX || o.changedTouches[0].screenX;
              mPS2idExt.input.x=x;
            }
            mPS2idExt.time=o.timeStamp;
            mPS2idExt.i=mPS2idExt.currentSelector.call($(mPS2idExt.selector));
          }
        }).on("pointerup touchend",function(e){
          var o=e.originalEvent;
          if(o.pointerType==="touch" || e.type==="touchend"){
            var y=o.screenY || o.changedTouches[0].screenY,
                diff=mPS2idExt.input.y-y,
                time=o.timeStamp-mPS2idExt.time,
                i=mPS2idExt.currentSelector.call($(mPS2idExt.selector));
            if($(this).data("mPS2id").layout==="horizontal"){
              var x=o.screenX || o.changedTouches[0].screenX,
                  diff=mPS2idExt.input.x-x;
            }
            if(Math.abs(diff)<2) return;
            var _switch=function(){
              return time<200 && i===mPS2idExt.i;
            };
            var dir=diff > 0 ? 1 : -1;
            if(time < 500 && Math.abs(diff) > 50) $(this).trigger("ps2id-scrollSection",[(diff>0 && _switch() ? -1 : diff<0 && _switch() ? 1 : 0),(_switch() ? mPS2idExt.i : i)]);
          }
        })
        // -----
        .on("ps2id-wheel-init",function(){
          //script initialization
          mPS2idExt=$(this).data("mPS2idExtend");
          $("._mPS2id-t").each(function(index){
            $(this).attr("data-psid-wheel-section",index);
          });
          $("._mPS2id-h").each(function(index){
            $(this).attr("data-psid-wheel-link",index);
          });
          //vanilla js mousewheel event (https://github.com/jquery/jquery/issues/2871)
          document.addEventListener('wheel', wheel, {passive: false}, false);
          document.addEventListener('mousewheel', wheel, {passive: false}, false);
          document.addEventListener('DOMMouseScroll', wheel, {passive: false}, false);
          function wheel(e){
            if(e.type == "wheel"){
              mPS2idExt.support.wheel = true;
            }else if(mPS2idExt.support.wheel){
              return;
            }
            if(!mPS2idExt.needScroll((mPS2idData.layout==="horizontal" ? e.deltaX : e.deltaY))){ //check if normal scrolling is needed to reach adjacent targets
              if($(mPS2idExt.selector).length) e.preventDefault();
              if((mPS2idData.layout==="vertical" && e.deltaY==-0) || (mPS2idData.layout==="horizontal" && e.deltaX==-0)) return;
              //trackpad fix (https://stackoverflow.com/a/26514147)
              var curTime=new Date().getTime();
              if(typeof mPS2idExt.debounce.prevTime !== "undefined"){
                if((curTime-mPS2idExt.debounce.prevTime)>200) doc.trigger("ps2id-scrollSection",((e.detail<0 || e.wheelDelta>0 || e.deltaY<0 || e.deltaX<0) ? 1 : -1));
              }
              mPS2idExt.debounce.prevTime=curTime;
            }
          };
        }).trigger("ps2id-wheel-init");
      });
      
    })(jQuery);
</script>

To disable the script on mobile/touch devices, remove the part from the comment:

//touch events (remove the following code if you don't want to apply the touch functionality)

to the next:

// -----

Version 1.0 script

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("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));
      }
    });

    //mousewheel (https://github.com/jquery/jquery/issues/2871)
    var supportsWheel=false;
    function wheel(e){
      if (e.type == "wheel") supportsWheel = true;
        else if (supportsWheel) return;
      if($($(document).data("mPS2idExtend").selector).length) e.preventDefault();
      $(document).trigger("scrollSection",((e.detail<0 || e.wheelDelta>0 || e.deltaY<0 || e.deltaX<0) ? 1 : -1));
    };
    document.addEventListener('wheel', wheel, {passive: false}, false);
    document.addEventListener('mousewheel', wheel, {passive: false}, false);
    document.addEventListener('DOMMouseScroll', wheel, {passive: false}, false);

  });
})(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 class to your elements. It is added automatically by the plugin. Also note that if you have additional links handled by the plugin (e.g. in addition to your menu links, you have back-to-top, next/previous section links etc. in your page), you might need to set your main (e.g. menu) links selector as the “Highlight selector(s)” in plugin settings (e.g. set the option value to .menu-item a).

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("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)]);
      }
    });

    //mousewheel (https://github.com/jquery/jquery/issues/2871)
    var supportsWheel=false;
    function wheel(e){
      if (e.type == "wheel") supportsWheel = true;
        else if (supportsWheel) return;
      if($($(document).data("mPS2idExtend").selector).length) e.preventDefault();
      $(document).trigger("scrollSection",((e.detail<0 || e.wheelDelta>0 || e.deltaY<0 || e.deltaX<0) ? 1 : -1));
    };
    document.addEventListener('wheel', wheel, {passive: false}, false);
    document.addEventListener('mousewheel', wheel, {passive: false}, false);
    document.addEventListener('DOMMouseScroll', wheel, {passive: false}, false);

  });
})(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...

    //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.

 


174 Comments

Post a comment

Comments pages: 1 2

  1. warsi
    Posted on September 18, 2018 at 10:57 Permalink

    hi malihu! first of all thanks for this wonderful code, i am using this for my website. i am getting an issue, while scrolling through touchpad, sometimes website previous section comes back instead of moving to the next section… can you plz help me out ?

    Reply
  2. Nick
    Posted on September 16, 2018 at 07:37 Permalink

    I forgot to mention that I am using oceanwp theme

    Reply
  3. Nick
    Posted on September 16, 2018 at 07:37 Permalink

    Hi,

    Firstly, thank you for the detailed article and for helping the commentors.

    Secondly, can you explain in layman’s terms how to add the script? I’m more of a designer who uses pagebuilders (elementor) alongwith plugins to create sites.

    I don’t know how to add custom javascript to the theme, can I use a plugin like custom css/js/html to add the script?

    Any and all help is appreciated. Thank you in advance and have a great day!

    yours sincerely,

    Nick

    Reply
  4. UMSI
    Posted on July 30, 2018 at 20:04 Permalink

    It’s exactly what I was looking for, thank you very much!
    Really appreciated, just to let you know.

    Reply
  5. Ian Mitchell
    Posted on July 14, 2018 at 11:38 Permalink

    Hi there. I’ve gotten your script to work and I love it, so first off – thank you!
    However I’ve put it into my site that already has off-canvas divs that transform: translateX to the left and right.

    And every time I active a shift to the left or right, your script sends me back to the top.
    Any idea on what’s causing this?

    Thanks so much.

    (scroll down to the second or third div and then hit “Read now”

    Reply
    • Ian
      Posted on July 14, 2018 at 11:58 Permalink

      Ah, I figured it out. My links were blank and there for had just “#” in them. Causing the script to go back to the very top. Changing them to the current article number made them slide over with no problem.
      http://stillwrappd.com/test/index.html

      Reply
      • Ian
        Posted on July 14, 2018 at 12:04 Permalink

        Sorry I guess I can’t delete my first question, but my other question is: is there a way to temporarily disable the scrolling script?
        For instance once the off canvas div slides in, i’d like to disable the script until the off-canvas div slides back off screen and you are back at the home page.

        Thanks so much!

        http://stillwrappd.com/test/index.html

        Reply
        • malihu
          Posted on July 15, 2018 at 01:19 Permalink

          You could try adding the following 2 lines of code in the custom script:

          //... }).on("mousewheel DOMMouseScroll",function(e){ //mousewheel if($("#container").hasClass("slide-left")) return; //rest of the code... }).on("keydown",function(e){ //keyboard if($("#container").hasClass("slide-left")) return; //rest of the code... //...

          You’re just adding:

          if($("#container").hasClass("slide-left")) return;

          as the first line of code inside the mousewheel and keydown events. The code disables scrolling if the right panel is active.

          Hope this helps

          Reply
          • Ian
            Posted on July 15, 2018 at 05:03 Permalink

            You are amazing. Thank you a thousand times over!
            Worked like a charm!

  6. Daniel
    Posted on July 9, 2018 at 22:35 Permalink

    This plugin is great and exactly what I was looking for. I am having an issue with the end of the scroll. When you reach the end and scroll down again, it will push the user back up 3 rows instead of to the very top. I can’t seem to figure out what is causing this to happen. I’d like it to loop back to the top of the site when the user reaches the end.

    Reply
    • malihu
      Posted on July 10, 2018 at 01:39 Permalink

      In the custom script above, try changing the selector from:

      selector:"._mPS2id-h",

      to:

      selector:".sfm-menu-level-0 ._mPS2id-h",

      Reply
  7. Stefano
    Posted on July 3, 2018 at 21:35 Permalink

    Hi Malihu,
    thank you for the plugin!
    In my case it doesn’t seem to work the scroll with mouse. The code is at the end of footer.php and the wordpress plugin is activated.
    Can you help me?
    http://www.stefanolista.it/test

    Reply
    • malihu
      Posted on July 5, 2018 at 00:08 Permalink

      Hello,

      Your theme seems to use its own function for scrolling the page which prevents “Page scroll to id” from being auto-enabled on your menu links.

      Try this:

      Go to plugin settings and change “Selector(s)” option to:

      a[rel='m_PageScroll2id'], .menu-item a[href*=#]:not([href=#])

      and save changes.

      Test your page and let me know if it works

      Reply
      • Kai Perez
        Posted on August 9, 2018 at 21:39 Permalink

        Here’s my story. I hated this plugin, it just wasn’t doing what I needed it to. After some research and patience I finally got it to work thanks to this comment. Thank you for the plugin, it really saves me from porting to an inferior theme just for this functionality. Cheers! I recommend a video tutorial.

        Reply
  8. Jhondas
    Posted on April 20, 2018 at 18:00 Permalink

    Hi Sir,

    i want to use this plugin desktop but in mobile i dont want to use this scroll extension. How can i do that ?

    Reply
    • malihu
      Posted on April 28, 2018 at 00:06 Permalink

      Change the CSS code to:

      @media only screen and (min-width: 768px) { body{ -ms-touch-action: none; touch-action: none; } /* disable on mobile */ }

      and change the js script mousewheel function to:

      }).on("mousewheel DOMMouseScroll",function(e){ //mousewheel if(window.matchMedia("(max-width: 768px)").matches) return; //disable on mobile if($($(this).data("mPS2idExtend").selector).length) e.preventDefault(); $(this).trigger("scrollSection",((e.originalEvent.detail<0 || e.originalEvent.wheelDelta>0) ? 1 : -1)); })

      i.e. add the line:

      if(window.matchMedia("(max-width: 768px)").matches) return; //disable on mobile

      right below:

      }).on("mousewheel DOMMouseScroll",function(e){ //mousewheel

      This will disable the script on viewport width below 768 pixels (i.e. mobile). You can change the 768px value (in the CSS and JS) to anything you want.

      Reply
  9. Mario
    Posted on April 12, 2018 at 12:29 Permalink

    Hi Malihu,

    I’ve used the script, but unfortunately now it’s just possible to scroll down the possible and I can’t scroll up anymore. In addition, The script with bullets doesn’t work, maybe I didn’t understand where to place it. Can you please help me?

    I have used Custom CSS and JS plugin to add the scripts.

    Thanks for you great job anyway.

    Reply
    • malihu
      Posted on April 12, 2018 at 16:37 Permalink

      I’ll need to see your page/site in order to help. Can you post your URL?

      Reply
    • DFD
      Posted on August 13, 2018 at 19:23 Permalink

      Same problem here. I’m on a WordPress full of plugins (by mine and by third parties). Sadly I’m on localhost and in this moment uploading the project is very difficult. However so far I solved replacing this part of the code:

      .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)); })<code> For this: <code>.on( "DOMMouseScroll mousewheel" , function( turn , delta ) { //mousewheel // Solution found in https://stackoverflow.com/a/29656088/762011 $( this ).trigger( "scrollSection" , ( ( delta == 1 ) ? 1 : -1 ) ); return false; })

      Seems to work fine (FF and Chrome). So sorry if I can’t give a link to the problem.

      On the other hand I wish to say a big THANK YOU to @malihu, for developing and maintaining this resource. The internet is a better place thanks to people like you, man.

      Reply
      • DFD
        Posted on August 13, 2018 at 19:29 Permalink

        Ah, I forgot to mention that the code above only works to solve my problem (perhaphs to the other people). When I implemented it on the fresh example, It didn’t work (the page only scrolls down).

        Reply
  10. John M. Moore
    Posted on March 30, 2018 at 07:58 Permalink

    Hello – I could use a little guidance. I’m trying to enable the mouse/keyboard scroll but cannot seem to append the above referenced javascript to footer.php correctly. The menu click/scroll works great.

    As an FYI – when I add after wp_footer.php(); (in a tag, I break my header. Any chance you can assist? I would greatly appreciate it!

    JMM

    Reply
    • malihu
      Posted on March 30, 2018 at 19:20 Permalink

      Hi,

      This sounds like a type error(?) Did you add the code in a script tag?

      Reply
      • John M. Moore
        Posted on March 30, 2018 at 20:05 Permalink

        Well I suppose that’s where I need some guidance…

        How exactly would that look?

        <?php wp_footer.php(); your code ?>

        Apologies, just new to this.

        Thanks again!

        JMM

        Reply
        • John
          Posted on March 30, 2018 at 20:17 Permalink

          How do I open/close the script tag? I did have it my comment above (on both sides of “your code”

          Reply
        • malihu
          Posted on March 31, 2018 at 15:34 Permalink

          I should be like this:

          <?php wp_footer.php(); ?> <script> /* javascript goes here */ </script>

          Reply
  11. Sergej
    Posted on March 27, 2018 at 07:38 Permalink

    Hey, thanks for this useful Plugin! I tried to make this script work on one of my pages, but i can’t seem to make it work. I’ve installed and activated your plugin, added this script to the footer, but it won’t scroll to the section, it scrolls normally. Pressing on buttons to scroll to the anchro works fine, though!

    If you find the time, take a look: https://neu.markete.ch/

    Reply
    • malihu
      Posted on March 27, 2018 at 22:01 Permalink

      Hi,

      I checked your page source and can’t find the custom script. Don’t know how you added it but it’s not in your document(?) Maybe it’s a cache issue?

      Reply
  12. Andre Alves
    Posted on March 21, 2018 at 18:11 Permalink

    Hi.
    I’m trying to implement this but I’m not sure if the class is the same (._mPS2id-h): http://prntscr.com/iudpuv

    When I change it to “_ps2id” it doesn’t scrolls and there’s no errors in the console.
    Could be something that changed on the plugin? I have the last version.

    Also, I’m using Visual Composer and the “sections” have full height. Not sure if can be the problem?

    Many thanks,
    Andre

    Reply
    • malihu
      Posted on March 22, 2018 at 04:28 Permalink

      You don’t need to add the _mPS2id-h or _ps2id classes in your HTML.

      Also, you cannot use this script without using “Page scroll to id” in your links (e.g. in your main menu) and sections. If you only want to use the mouse-wheel functionality without having such links in your page, you’ll have to create a hidden list of links that point to your sections/targets.

      Reply
  13. Aejaz
    Posted on March 19, 2018 at 07:18 Permalink

    Hi,
    I’m Using Avada Theme with fusion Builder
    I have added the script in Head area , I want mouse wheel change section Feature in my home page there are 8 sections in my homepage each section in the different container.

    I have added _mPS2id-h in my Fusion builder Container class and also in ID ( added the same class in all containers )
    I also tried by adding _mPS2id-h in only in class of fusion builder container but it’s not working and viceversa.

    am I doing anything wrong? Please check and tell
    In plugin settings, i have to change selector?

    Please Reply ASAP
    Regards

    Reply
    • malihu
      Posted on March 19, 2018 at 20:08 Permalink

      Hi,

      1.You don’t need to add the _mPS2id-h class anywhere. See “Important” note in the “Script” section above. You should remove the _mPS2id-h classes and ids.

      2.The script will not work when placed in the head tag. You need to place it at the bottom of your HTML. See the beginning of the guide above for the script placement.

      3.You cannot use the script without using “Page scroll to id” in your links (e.g. in your main menu). If you only want to use the mouse-wheel functionality you’ll have to create a hidden links list that point to your sections/targets.

      4.Your page layout/design is not optimized to have a functionality like the one offered by the script. Your sections have a fixed height so if a user has a short viewport, he/she will not be able to read any content by standard scrolling. All your section height should be fluid with height or max-height equal or less to the viewport.

      Hope this helps

      Reply
  14. Miguel Abrego
    Posted on February 20, 2018 at 07:37 Permalink

    Site: http://www.rorroechavez.com

    Hello man! Thanks a LOT for this, it’s extremely helpful.
    I’ve got one question though. I for the life of me have not found a way to put the jQuery code inside of my site (I’m a newbie using Visual Composer and very little coding) so I manually made the bullet side menu.

    I managed to make this Website and am using PS2id for the link handling. Is there any way to make the manually created side menu react to which section the user is viewing at the time? i.e., is there any code or CSS styling I could use so the item for the specific section being viewed changes colour? Thank you very much!

    Reply
    • malihu
      Posted on February 20, 2018 at 20:01 Permalink

      Hi,

      Did you solve the issue? I see that you’ve already added the plugin highlight class in your CSS.

      Since you use visual composer, it might be better to use the composer’s ID instead of creating the targets yourself (it’ll make highlighting better and more precise). Does the Visual Composer provide a Row ID/CSS ID for its blocks/modules?

      If yes, you can follow a guide like the one below which is similar to most page builders/Composers:

      http://manos.malihu.gr/using-page-scroll-to-id-with-the-divi-builder-plugin/

      Reply
  15. Amir
    Posted on February 3, 2018 at 01:21 Permalink

    First of all, thank you for this great plugin. It works very well.
    one question:
    Is it possible to show section names beside the bullets? It will be very nice to have that and it will be working like menu

    Reply
    • malihu
      Posted on February 3, 2018 at 17:47 Permalink

      You can create the aside bullets manually (skip the auto-generated aside bullet indicators function) and add exactly the markup you want (e.g. section titles etc.):

      <div id="sections-bullets"> <a href="#section-1" class="section-bullet" rel="m_PageScroll2id">Section 1</a> <a href="#section-2" class="section-bullet" rel="m_PageScroll2id">Section 2</a> <a href="#section-3" class="section-bullet" rel="m_PageScroll2id">Section 3</a> </div>

      You can then style them via CSS however you like.

      Reply
  16. preety
    Posted on December 26, 2017 at 07:44 Permalink

    its didnt work with this website please provide solution for me

    Reply
  17. Lara
    Posted on December 18, 2017 at 20:55 Permalink

    Hi there,

    I am trying to implement this on my page, and it’s just not working. I’m using Divi – and the front page has 3 sections. I would like this to work with the dot navs, and i’m decent at editing code – but can’t seem to get this to work – can you give me a hand?

    Thank you!

    Link: http://f4d.yaygraphicdesign.com

    Reply
  18. Gal Bahar
    Posted on December 18, 2017 at 12:26 Permalink

    Hello,

    Thank you for this great plugin! it’s lovly (:
    Unfortunatly I could’nt get the bullets indicators to work for me, would you be kind and help me figur it out?

    Best Regards!

    Reply
    • Gal Bahar
      Posted on December 20, 2017 at 09:56 Permalink
      • Gal Bahar
        Posted on December 20, 2017 at 10:33 Permalink

        NV I found it, it’s work now!
        but after the 5th it’s go back to the first insted of gowing to the next one (7 in total), and also it’s count my 7th twice I think because it’s mentioned in the main menu in the first time and in the mobile menu in the second time. what can I do to solve it?

        Thanks again this is awsome!

        Reply
      • malihu
        Posted on December 21, 2017 at 15:27 Permalink

        It seems that you create your links in the #top-bar (the hidden blue menu at the top).

        1. You need to add the 7th section link in this menu as well (you only have the first 6).

        2. In the custom js script, you need to add a more specific selector by changing the following line from:

        selector:"._mPS2id-h",

        to:

        selector:"#top-bar ._mPS2id-h",

        Doing the above will fix the count issue (7th section appearing twice in the bullets) and going back to first section after scrolling to last.

        Reply
        • Gal
          Posted on December 26, 2017 at 16:17 Permalink

          You are the man!!

          Reply
  19. harsh
    Posted on December 17, 2017 at 11:46 Permalink

    Suppose a page contains only 4 sections.

    I want to smoothly scroll between consecutive near sections using mouse scroll. With single mouse scroll the page should move one section next either upwards or backwards.

    let me know how its possible with wordpress divi theme :https://www.elegantthemes.com/gallery/divi/ .

    Reply
    • malihu
      Posted on December 17, 2017 at 17:24 Permalink

      1. Divi builder lets you add in id to any block element, so you should add an id to each one of your 4 sections.

      2. Install and activate “Page scroll to id” plugin. Go to plugin settings and set the “Selector(s)” option to:
      a[href*=#]:not([href=#])
      Save changes.

      3. Create your links that point to each of your sections (you can follow plugin’s tutorial here).

      4. Add the custom js script of this post in your footer.php template, inside a script tag after wp_footer(); function.

      Hope this helps

      Reply
      • Harsh
        Posted on December 19, 2017 at 18:55 Permalink

        Thank you for your response. I am trying to follow the steps. I have documented the screenshot here :

        https://drive.google.com/file/d/1OlgOk684TeBt6btubHtMAr3yo3ZpJACE/view?usp=sharing

        After adding the script to head of the code. The front end of the website shows some code at bottom of page. I have added a screenshot at the end of doc.

        Could you please have a look at them and correct me where I am making mistake.

        Reply
        • malihu
          Posted on December 21, 2017 at 14:50 Permalink

          Did you add the custom js script inside a script tag? I think this is the issue.

          In step 4, you need to wrap the js script inside:

          <script> code here... </script>

          Reply
          • Harsh
            Posted on December 21, 2017 at 21:42 Permalink

            Thank you for your response,

            I added the js script inside the mentioned tags. The issue with the code shown at bottom of the page is solved.
            But I am not getting the section change effect upon scrolling..

            I would like to understand thepoint 1. “so you should add an id to each one of your 4 sections.”

            Which id you are talking about ?

        • malihu
          Posted on December 22, 2017 at 14:09 Permalink

          Ah sorry, didn’t see the question in point 1 in your document.

          You need to add an id for each one of your 4 building elements via the divi builder interface.

          You can do this by opening your section module settings and adding an id value in the “CSS ID” field (see this video for reference).

          For example, open your first section module settings and add the value:
          section-1
          in “CSS ID” field. Click “Save”.

          Create a link in your content using the shortcode:
          [ps2id url='#section-1']Go to section 1[/ps2id]
          and save it.

          The url value should match the “CSS ID” value you added earlier, with an additional hash (#) at the beginning.

          So now, each time you click the “Go to section 1” link, the page will scroll to section-1 section. Do the same for each one of your sections.

          Note that in the document you posted, you used the wrong shortcode for creating the link (you used the shortcode that creates targets). The shortcode I posted above is the correct one (it uses the url attribute instead of id).

          Reply
          • harsh
            Posted on December 24, 2017 at 14:33 Permalink

            Thank you for your help.

            Now its working. I can move to section I want using the link.

            But I want this effect using single mouse scroll also. If I scroll my mouse down one point then the page should move to next section one point.

            as shown on this page: http://manos.malihu.gr/repository/page-scroll-to-id/demo/ps2id-mousewheel-keyboard-example.html

            If I am scrolling my mouse down the wole section gets changed.so within seven scrollof mouse wheel I can reach to bottom of the page.

            I want such effect.

            Actually I am trying to create effect same as : http://arhue.com/

            I would be grateful to you if you could tell me how can I get the effect of scrolling to next section using single scroll.

        • malihu
          Posted on December 24, 2017 at 16:14 Permalink

          Does the mouse-wheel scroll the page?

          In order to have the same layout and effect as the demo, you need to have your sections placed one next to the other:

          section-1 section-1 content section-2 section-3 content section-3 section-3 content

          and so on…

          You’ll also need to set their CSS properties in such a way that each section has the same height as the viewport height and positioned relative.

          I can’t really provide much help unless I see your page.

          Reply
  20. Ilja
    Posted on December 14, 2017 at 23:34 Permalink

    Hey, malihu,

    great plugin!

    But in my website, if i scroll to the last section and than scroll down again, the webside scrolls up to the first section.
    I can’t figure out why. Can you help me to fix it like in your Demo-Page?

    Thanks

    Reply
    • malihu
      Posted on December 15, 2017 at 12:21 Permalink

      Hi,

      In the script try changing:

      selector:"._mPS2id-h",

      to:

      selector:".textwidget ._mPS2id-h",

      Reply
      • Ilja
        Posted on December 15, 2017 at 23:00 Permalink

        it works!

        Thank You

        Reply
  21. Nick
    Posted on October 18, 2017 at 05:23 Permalink

    Hey mate, curious whether what I’m trying to achieve is possible:

    1. I have the home page with various “block-like” sections going down the page.
    2. They aren’t in the menu in any way.
    3. I would like to have my mouse scrolling stop at the top of the section for a bit. Kind of a hold? Some of my sections are larger than a full page so I don’t really want to make each movement of the mousewheel go to a new section (but if that’s the only option then happy to make the changes to get it working) – I’m mostly after the snapping effect.

    Does this sound possible?

    Reply
  22. Arkadiusz
    Posted on October 7, 2017 at 16:25 Permalink

    Hello,

    Is it possible to scroll containers longer than viewport height?
    Like here in section “Options” (#options):
    https://projects.lukehaas.me/scrollify/

    Reply
    • malihu
      Posted on October 7, 2017 at 19:46 Permalink

      Hi,

      No, it’s not possible with this script.

      Reply
  23. Haripal
    Posted on September 11, 2017 at 10:06 Permalink

    Sir, i have added keyborad and mousewheel code to my website. It worked well. But when i add touch event code it stopped working. Please let me know how can i solve this.

    Reply
  24. Weisen
    Posted on August 20, 2017 at 22:00 Permalink

    Hi Malihu,

    Good Day! Will the code above work even if I don’t add the classes on the menu?

    For example I just wanted the elements on just my homepage to scroll and menu links on top lead to different pages?

    I’m using uncode theme but I don’t think they have the scroll to section functionality which your plugin can provide.

    Thank you!

    Reply
  25. Vektor
    Posted on August 6, 2017 at 03:36 Permalink

    Hi Malihu!

    I have a serious problem with this (sorry for my ignorance and english, i’m spanish designer).

    Everything works fine, but don’t work with mousewheel and i don’t understan why. Can you iluminate me please?

    Really thanks!

    Reply
    • malihu
      Posted on August 6, 2017 at 12:42 Permalink

      The js code you added is not correct. Change the lines at the start:

      jQuery(document).ready(function($){ $(window).on("load",function(){

      with:

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

      Reply
      • Vektor
        Posted on August 7, 2017 at 03:53 Permalink

        First, thanks for reply! I changed that code and still don’t work. Anything more for helping me please?

        Reply
        • malihu
          Posted on August 7, 2017 at 12:51 Permalink

          The page at vektorlab.com/testscroll/ works well for me. Did you fix the issue?

          Reply
          • Vektor
            Posted on August 7, 2017 at 12:57 Permalink

            you are right! The problem is i’m working with firefox and don’t work with firefox 54.0.1. Work in chrome and iexplore. Do you know why? Really really thanks

    • malihu
      Posted on August 7, 2017 at 13:18 Permalink

      Try removing the following classes from your links:

      __mPS2id _mPS2id-h mPS2id-clicked mPS2id-highlight mPS2id-highlight-first

      and also the following from your targets:

      _mPS2id-t mPS2id-target mPS2id-target-first mPS2id-target-last

      All the classes above are added by the plugin automatically, so you should not add them manually.

      Also, remove the code below as you already loading the jQuery library in your HTML head tag

      <!-- Google CDN jQuery with fallback to local --> <script src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> <script>window.jQuery || document.write('<script src="js/jquery-3.1.0.min.js"><\/script>')</script>

      Reply
  26. Jaap de Wit
    Posted on July 25, 2017 at 18:44 Permalink

    Hi,

    I’ve installed the plugin and placed the custom code for scrolling to next section with mouse in the theme’s custom code section (header).
    But it’s not working. I’m using the Divi theme.

    Your older code which I found in https://wordpress.org/support/topic/scroll-with-mouse-to-id-possible/ works for some part.

    Any idea? (website is in maintenance, I can disable it for some period, let me know)

    Cheers,
    Jaap

    Reply
    • malihu
      Posted on August 6, 2017 at 12:46 Permalink

      I can’t really help unless I see your page, so let me know when you disable maintenance.

      Reply
      • Jaap
        Posted on August 29, 2017 at 09:58 Permalink

        Hi,

        Maintenance is disabled. You can check. WP plugin is enabled and I’ve placed the extended script in the header.

        Cheers,
        Jaap

        Reply
        • malihu
          Posted on August 31, 2017 at 21:17 Permalink

          It seems that all page scripts are using the defer attribute which affects when js code is executed. Try adding the custom/extended script in an external .js file and include it at the bottom of your document.

          Reply
          • Jaap
            Posted on September 8, 2017 at 09:57 Permalink

            Hi Malihu,

            Thanks for your answer. I’ve placed the script in a separate js file and am calling it from the footer.php. Still doesn’t work though. Any more ideas?

            Cheers,
            Jaap

          • Jaap
            Posted on September 14, 2017 at 13:09 Permalink

            Hi Malihu,

            Hope you have some time to check. My customer really likes this functionality and wants to have it work.
            Cheers,
            Jaap

        • malihu
          Posted on September 15, 2017 at 21:42 Permalink

          I’ve just checked it again. Try adding defer to the script (like the other scripts in your page):

          <script src="path/to/scroll.js" defer></script>

          Reply
          • Jaap
            Posted on September 17, 2017 at 11:42 Permalink

            Hi, I’ve tried adding ‘defer’ but then scrolling down is no longer possible. Only through menu items. When scrolling up it’s scrolls all the way to the top.

        • malihu
          Posted on September 17, 2017 at 16:04 Permalink

          OK first, you need to use defer

          Second, it seems that you have a duplicate of each section/link. One for desktop and one for mobile. The duplicated links are all on the same menu element with no way to identify them.

          The issue is that the script cannot work with the desktop and mobile links in the same menu element. I’m not sure if you can change this(?)

          Reply
          • Jaap
            Posted on September 18, 2017 at 11:33 Permalink

            Hi Malihu,

            I’ve managed to get it working on desktop by removing the section id’s from the mobile sections. I also need to get it working on tablet and mobile. How come it doesn’t since the mobile id’s are different from the desktop ones? Breaking my head here 🙂

            Cheers,
            Jaap

          • Jaap
            Posted on September 18, 2017 at 16:22 Permalink

            Hi Malihu,

            Almost there! I managed to solve the problem with desktop/mobile. The scroll is working nog on all devices. The only thing I see is that sometimes when scrolling it skips a section. Any idea how to fix that?

            Cheers,
            Jaap

        • malihu
          Posted on September 19, 2017 at 19:08 Permalink

          Glad you solved the issue. I can’t really say why it might skip a section. Do you have a special mouse or?

          I’ve tested your page extensively with standard mouse-wheel (normal wheel notch), spin-scroll mousewheel (logitech hyper-scroll) and trackpad (2 finger gesture) and it never missed a section for me.

          Keep in mind though that if you use for instance trackpad or spin-scroll acceleration, the sections will continue to scroll untill the wheel/gesture is stopped.

          Reply
          • Jaap
            Posted on September 19, 2017 at 21:15 Permalink

            Hi Malihu,

            Thanks for your answer. I’m using an Apple magic mouse but scrolling with the trackpad also skip sections. (chrome and safari)

            I also found out that when using the script with touch events scrolling on other pages than the homepage is no longer possible on all Samsung devices.

            Removing this line: “body{ -ms-touch-action: none; touch-action: none; }” solves that issue.

            Cheers,
            Jaap

        • malihu
          Posted on September 20, 2017 at 19:16 Permalink

          If you have other pages that you want to scroll normally, you need to change the CSS to:

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

          so it applies only on homepage.

          Apple magic devices use scrolling acceleration that’s very sensitive. A section might get skipped even when you touch-swipe with minimum force. I’m guessing this is the case(?)

          Reply
  27. John
    Posted on June 24, 2017 at 14:07 Permalink

    Hi Malihu,

    Thanks for your great plugin and all your work. I’m trying to get this extension of ps2id work but with little success. Everything seems fine from my side but somehow no bullets appear and no keyboard/mouse scrolling is possible.

    Could you possibly offer a hand? The test site I’m working on is here.

    Thanks in advance.

    J.

    Reply
    • John
      Posted on June 24, 2017 at 18:09 Permalink

      John here again,

      Just a quick update. I got the scroll with mouse and keyboard to work after all. It was my mistake.

      The only two issues now are the bullet points not appearing and also a strange jump from the 1st to the 3rd section and back. The other two sections are being ignored.

      Any help will be appreciated,
      Thanks.

      Reply
      • malihu
        Posted on June 25, 2017 at 02:37 Permalink

        Hello,

        In one of your widgets (I think a section-2 link), you’ve set the class _mPS2id-h by hand. Remove it and test again the page.

        The problem comes from those next/previous widget links so first try the above to see if this fixes the issue (I’ve made a live test by removing the next/previous widget links and mousewheel works as expected without skipping sections).

        The bullets are appended in your page. You just need to style them so they appear over your content. For example:

        /* aside indicators */ #sections-bullets{ position: fixed; right: 2em; height: auto; top: 50%; transform: translateY(-50%); z-index: 99; } .section-bullet{ display: block; position: relative; width: 9px; height: 9px; border-radius: 100%; background: #fff; margin: 12px auto; opacity: .6; } .section-bullet:hover, .section-bullet.mPS2id-highlight{ opacity: 1; background: #e6842c; }

        You also have a js console error, because you’ve wrapped the js code in jQuery(document).ready(function($){ ... })(jQuery); which is not correct. The code should be wrapped in (function($){ ... })(jQuery);, exactly as shown in the post above.

        Reply
        • John
          Posted on June 28, 2017 at 19:12 Permalink

          Hi again Malihu,

          Thanks for the reply, extremely helpful.

          You were right about the unnecessary class, it’s removed. I fixed the console error also, I was prompted by the plugin I use to add scripts to form it this way. However the jumping behaviour persists. Scrolling up from section-1 leads to section-3 and scrolling down from s-3 takes me back to s-1. All other navigation is ignored. I’ve run through everything again but I don’t get it.

          By the way, the next/previous links are necessary for the designer and I can’t do without them. I knew already that the scrolling is smooth without them but I think I can’t drop them. Any other ideas would be helpful otherwise I’ll have to chose between the two.

          And thanks for the bullets too. they were there, I never thought of simply styling them.

          Thanks a million,
          John

          Reply
          • malihu
            Posted on June 29, 2017 at 05:34 Permalink

            No need to choose between the two. We’ll make it work 😉

            Go to plugin settings and set the value of “Highlight selector(s)” option to:

            .menu-item a[href*='#']

            Save changes and test your page again.

            See also the last point in my previous comment. You have inserted the js custom script in:

            jQuery(document).ready(function($){ //custom script here... })(jQuery);

            which is not correct. You need to change it to:

            (function($){ //custom script here... })(jQuery);

            Let me know

          • John
            Posted on June 29, 2017 at 17:12 Permalink

            Hi again,

            Genius! That solved it, so cool.

            The custom js script I had corrected the previous time, just didn’t explain it well in my previous message. The new Highlight selector did the trick.

            Thanks so much M., amazing stuff.

            John

          • malihu
            Posted on June 29, 2017 at 20:25 Permalink

            Cool 🙂 Glad I helped!

  28. Manuel
    Posted on May 27, 2017 at 06:32 Permalink

    How to select specifics pages for the script work in some pages and others don’t work.

    Reply
    • malihu
      Posted on May 29, 2017 at 21:44 Permalink

      If you’re using WordPress, you should insert the js script in conditional tags.

      If not, simply insert the script only in the pages you want.

      Keep in mind that in order for such scripts to work, you need specific page layout/design (like the one in the demo).

      Reply
  29. 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
  30. 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

Comments pages: 1 2

Post a comment

Cancel reply

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