Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to make Javascript "focusout" event only fire once?

Here is my current function:

document.getElementById('textarea').addEventListener('focusin', () => {
    document.getElementById('UserTextArea').classList.add('text-selected');
    document.getElementById('textarea').style.marginBottom = "0px";

    document.getElementById('textarea').addEventListener('focusout', () => {
    let CommentText = document.querySelector('.textarea').innerText;
    chrome.storage.local.set({SavedComments: CommentText}, function() {
    });
});
});

It works, and it’s functional. However as is made clear when I insert some "alert(‘hello world’)"s in there to test it out? The "focusout" event doesn’t just fire once. It fires at least a few times, sometimes a very large number of times. The program works, and the functionality is there — however a concern I have is, as I add more and more features to the application, this poorly written code will cause some issues to emerge.

Upon further inspection, the way this is written? It seems increment the event listener each time. So each time the person focuses in on the textbox, then focuses out? It fires the accompanying function one additional time. So after focusing in and out 13 times, it will fire 13 in a row. On the 20th time, 20 times in a row, etc.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

What’s the cleanest way to make a "focusout" event only fire once?

Thanks!

>Solution :

It seems increment the event listener each time.

Exactly – an event listener for focusout gets added each time focusin fires, and never gets removed.

Keep just one listener for each event at all times:

document.getElementById('textarea').addEventListener('focusin', () => {
    document.getElementById('UserTextArea').classList.add('text-selected');
    document.getElementById('textarea').style.marginBottom = "0px";
});

document.getElementById('textarea').addEventListener('focusout', () => {
    let CommentText = document.querySelector('.textarea').innerText;
    chrome.storage.local.set({SavedComments: CommentText}, function() {
    });
});

Also, if .textarea is a <textarea>, you want .value, not .innerText. (And is textarea both its id and class?)

Separately, consider using CSS to apply the margin change if it wasn’t intentional that you didn’t remove it in focusout:

#textarea:focus {
    margin-bottom: 0px;
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading