+ 8

Solved:Is there a way to disable click on an element with an event listener without removing the event listener or flags & if's?

I have a group of elements that can be clicked. But once clicked, I don't want them clicked again. I have a bunch of flags and if's but it seems an ugly solution. Removing and adding the event listeners is also ugly. Is there a better way?

9th May 2019, 1:41 PM
Paul K Sadler
Paul K Sadler - avatar
23 odpowiedzi
+ 7
Have you tried using the line below? event.preventDefault(); Where event is provided as an argument in your click handler.
9th May 2019, 1:43 PM
David Carroll
David Carroll - avatar
+ 6
Hmm... Something isn't right about that. Can you share the code?
9th May 2019, 1:48 PM
David Carroll
David Carroll - avatar
+ 6
In addEventListener, add an option, object 'once' set to true, would make the event only fire once. target.addEventListener('click', eventMethod, { once: true } );
9th May 2019, 4:44 PM
Calviղ
Calviղ - avatar
+ 5
Paul K Sadler BTW... I just saw your followup question from earlier. I'm responding to that now... Without knowing more about the code and markup, it's hard for me to say what the issue is with e.preventDefault() in your code. I can mess around with a version of what I believe you described and try to replicate the issue. However, I'd be guessing and I would likely implement my code much differently. If you can publish what you have in Code Playground, that would be much easier to work with. Otherwise, no biggie. 😉
9th May 2019, 9:34 PM
David Carroll
David Carroll - avatar
+ 4
In addition to Biraj's solution for removing named event listener with removeEventListener() method, here is how you can remove anonymous event listener: https://code.sololearn.com/W6NpiFj2L4kt/?ref=app However, an advanced solution will be to refrain from adding event listener to each element one by one. A simple solution is using event delegation, and dataset. Here is a small demo: https://code.sololearn.com/WKip4OTCKHdd/?ref=app
9th May 2019, 2:11 PM
Gordon
Gordon - avatar
+ 4
I have a memory card game. As you click pairs of cards I check to see if they match or not. The card deck is a <ul> and the cards are <li> I have moved the event lister up to the parent as it is a less ugly and I get the events when they bubble up. deck.addEventListener('click', function(event) { if(!gameTimerIntervalID) { gameTimerIntervalID = window.setInterval(() => { seconds += 1; displayTimer(timer); }, 1000); } if(event.target.nodeName === 'LI') { // Let's flip the cards and have a look if(event.target.classList.contains('match') || event.target.classList.contains('open') || event.target.classList.contains('show')) { } else { event.target.classList.add('open', 'show'); openCards.push(event.target); if(openCards.length === 2) { Basically here, after two cards are open, I don't want the cards in the deck clicked until they are processed.
9th May 2019, 2:12 PM
Paul K Sadler
Paul K Sadler - avatar
+ 4
here your click do two things. you should separate them. your trigger timer should be one single named function and be remove with Biraj's way. for the rest, put it as one anonymous function, only the outmost if else is checking whether openCards length. Your classList statements should be in the code block when openCards has less than two elements. you'll also need a setTimeout for your code block where openCards does have two elements.
9th May 2019, 2:18 PM
Gordon
Gordon - avatar
+ 4
Paul K Sadler Sorry for going MIA on you. I got slammed with work. I reviewed your followup and now have a better understanding of what you were asking. It sounds like you've gotten several people to help... so I'm glad that worked out! 👍
9th May 2019, 9:22 PM
David Carroll
David Carroll - avatar
+ 4
If it hasn't been suggested yet, maybe add the 'disabled' attribute after the event has fired. Here's a quick example using jquery. https://code.sololearn.com/Wl7eqc5ttR8t/?ref=app The disabled attribute will suffice, but removing the click event as well just to show you what that looks like. Doing one or the other works.
9th May 2019, 10:36 PM
Mike
Mike - avatar
+ 4
Paul K Sadler no prob... it'll work on other elements too. Just do the .off instead of disabling. Mind you, I really should stop using jQuery lol
10th May 2019, 12:00 AM
Mike
Mike - avatar
+ 3
David Carroll Biraj Gordon Thank you for all the input, this is Awesome! I like @Biraj suggestion on the CSS. I am going to add a class to disallow the pointer on the deck using a class to set the pointer event to none. Reading about it on MDN. Thanks again guys this was very helpful. [EDIT] trying to type on the phone in that tiny box at the bottom is a challenge.
9th May 2019, 2:24 PM
Paul K Sadler
Paul K Sadler - avatar
+ 3
Biraj That worked! After talking myself through how I wanted it to work once two cards were clicked I realized I could just set it on the deck. The result was far more elegant than what I was doing. if(openCards.length === 2) { deck.classList.add('no-click'); ... The CSS is .no-click { pointer-events: none; }
9th May 2019, 3:58 PM
Paul K Sadler
Paul K Sadler - avatar
+ 3
Thanks again everyone! 😁
9th May 2019, 4:08 PM
Paul K Sadler
Paul K Sadler - avatar
+ 3
David Carroll I wonder if the issue with event.preventDefault(); was being on the child rather than the parent? What I read on MDN seemed to make me think it would stop the bubble up, but that didn't happen. I will read some more, because, like you, I thought that would work.
9th May 2019, 4:20 PM
Paul K Sadler
Paul K Sadler - avatar
+ 3
Calviղ that's cool, I am going to try that out.
9th May 2019, 6:14 PM
Paul K Sadler
Paul K Sadler - avatar
+ 3
David Carroll I understand, thanks for following up.
9th May 2019, 9:27 PM
Paul K Sadler
Paul K Sadler - avatar
+ 3
Mike thanks for that and the demo. I'm using a ul/li in this case and not a button. But I will keep it in mind for future use. Thanks again!
9th May 2019, 11:56 PM
Paul K Sadler
Paul K Sadler - avatar
+ 2
David Carroll I did, but that did not do the trick. Using flags and if's made it work and so did pulling the event listener. Just seemed convoluted.
9th May 2019, 1:46 PM
Paul K Sadler
Paul K Sadler - avatar
+ 2
David Carroll Thanks, what you all came up with is working, so I would rather call on your time when I am stuck 🙃
9th May 2019, 9:35 PM
Paul K Sadler
Paul K Sadler - avatar