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

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:

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

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

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 afterPage 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();

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:

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:

166 Comments

First, thank you for this amazing tutorial. It’s working fine with my desktop mouse but not in my laptop (trackpad), it jump 2 sections instead of one.
I tried with your demo website, work’s fine in desktop/laptop.
Do you have any clues please ?

First of all thanks for this beautifully done script. I’ve been scratching my head for a year now but nothing seemed to work perfectly as yours. The only very small hiccup I’m having is perhaps regarding the offset. When I’m using the section buttons on the right, the section is perfectly adjusted to the middle of the screen. But when I’m using mouse scroll, the section is a bit offset. Any ideas what went wrong on my part?

Thank you for such great work on this plugin and it works like a charm. However, I do have one query regarding the scroll thing.

I have implemented scrolling functionality in adjacent sections. But there are certain sections whose height is greater than the viewport height because of more content in it.

In this scenario, the scrolling behavior is not working as expected.

Expected behavior: If my viewport height is 630px and section height is 900px. When a user navigates to section, only 1st half i.e. 630px of content should be visible and on another scroll, remaining content i.e. (900 – 630)px should be visible.

I’ve tested your page with 2 mouses (with and without free-scroll) as well as with a Microsoft trackpad on Windows and I don’t have the issue you describe. Maybe it’s something specific with your mouse (e.g. not registering the first wheel notch since it’s old)?

The current script above is developed to work only on adjacent sections that are the same height as the browser’s viewport (i.e. with very specific content layout).

This said, you could add a target id on your footer (the same way you’ve done with your other sections) in order to make it work like the rest of your sections.

I’m currently working on updating the mouse-wheel script so it can work with non-adjacent sections (like in your case) and sections with content that extends the browser’s viewport.
I’ll also make the script easier to implement via functions.php.

Hi Malihu, thank you for the great work on your plugin (Page scroll to id) and the additional code to jump to id’s rather than scrolling. I’m using your work on a new website (in development) and I’m encountering some issues. The url is http://bed.k-dushi.com/. Jumping to the second section works but then it “get’s stuck”. It isn’t possible to jump to the third section other than the arrow button I included. It also doesn’t jump to the footer. From the last section (before the footer) it jumps back up. Would it be possible to check this out? That would be very much appreciated. Thanks in advance! Best regards, Marcel

This will make the plugin script to scroll through the the sections defined by your arrow links (i.e #two and #three). You’ll probably need another link like these to point to your section #one so the user can cycle through all 3 sections.
—–

Hi Malihu, sorry for my late reaction. I didn’t get your email but also didn’t receive a notification of your reply.. So I only saw it just now.

I added the class and it works a bit better. But it still doesn’t scroll back to #one although I added a button linking to this id. Also it doesn’t go to the footer. Do I need to give that the id #four (for example) and at a link as well?

The 2 buttons you added are a bit different than the arrows (their CSS selector is different), so the “Highlight selector(s)” value we added will not work for them.

The best way to have one set of elements and still use any type of button you like (or not use any button if you want), is to have a hidden menu somewhere in your page, that users won’t be able to see (but the script will). For example:

hi, i am using this scrolling feature in my home page but my requirement is i want to use menu with other links bcuz my website is a multipage website , Is it possible to scroll section wise without passing links in the menu? If possible kindly provide me the solution

The custom script in this post already covers scrolling to the next/previous section via keyboard arrows. To have actual next/previous section links, you’ll need to create them manually. It’s what I did on the demo page you posted.

The script cannot create such links automatically. You should create a link for each section that points to the next section’s id (same with previous links).

Hi Manos.
I have followed your guide on this page but can’t seem to get the scroll-function to work with keyboard-arrows.
I’m using the WordPress-plugin as well and has put the top JS into the footer.
I have tried with different selectors and targets but to no avail.
Do you have any idea where I go woring?
Thank you in advance.

Hi again Malihu.
The site crashed shortly after, so I have build it again.
Now I get the scroll to work but shortly on the frontpage after it stops working. when I check the Chrome browser Console I get the following error:
[Violation] Forced reflow while executing JavaScript took 60ms
This error is repeating itself and I think that is the reason the scrollfunction doesn’t work.
Another question: can I get the keyboard-arrows to work after the last page-scroll (It scrolls 3 times to the 3 #-links I have made – but then the keyboard-arrows doesn’t work any more)

Hi, as of the latest chrome update, scrolling events are listed as passive by default. That means event.preventDefault() will be ignored on scroll unless another parameter ({ passive: false }); is passed to the event listener.

Jquery has an open ticket for this and apparently it is hard to implement passing this extra parameter with jquery.

At the moment there’s no way to do it with jQuery. The only way is to write a vanilla javascript mouse-wheel function.

Because of the severity of this issue, I updated the code and replaced the jQuery mouse-wheel function with a pure javascript one. This is needed in order to use the passive: false (see the updated code).

You’ll need to have the section links somewhere in your page (even hidden), because otherwise the script cannot function. You can simply place a div with the links anywhere and hide them via CSS display: none;

Thanks for this plugin, script, and support! I hope you can assist me. I have the plugin installed, but after I put the script into my footer.php, I can no longer scroll with my mouse at all on the site.

If I use the menu to go to another section on the page, that works fine – but if you scroll down on the mouse, it will bring you always to the top of the page.

I am trying to have this scroll directly to sections in my divi one page using your script and the Page scroll to id plugin but I can’t make it work. Could you have a look and let me know if you have an idea why?

«Free software» means software that respects users' freedom and community. Roughly, the users have the freedom to run, copy, distribute, study, change and improve the software. With these freedoms, the users (both individually and collectively) control the program and what it does for them. — GNU, The Free Software Definition