简体   繁体   中英

JavaScript: Add Event Listener to an Event Listener

I am working with ChartJS. I have a onClick function defined for the chart which changes the data for the chart and calls an update() function. It looks like the chart does not actually fully update until the onClick function has finished, so there is not way for me to access the new data in the chart in the onClick handler.

I am hoping there is a way to add an event handler on that onClick event handler, but I can't figure out how to do it. I tried adding a separate onClick event handler, but it looks like they run asynchronously, and I can't figure out a way to guarantee that the onClick event handler that is changing and updating the chart finishes first. Ideally, I would be able to create an event handler on the chart's event handler, but I don't know how to do that.

I found a similar question asked some years back, but it looks like they might have been able to add an event handler to their event handler because it was a custom event, and wasn't just 'click'. Does anyone know of a good solution to this?

function chartOnClickHandler(e) {
    if (e.native.detail !== 2) return;     // if not double click return
    if (e.native.target.style.cursor === 'default') {
        handleDoubleClickAddPoint(e);
    }
    else if (e.native.target.style.cursor === 'grab'){
        handleDoubleClickRemovePoint(e);
}

} // I want to run code here, after chartOnClickHandler has finished executing. 

// Below is my second event listener. Ideally, I could call the passed in function 
// whenever chartOnClickHandler is called. 
chartElement.addEventListener('chartOnClickHandler', (e) => {
    // Handle event

});

99% chance this doesn't work so please someone kindly correct it so it works. Also I feel like this is not even on the right track.

function chartOnClickHandler(e) {
    return new Promise((res, rej)=>{
        if (e.native.detail !== 2) rej(0); // arbitrary reject value
        if (e.native.target.style.cursor === 'default') {
            res(handleDoubleClickAddPoint(e));
        }
        else if (e.native.target.style.cursor === 'grab'){
            res(handleDoubleClickRemovePoint(e));
        }
    })
}

function handleSynchronously(e) {
    chartOnClickHandler(e).then(
        // do synchronous stuff here
    );
}

I think I found a simple way around my issue. Instead of adding an event listener that waits for the function to finish, I found a way to mess around with the event queue. Using either queueMicrotask() or setTimeout() , I am able to add a function to the event queue that comes after the current running event.

Update: I ended up going with setTimeout(function, 1000) because I have to wait for the Chart's animation to end to properly get the data I need.

function chartOnClickHandler(e) {
    if (e.native.detail !== 2) return;     // if not double click return
    if (e.native.target.style.cursor === 'default') {
        handleDoubleClickAddPoint(e);
    }
    else if (e.native.target.style.cursor === 'grab'){
        handleDoubleClickRemovePoint(e);
    }

    queueMicrotask( () => { 
        // Function to be run after the current task/event (chartOnClickHandler)
    });

    setTimeout( () => { 
        // Function to be run after the current task/event (chartOnClickHandler)
    }, 0);     // timeout can be 0, since we don't care about delay time, just to push the event down in the event queue.

} // Queued function will run here, after chartOnClickHandler has finished executing. 


// Below event handler is not needed and can be removed. 
chartElement.addEventListener('chartOnClickHandler', (e) => {
    // This event handler is not needed anymore
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM