Issue with jQuery's click-to-scroll menu bug

My website features a unique "click-to-scroll" menu setup with the following logic:

1. When a menu link is clicked, the page scrolls to the corresponding anchor and adds an active class to that link.

2. On scroll, the active class toggles based on the current anchor's location.

While everything works fine, there is a minor bug where clicking a link causes the page to flicker slightly, affecting the active menu links as well. To see and test this live, visit (note: it's still in early development stages, lacks mobile responsiveness, and may look subpar).

I'm unsure of what exactly triggers this flickering, but I suspect it's because my code instructs the active class to be added to a link when scrolling over its corresponding section. This results in adding the active class to other links before reaching the desired section due to the need to pass through different sections while scrolling.

Both of these scenarios are undesirable.

Check out the jsFiddle here

Here's the code snippet for reference:

var section_padding = 45;

$("#menu ul li a").on("click", function(event) {
event.preventDefault;

$("#menu ul li a.active").removeClass("active");
$(this).addClass("active");

var target = this.hash;
var menu = target;
var cache_target = $(target);
var buffer = (cache_target.offset().top - section_padding);

$("html, body").stop().animate({
"scrollTop": buffer
}, 400, "swing");

});

function scroll(event) {
var scroll_pos = $(document).scrollTop();
$("#menu ul li a").each(function() {
var cur_link = $(this);
var ref_el = $(cur_link.attr("href"));

if( ref_el.position().top <= scroll_pos && ref_el.position().top + ref_el.height() + (section_padding * 2) > scroll_pos ) {
$("#menu ul li a").removeClass("active");
cur_link.addClass("active");
} else {
cur_link.removeClass("active");
}

});
}

$(document).on("scroll", scroll);
* {
    margin: 0;
    padding: 0;
}

#menu {
    display: block;
    height: 50px;
    width: 100%;
    position: fixed;
    z-index: 100;
    background: rgba(255, 255, 255, .8);
}

#menu ul {
    display: block;
    width: 100%;
    height: 100%;
    list-style: none;
}

#menu ul li {
    display: block;
    box-sizing: border-box;
    height: 100%;
    width: calc(100% / 5);
    border-right: 1px solid #ccc;
    border-bottom: 1px solid #ccc;
    float: left;
    text-align: center;
    line-height: 50px;
}

#menu ul li a {
    display: block;
    text-decoration: none;
    font-family: arial;
}

#menu ul li a:hover,
#menu ul li a.active {
    background: #f0f0f0;
}

#sections {
    display: block;
    position: relative;
    top: 50px;
}

section {
    display: block;
    height: 500px;
    width: 100%;
    background: #67D182;
    padding: 45px 50px;
    box-sizing: border-box;
}

#sections section:nth-child(even) {
    background: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<nav id="menu">
  <ul>
    <li><a href="#top">Top</a></li>
    <li><a href="#about">About</a></li>
    <li><a href="#portfolio">Portfolio</a></li>
    <li><a href="#contact">Contact</a></li>
    <li><a href="#blog">Blog</a></li>
  </ul>
</nav>

<div id="sections">
    <section id="top">
      <h2>#top</h2>  
    </section>
    
    <section id="about">
      <h2>#about</h2>  
    </section>
    
    <section id="portfolio">
      <h2>#portfolio</h2>  
    </section>
    
    <section id="contact">
      <h2>#contact</h2>  
    </section>
    
    <section id="blog">
      <h2>#blog</h2>  
    </section>
</div>

If you have any insights on resolving this issue, please share. Your assistance is highly appreciated. :)

Answer №1

The reason for this issue is that preventDefault is a function, so all you need to do is make the following change:

event.preventDefault;

Change it to:

event.preventDefault();

This adjustment should work correctly. FIDDLE: https://jsfiddle.net/lmgonzalves/ve5qr3bL/2/

UPDATE:

You must unbind the scroll event and then re-bind it once the animation is completed.

$("#menu ul li a").on("click", function(event) {
    event.preventDefault();

    $(document).off("scroll"); // unbind here

    // code

    $("html, body").stop().animate({
        "scrollTop": buffer
    }, 400, "swing", function() {
        $(document).on("scroll", scroll); // bind again here
    });

});

FIDDLE: https://jsfiddle.net/lmgonzalves/ve5qr3bL/3/

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Check if the string includes an <a> element in PHP

If I were to submit a form with the message: Hey there! Interested in <a href="http://example.com">visiting</a> my <a href="http://example.com">website</a>? What is the PHP code needed to identify if the string contains <a> ...

Autopost back feature fails to function on pages with AJAX loaded divs

My page utilizes a jQuery onclick event to load an external .aspx file into a div. The loaded page contains a dropdown list with an autopostback attribute that transfers the selected item to a label. Although everything is functioning correctly initially, ...

