Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

137
Views
Constantly waiting for a click (regardless of changes to the DOM or other clicks)

The problem I have is with the jQuery datepicker. Execution of my function happens on the click of a certain date. The problem occurs when the month changes, then the entire datepicker is deleted from the DOM and a new datepicker appears.

My solution (bad solution) is with a constant wait for the arrow to change DOM, when that happens then I start further execution of the script. The biggest problem I have is performance, because I use interval.

enter image description here

This is my example of a solution that works, but barely...

$('#input-for-opening-datepicker').on('click', function(){
    // In my attempt to solve the problem it is necessary to use an interval 
    // because without it the program does not see the change of the month 
    // and does not catch a click on the date.
    setInterval( function(){
        const arrows = $('.datepick-arrows');

        // If arrows exist in DOM, wait for the click
        if (arrows.length > 0){
            arrows.on('click', function(){
                // ... then wait for the date click to continue executing the code
                $('.datepick-month table tbody tr td a').on('click', function() {
                    // Code...
                });
            });

            // If you do not click on the change of the month, and the date picker 
            // is open then wait again for the click of a certain date because the 
            // change of the month does not have to happen by the user.
            $('.datepick-month table tbody tr td a').on('click', function() {
                // Code...
            });
        }
    }, 200);
});

How do I achieve script execution without using an interval that greatly affects performance?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Hooking up event handlers in response to an event is usually not best practice, and hooking them up in an interval timer is definitely not best practice. Your code is repeatedly re-hooking the events (even on the same elements).

Instead, two options for you:

Event Delegation

If the datepicker doesn't cancel propagation (bubbling) of the click events, you can use event delegation:

document.addEventListener("click", function(event) {
    const arrow = event.target.closest(".datepick-arrows");
    if (arrow) {
        // Click on a datepicker arrow

        // ...do what you do on arrow click...

        return;
    }
    const month = event.target.closest(".datepick-month table tbody tr td a");
    if (month) {
        // Click on a month

        // ...do what you do on month click...

        return;
    }
});

MutationObserver

If the datepicker does stop propagation, the delegation approach won't work. In that case, you can use a MutationObserver to watch for the date picker being added to the DOM and hook up your handlers (probably using a WeakSet to remember the ones you know you've hooked up events on).

// A weak set of known date pickers
const knownDatePickers = new WeakSet();
// The observer
const observer = new MutationObserver(function(mutations) {
    // Or you could look through `mutations` for the datepicker
    const datePicker = document.querySelector("selector for the datepicker");
    if (datePicker && !knownDatePickers.has(datePicker)) {
        knownDatePickers.add(datePicker);
        // ...hook up your datepicker events here...
    }
});
observer.observe(document.documentElement, {
    attributes: false,
    childList: true,
    subtree: true
});

Or you could avoid the need for the WeakSet by looking in the newly-added notes in the mutation record:

const observer = new MutationObserver(function(mutations) {
    let added = null;
    let removed = null;
    for (const mutation of mutations) {
        for (const node of mutation.addedNodes) {
            if (node.matches && node.matches("selector for datepicker") {
                added = node;
                break;
            }
        }
        for (const node of mutation.removedNodes) {
            if (node.matches && node.matches("selector for datepicker") {
                removed = node;
                break;
            }
        }
    }
    if (added && added !== removed) {   // If you *move* an element, it appears in
                                        // both `addedNodes` and `removedNodes`
        // `added` is a new datepicker, set up your event handlers
    }
});
observer.observe(document.documentElement, {
    attributes: false,
    childList: true,
    subtree: true
});

Both listed options are directions to go, not copy-and-paste solutions. You'll have to fill in the blanks and tweak the code as needed.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!