Setting a closure to encapsulate a global variable

I possess a set of functions that allow me to configure prompts for when someone exits a page while inputting values. However, my main concern lies in how to properly encapsulate the checkFlag. Currently, checkFlag is being treated as a global variable which proves to be somewhat inconvenient.


let checkFlag = false;

const onBeforeunloadHandler = function(e) {
    var msg = '';
    e.returnValue = msg;
};

const formAlert = function() {
    if(!checkFlag) {
        window.addEventListener('beforeunload', onBeforeunloadHandler);
        for(var i = 0; i < checkValue.length; i++) {
            checkValue[i].removeEventListener('input', formAlert);
            checkValue[i].removeEventListener('change', formAlert);
        }
        checkFlag = true;
    }
};


(() => {
    let checkValue = document.querySelectorAll( "input[form='test'], textarea[form='test']");
    let submitBtn = document.querySelector('button[type="button"]');
    
    for(var i = 0; i < checkValue.length; i++) {
      checkValue[i].addEventListener('input', formAlert);
      checkValue[i].addEventListener('change', formAlert);
    }
    submitBtn.addEventListener('click', function() {
        window.removeEventListener('beforeunload', onBeforeunloadHandler);
    });
})();

If you have any suggestions or feedback, please don't hesitate to share. Thank you!

Answer №1

It's best to encapsulate everything in the IIFE instead of using variables in the outer scope.

(() => {
    let flag = false;

    const unloadHandler = function(e) {
        var message = '';
        e.returnValue = message;
    };

    const alertForm = function() {
        if(!flag) {
            window.addEventListener('beforeunload', unloadHandler);
            for(var j = 0; j < values.length; j++) {
                values[j].removeEventListener('input', alertForm);
                values[j].removeEventListener('change', alertForm);
            }
            flag = true;
        }
    };

    let values = document.querySelectorAll( "input[form='test'], textarea[form='test']");
    let button = document.querySelector('button[type="button"]');
    
    for(var k = 0; k < values.length; k++) {
      values[k].addEventListener('input', alertForm);
      values[k].addEventListener('change', alertForm);
    }
    button.addEventListener('click', function() {
        window.removeEventListener('beforeunload', unloadHandler);
    });
})();

Answer №2

(() => { let flagChecked = false;

const unloadHandler = function(e) {
    var message = '';
    e.returnValue = message;
};

const alertForm = function() {
    if(!flagChecked) {
        window.addEventListener('beforeunload', onBeforeunloadHandler);
        for(var index = 0; index < valueToCheck.length; index++) {
            valueToCheck[index].removeEventListener('input', formAlert);
            valueToCheck[index].removeEventListener('change', formAlert);
        }
        flagChecked = true;
    }
};


let valueToCheck = document.querySelectorAll( "input[form='test'], textarea[form='test']");
let buttonSubmit = document.querySelector('button[type="button"]');

for(var index = 0; index < valueToCheck.length; index++) {
  valueToCheck[index].addEventListener('input', alertForm);
  valueToCheck[index].addEventListener('change', alertForm);
}
buttonSubmit.addEventListener('click', function() {
    window.removeEventListener('beforeunload', unloadHandler);
});

})();

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

Enabling communication between my React frontend and Express server

I currently have a Digital Ocean Ubuntu VPS set up with Apache, Node, and Mongo running. I can successfully retrieve data from my database using CURL on the server and my node backend is running on port 3000. For my React frontend, I am using Fetch and it ...

Errors in the console appear when jQuery loads HTML containing images

Whenever I attempt to load a simple piece of HTML (though some images are currently inaccessible), jQuery seems to be attempting to load them, resulting in errors in the console. Here is an example of the code: var html = $('<div>' + &apo ...

geolocation data not being updated in isolate scope binding

I'm currently facing an issue with using isolated scope in a directive. Surprisingly, everything seems to be working perfectly fine. I have set the '=' scope on two properties and successfully bind them in my template. However, when I call m ...

I'm curious why I need to add an extra await in my Vue.js unit test whenever multiple calls are made to my Firebase auth mock

In my vue.js application with firebase authentication, I encountered an issue while testing the Login.vue component. To mock firebase auth, I had to simulate the configuration file used for initializing firebase (named firebase.config). It's worth men ...

Creating a dynamic grid design with images using the <ul><li></li></ul> HTML tags

Trying to create a responsive grid of images that adapts to changes in browser size. Is there a way to achieve this using a list? Ideally, I want the images to be evenly spaced in rows. For example, if there are three rows of four images on top and one r ...

Having trouble with implementing ng-hide and ng-show functionality

I have been working on creating my very first Angular website and so far, everything has been going smoothly with the first page. However, I am facing an issue with the second page not appearing as expected when it meets the condition set with ng-show in t ...

Tips for implementing File upload with WEB API in Dot net core

Currently, I am developing an ASP DOT NET core web api that requires sending multiple attachments. My implementation looked something like this: <input type="text" id="txt_firstName" /> <input type="text" id="txt_lastName" /> <input type= ...

I'm facing an issue with my GraphQL resolvers due to a circular dependency

After modifying my repositories to directly return the GQL resolvers, everything was going smoothly until I encountered a circular dependency issue. Now, I have two repositories that rely on each other, creating a dilemma that JavaScript cannot easily reso ...

Techniques for manipulating multiple circles with JavaScript

After creating a series of circles with d3, I successfully implemented the functionality to drag individual circles and track their positions. var width= 800; var height=600; svg= d3.select("body").select(".div1").append("svg") ...

CSS border-image negative positioning (no HTML required)

We are on the lookout for a way to apply a specific border style to nearly all img tags within the content area of a CMS (such as Wordpress or Joomla). Our goal is to achieve this solely using CSS without having to access any parent tags: The initial step ...

How to utilize JS variables for filtering an array in EJS?

Is there a way to filter my user array based on the "username" variable in JavaScript? On the server side: var users = data.filter(u => u.id.startsWith('user_')).map(u => u.value); // [{"username": "arin2115", "som ...

Initiate the setInterval function upon clicking the button

Is there a way to successfully start setInterval when the user presses a button with ID #begin? I have attempted various methods, but they all seem to prevent setInterval from working at all. Any suggestions on how to make this work correctly? Thank you! ...

Exploring the Possibilities of Manipulating HTML Tables with CSS

Looking for a solution to rearrange the layout of a html table with 2 cells in a row? Want to make the second cell appear below the first one instead of next to it using only CSS? It may require a bit of a "dirty hack", but the desired outcome is still n ...

The JavaScript code in Three.js is experiencing issues when running in a secure HTTPS environment

After transitioning my website from http to https, I encountered an issue with one of my projects. The background using the Three.js library in this random generator does not show up when the URL is https. However, when the URL is http, the generator wor ...

Javascript recursive function calling itself

I've been struggling with the logic in my code and it seems like I've been staring at it for too long to spot the issue. A strange recursion occurs when this piece of code runs after a 30-second timeout, resulting in multiple GET requests to rese ...

"Enhance your web development with Vue.js and Vue-chart.js for beautiful linear

I'm currently struggling to implement a linear gradient background on my Vue-chart.js line chart. Despite searching high and low, the documentation and examples available are not proving to be helpful. After importing the Line component from vue-char ...

Utilizing external objects within the data() function of Vue: A comprehensive guide

When it comes to defining data in a Vue component, the typical approach is to use the data function as shown below: data() { return { a: 0 } } But I have a question: instead of defining the data object after return, is it possible to defin ...

The implementation of an onclick event in a freshly created HTML element is functioning solely on the final element

One issue I encountered was that when I generated page number buttons at the bottom of a page, the onclick event only worked with the last button created. Below is an example of how the page buttons were displayed: https://i.stack.imgur.com/wHwI0.png ...

Error: controller undefined

As I delve into a Coursera course on AngularJS, I've encountered a perplexing issue with a controller. The console is indicating that it is not defined. Upon running it through the https://validator.w3.org/, a recurring error message mentioning that ...

Using indented, multi-line logging in a NodeJS environment can help to

I'm looking for a way to display objects that have been printed with JSON.stringify() in the console, specifically within the context of a Mocha test suite output. While my tests are running, I want the object log lines to be indented further to the ...