Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

143
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda