Event running more than once when using keyboard shortcuts

Hello everybody! In my plugin, I noticed strange behavior when trying to run events using keyboard shortcuts. I notice that whether in development mode with DT or when restarting Photoshop, when I request the event, it is executed more than once in just one request, it’s like every time I request the event, it is executed in same number of requests in one. In summary: If I click on the button for the first time, the event is executed correctly, if I click on the button for the second time, the same event is executed twice and so on until I reload the plugin via DT or restarting PS.


Script:

    const inciarD7 = document.querySelector("#serv-btn5");
    inciarD7.addEventListener("click", async (event) => {
        if (event.altKey || event.metaKey) { presetsQKBsize()} 
        else { process = true; await incialConfigs() ;}
    });

    async function presetsQKBsize(){
        document.querySelector("#serv-btn5SM").style.display="flex";
        ////////QCABEÇA P
        document.querySelector("#serv-btn5P").addEventListener("click",  () => {
            document.querySelector("#serv-btn5SM").style.display="none";
            docEstampa(396.7, 510.1, "Quebra-Cabeça P")
        });
        ////////QCABEÇA M
        document.querySelector("#serv-btn5M").addEventListener("click",  () => {
            document.querySelector("#serv-btn5SM").style.display="none";
            docEstampa(551.5,780.1, "Quebra-Cabeça M");
        })
        ////////QCABEÇA G
        document.querySelector("#serv-btn5G").addEventListener("click",  () => {
            document.querySelector("#serv-btn5SM").style.display="none";
            docEstampa(776.5, 1130.4, "Quebra-Cabeça G")
        })
    }

I use this event at least 7 times a day. It’s horrible having to restart Photoshop every time.

This might likely not be related, but looking over your code I noticed that you’re calling presetsQKBsize without awaiting its return, which I wonder if that’s intentional given you’ve declared that function as asynchronous.

The way I would go about debugging this is to log how often addEventListener is getting called for a particular button. I’m suspicious about whether it’s getting called in the process of a button callback. And you’re saying this only happens in development mode, not in production code?

1 Like

Looking at the code, it is possible that the event is being added each time it is executed.

It may be necessary to addEventListener to the element only once at startup, or to remove the event each time after it is executed.

1 Like

Exactly what @sttk3 said. With every Alt + click on #serv-btn5 you’re attaching event listeners to all 3 other buttons under it. Based on your given code, it makes sense events are triggered as many times as you have clicked on #serv-btn5 before that. Either attach events only once or don’t use them at all and simply on each click execute

docEstampa(551.5,780.1, "Quebra-Cabeça M")
2 Likes

Hello @dotproduct, @sttk3 e @Karmalakas, thank you for sharing your knowledge and hopes with my case, I apologize for the late response. I am carefully reading and re-reading all the observations and suggestions from friends, I think I already have some keywords that will lead me to a palliative or definitive solution. I will come back here today and share the result.

Everyone was correct. The solution is to remove the “removeEventListener()” event handlers before adding new ones. Thanks everyone for pointing me in the right direction.

const inciarD7 = document.querySelector("#serv-btn5");
    inciarD7.addEventListener("click", async (event) => {
        if (event.altKey || event.metaKey) { presetsQKBsize()} 
        else { process = true; await incialConfigs() ;}
    });

    function presetsQKBsize() {
         document.querySelector("#serv-btn5SM").style.display="flex";
        //////// REMOVE PREVIOUS EVENT HANDLERS IF THEY EXIST
        document.querySelector("#serv-btn5P").removeEventListener("click", setingPClick);
        document.querySelector("#serv-btn5M").removeEventListener("click", setingMClick);
        document.querySelector("#serv-btn5G").removeEventListener("click", setingGClick);
        //////// ADD EVENT HANDLERS FOR EACH BUTTON
        document.querySelector("#serv-btn5P").addEventListener("click", setingPClick);
        document.querySelector("#serv-btn5M").addEventListener("click", setingMClick);
        document.querySelector("#serv-btn5G").addEventListener("click", setingGClick);
    }

    function setingPClick() {
        document.querySelector("#serv-btn5SM").style.display = "none";
        docEstampa(396.7, 510.1, "Quebra-Cabeça P");
    }

    function setingMClick() {
        document.querySelector("#serv-btn5SM").style.display = "none";
        docEstampa(551.5, 780.1, "Quebra-Cabeça M");
    }

    function setingGClick() {
        document.querySelector("#serv-btn5SM").style.display = "none";
        docEstampa(776.5, 1130.4, "Quebra-Cabeça G");
    }

Sorry, but for me (and probably some others) this kind of logic doesn’t make sense. Why wouldn’t you attach these event listeners only once elsewhere? You could do it even on panel load and forget. Maybe I don’t know something, but this looks so wrong…

2 Likes

Great observation! It’s a good thing to be surrounded by qualified people, I recognize that I’m not a programming professional, I don’t make plugins to sell, this is just a great option to create my own automation tools for my workflow, as for the logic I used, if it makes sense or not, it worked well for me, I had to turn around, look for a solution, I don’t feel comfortable asking someone to come here and write snippets of code, I’m here to learn. @Karmalakas you suggested, “I could do this even by loading the panel and forget about it”, it seems like a good approach, feel free to share your logic in practice, it would be much appreciated, we have enough arguments in the code above.
I’ll deselect the correct answer and reserve it for your method.