Using jQuery in CodeIgniter for form validation and AJAX form submission is an effective way to ensure

Whenever I submit the form, errors show perfectly. However, when I submit it again, the data enters the database but the else condition does not work as expected. I want to hide the form and display a success message. The first time, an error response occ ...

Is it necessary to encapsulate Factory calls within a function in my Controller file?

Typically, I call a Factory from my Angular controller directly within the controller function without creating a separate method. For instance: (function () { 'use strict'; angular.module("Dashboard") .controller("DashboardController", D ...

Using $state.go within an Ionic application with ion-nav-view may cause unexpected behavior

I recently started working on an Ionic Tabs project. I have a button called "initiateProcess" that triggers some operations when clicked using ng-click. Within the controller, it performs these operations and then navigates to a specific state (tab.target) ...

The 'classProperties' React component module is currently not enabled

Encountering an error while running my react module 'classProperties' isn't currently enabled (44:11): } 43 | // componentDidUpdate or try this > 44 | onClick = (e) => { | ^ 45 | e.preventDefault(); 4 ...

Bottom-anchored horizontal navigation bar for seamless scrolling experience

Is there a way to create a navbar with horizontal scrolling at the bottom of the page without compromising its scrollability? When I use position: fixed;, the navbar becomes non-scrollable. div.scrollmenu { background-color: #333; overflow: auto; ...

Is it possible to retrieve a Video File Upload using PHP?

Imagine if I were to design a form with a basic "File Upload" input, it might look something like this: <div class="elementor-field-type-upload elementor-field-group elementor-column elementor-field-group- ...

Guide to iterating through an object and generating child components in React.js

Struggling with a React.js loop through child component issue as a newcomer to the language. I have an object and want to create child components from its values. Any help would be greatly appreciated. var o = { playerA: { name: 'a', ...

breaking up various dates into specific formatting using React

I need to convert a series of dates Wed Nov 13 2019 00:00:00 GMT+0000 (UTC),Tue Nov 19 2019 00:00:00 GMT+0000 (UTC),Tue Nov 19 2019 00:00:00 GMT+0000 (UTC) into the format 11/13/2019, 11/19/2019, 11/19/2019 ...

Switch between display modes using a button and CSS media query

I'm trying to find the most effective method for toggling display states on a webpage using a button while also being able to adjust based on screen size. For larger screens, I want to default to a horizontal layout with the option to switch to vertic ...

Combining and mapping arrays in Javascript to form a single object

I am using the following firebase function this.sensorService.getTest() .snapshotChanges() .pipe( map(actions => actions.map(a => ({ [a.payload.key]: a.payload.val() }))) ).subscribe(sensors => { ...

A guide on incorporating a Java loop with Selenium automation

// Searching and deleting process driver.findElement(By.cssSelector("input[type='search']")).sendKeys("Diversification Rule Template"); driver.findElement(By.className("delete-template")).click(); Alert alert = driver.switchTo.alert(); Thread. ...

Populating Dropdown list with values based on input provided in Textbox

Can you assist me in finding the solution to this issue? I have a TextBox and a DropDown list. For example, if I type "Anu" into the textbox, I want it to populate the dropdown list based on the text entered. How can I achieve this? I am working with vb. ...

Just starting out with CSS and HTML - Receiving an alert saying "special characters need to be escaped"

Just updated: I'm in the process of designing a button that will redirect to an external URL. I don't want the standard gray button so I added some custom styling. When testing this code, everything works perfectly until I integrate it into Word ...

A TypeError is thrown when attempting to use window[functionName] as a function

I came across this page discussing how to call a function from a string. The page suggests using window[functionName](params) for better performance, and provides an example: var strFun = "someFunction"; var strParam = "this is the parameter"; //Creating ...

What is the best way to utilize an audioStream provided by the Amazon Lex SDK during the process of recognizing a spoken phrase?

I have successfully built a chatbot using Amazon Lex and integrated it with a Node.js Rest API by following the official documentation. After sending a RecognizeUtteranceCommand, I am receiving an audioStream in the response. Now, the main challenge I&ap ...

Understanding how to utilize the scoped slot prop within a parent computed property

Currently, I have a closely connected pair of parent-child components utilizing a scoped slot. The child component sends data to the parent through a scoped slot prop (which we'll refer to as myScopedProp). Everything is functioning smoothly in this s ...

Ways to personalize Angular's toaster notifications

I am currently utilizing angular-file-upload for batch file uploads, where I match file names to properties in a database. The structure of the files should follow this format: 01-1998 VRF RD678.pdf VRF represents the pipeline name RD represents the lo ...

Executing a function when a webpage loads in Javascript

I have created a responsive website using Twitter Bootstrap. On my site, I have a video displayed in a modal that automatically plays when a button is clicked. Instead of triggering the function with a button click, I want the function to be called when ...