preventing a nested JavaScript function from being executed multiple times

Trying to implement a JavaScript function to run only once has proven to be quite a challenge for me. Despite exploring previously asked questions like Function in javascript that can be called only once, none of the suggested solutions seem to work for me. I suspect that the issue may be related to the presence of nested functions or some crucial detail escaping my attention. The desired functionality involves triggering a function upon scrolling a webpage which includes running a brief animation on a canvas within the header, reducing the header's size, and maintaining it in that state.

Unfortunately, the problem persists as subsequent scrolling events lead to the re-execution of the animation. Below is an abridged snippet of the code that fails to deliver the desired outcome:

$(document).on("scroll",function(){

    var arrange_title = function(){

        //some code 
    };

    if($(document).scrollTop()>0){ 
        arrange_title();
        arrange_title = function(){};
        setTimeout(function(){
            $("header").removeClass("large").addClass("small");
        },1000);
    }
});

Alternative attempts, such as declaring a global variable, initializing it to "false" within a "window.onload" function, and subsequently setting it to true within a conditional statement triggering the animation, have also proven ineffective in preventing the repeated execution of the function. Any insights or suggestions would be greatly appreciated.

Answer №1

When searching for a solution, consider using a function like listenToOnce where the listener triggers only once, never again. It can be adjusted for multiple calls, but the basic logic remains unchanged:

First, register the listener.
Then, once the listener triggers, remove it.

Refer to .off

$(document).on("scroll",function(){

    var arrange_title = function(){
        //some code 
    };

    if($(document).scrollTop()>0){ 
        arrange_title();
        arrange_title = function(){};
        setTimeout(function(){
            $("header").removeClass("large").addClass("small");
            // $(document).off('scroll'); // or here
        },1000);
    }

    $(document).off('scroll'); // remove the listener, you can place this in the setTimeout to ensure the classes are added/removed
});

Answer №2

Avoid resorting to timeouts as a solution. This may be the root cause of your issues. Instead, define a variable outside of your function using the var keyword to give it global scope. Wrap your code within a conditional check for that variable. Prior to executing your code for the first time, modify the variable within the check to prevent the code from running again.

Answer №3

Avoid using setTimeout whenever possible. Most animations can be monitored for completion.

function animateHeader() {
  return $('header').animate();
}

function shrinkHeader() {
  $("header").removeClass("large").addClass("small");
}

function scrollHandler(event) {

  if ($(document).scrollTop() > 0) { 

    animateHeader().then(shrinkHeader);

    $(document).off("scroll", scrollHandler);

  }

}

$(document).on("scroll", scrollHandler);

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

Utilize React Material UI to elegantly envelop your TableRows

Currently, I am faced with a challenge involving a table that utilizes Material UI and React-table. My goal is to wrap text within the TableRow element, but all my attempts have not been successful so far. Is there anyone who knows the best approach to a ...

How to use jQuery with multiple selectors?

I am attempting to create a feature where multiple links are highlighted when one is clicked. However, I am encountering an issue where only the link that is clicked is being highlighted, rather than all three links. Below is the code snippet: $('#v ...

Setting up the InMemoryCache in Vue ApolloConfiguring the InMemoryCache

I've set up vue-apollo following the instructions in the apollo.config.js file from this guide: (I'm using VSCode). Now, I want to configure the InMemoryCache to exclude the typeName (addTypename: false) like it's explained here: https://w ...

What is the best way to divide the dev-server.js file in Vue into multiple separate files?

Currently, I am utilizing vue.js to develop an application and have created a mock login api on localhost in dev-server.js. Now, I am looking to refactor the code related to the login api into a separate file. Do you have any suggestions on how I can ach ...

VueJS: Preloading data prior to and following component initialization

VueJS is a new technology for me, and I'm currently working on a component that needs to retrieve data from an API before loading the corresponding route. The component should only load once the data is fetched. Additionally, after the component is cr ...

Issue with webcomponents-lite.js file

Encountering this particular error message in the console while attempting to run the application: webcomponents-lite.js:64Uncaught TypeError: Cannot read property 'getAttribute' of null at webcomponents-lite.js:64 at Object.549 (webcomp ...

Material UI allows for the creation of numbered lists with ease. This

<List> {instructionList.map((el) => ( <ListItem divider key={el.id}> {el.type === 'number' ? <React.Fragmen ...

Tips for integrating Excel files with NestJS

I'm in the process of developing a REST API that will utilize a third-party API to retrieve specific status information. The URLs needed for this API are stored in an Excel file, which is a requirement for this use case. My goal is to extract the URLs ...

The error message "Create controller with service — Get... is not a function" indicates that

Within my ASP.NET Boilerplate project, the following code snippet is present: (function () { appModule.controller('augustinum.views.kostenstelle.index', [ '$scope', '$uibModal', 'abp.services.app.kostenstelle ...

Ways to limit date selection with JavaScript or jQuery

On my webpage, I have two date fields: fromDate and toDate. My goal is to prevent submission if the difference between the dates is more than 7 days. https://i.sstatic.net/65LLH.png Despite implementing a script for this purpose, it doesn't seem to ...

`res.render when all data queries are completed``

When I make an app.get request in my server.js file, I retrieve a dataset from MongoDB and then render my page while passing the data to it. Here is an example: //page load app.get('/', (req, res) => { //find all data in test table ...

Testing the mongoose.connect callback method in Jest: A step-by-step guide

Currently working on a new Express application and utilizing Jest as the testing framework. All sections of code have been successfully covered, except for the callback of the mongoose.connect method: https://i.sstatic.net/SNrep.png I attempted to spy o ...

Fixing PNG Fading Issue in Internet Explorer 8

I am currently utilizing the jQuery Cycle plugin to produce a fading animation effect. While this works perfectly on most browsers, I have encountered an issue with PNG files containing semi-transparent pixels in Internet Explorer 8. These partially transp ...

What is the best way to turn off the annoying pop-up messages that show up for input validation, specifically the one that says "Please complete

Currently using Angular 2, my form has input fields similar to this simplified version: <input class="body-text1" type="text" [(ngModel)]="model.name" name="name" required minlength="1"> <!--more inputs like this --> Although I have implement ...

At what point is ng-if triggered?

I am currently in the process of developing functionality for buttons that open directives in modal windows. To keep things simple, I decided to use a modal container flagged with the versus directive: <div ng-if="vm.Modal.Modal1"> <directive-for ...

Dynamically assigning classes based on the element that is being scrolled beyond

I am working on a navigation bar (nav) that consists of letters and corresponding sections. My goal is to add an active class to the letter when a user scrolls to its associated section. For instance: When the user scrolls to a section with the id of a, t ...

jQuery sidebar with a fixed position

Is there a way to implement a sidebar menu feature using jQuery that reappears on the left as the user scrolls down the page? You can see an example sidebar menu here. ...

The Angular Animation constantly resets with each new action taken

In my Angular project, I am working on a scaling animation for a list. I want the animation to only trigger when specific buttons (red and green) are pressed. Currently, the animation restarts regardless of what I click on. Can anyone help me troubleshoot ...

Simplest method for storing small amounts of data

As a beginner in coding, I may be asking a question that seems obvious to some. I successfully created a web app using html/JavaScript that collects user input and transforms it into a variable of my interest. The data I want to extract is stored in an arr ...

How can I effectively handle extensive data parsing from a file using JavaScript?

Looking to optimize data parsing in JavaScript for a large file? I'm currently using JSON parse for a 250MB file, but it's too slow. Is there a faster method to extract a high volume of data without iterating through every character? The file con ...