0

i have thousands of divs with hundreds of descendants inside, so i want to select one or more with removeeventlistener. Simply want to choose who listens to the event inside a div with descendant elements,for example:

I want to select that the input and the textarea cannot listen to the click event with removeeventlistener, but the div and the p tag do listen or that only the textarea listens and the others don't

<style>
        .frame {
            width: 300px;
            height: 300px;
            background-color: brown;
            
        }
        
        input {
            margin: auto;
            
        }
        
        p {
            font: bold 200% roboto;
            text-align: center;
            
        }
</style>
<body>
    
<div class="frame">
    
    <input placeholder="">
    <textarea></textarea>
    <p>THIS IS P TAG</p>
div area    
</div>

<div class="frame">
    
    <input placeholder="">
    <textarea></textarea>
    <p>THIS IS P TAG</p>
div area    
</div>

</body>
<script>
const labels = document.querySelectorAll('.frame');
        
    for (var i = 0; i < labels.length; ++i) {
  
        labels[i].addEventListener('click', function touch() {
        
            // resize div
            
            if( this.clientWidth == 300) {
                
                this.style.width = "600px";
        
                this.style.height = "600px";
                
            }else{
                
                this.style.width = "300px";
        
                this.style.height = "300px";
                
            };
            
            //remove the event
            
            this.firstElementChild.removeEventListener('click', touch);
            
            //document.querySelectorAll('input').removeEventListener('click', touch);
            
        });
    };
</script>

DEMO

Table
  • 11
  • 7
  • 1
    Before doing anything else, please see [what is event delegation](https://stackoverflow.com/questions/1687296/what-is-dom-event-delegation). Notice, that you haven't set (not in the example at least) any listeners to the children of the `.frame`s, hence you can't remove them either. The linked post explains how the events are bubbling through the document. – Teemu Oct 07 '22 at 12:22
  • Teemu how to simply select one descendant element among thousands that are different? – Table Oct 07 '22 at 12:30
  • @wooddocu For example specifying an [id](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id) – rajniszp Oct 07 '22 at 12:31
  • You should not attach an event listener to thousands of divs. Add a single listener to the closest parent element of the divs, then check what is clicked. `event` object passed to the event handler function contains `target` property, that refers to the actually clicked element, not to the element which the event was attached to. Then it's easy to check, if the clicked element is the one you need, see [closest](https://developer.mozilla.org/en-US/docs/Web/API/Element/closest) and [matches](https://developer.mozilla.org/en-US/docs/Web/API/Element/matches). – Teemu Oct 07 '22 at 12:34
  • To pick a textarea, probably it's easiest to use `event.target.closest('.frame').querySelector('textarea')`, providing it's the only textarea within `.frame` element. If there are more textareas, you could give a common class name for all the textareas, and use a class selector instead of the tag selector in my example above. – Teemu Oct 07 '22 at 13:06
  • Teemu after selecting them, how do i use event target in the if conditional? – Table Oct 07 '22 at 13:15
  • Teemu how would you do, to select choose with event target in an if conditional among hundreds of thousands of descendants, using the question as a model, can you give an example? – Table Oct 07 '22 at 13:37
  • Teemu can you explain it better about the if conditional in an answer? – Table Oct 07 '22 at 13:43
  • Well, take a look at [this jsFiddle](https://jsfiddle.net/8x7czp5v/), maybe it helps ..? – Teemu Oct 07 '22 at 13:55
  • [Another example](https://jsfiddle.net/8x7czp5v/2/) using `matches`. This should work exactly like you've described in your question. Notice, the example uses tag selectors, if there are hundreds of elements inside `.frame` element, I'd recommend you to give a class to the target elements and use class selectors instead of tag selectors. – Teemu Oct 07 '22 at 14:19
  • Teemu thanks for your help, do you know how to simplify your code more, similar to putting a single removeEventListener and the stop listening element, similar to what is proposed in my code? – Table Oct 07 '22 at 15:03
  • Simplify three lines of code? As I've said before, removing event listener from the children is not possible, because there are no listeners to remove. When you attach a click listener to `.frame` element (or to its parent), any element inside the div will fire the event when you click on it. That is called event bubbling. It's possible to make tricks with CSS and `pointer-events` property, but it has limited use-cases, and needs much more code, as it's just like an addition to my example code. – Teemu Oct 07 '22 at 15:14
  • Teemu yes, simpler, but three lines is succes, how would you use these three lines inside the for loop, can you give me an example in a reply answer? – Table Oct 07 '22 at 15:51
  • You don't need a for loop, only you need is that single event handler. Please read the post I linked in my first comment. – Teemu Oct 07 '22 at 15:57
  • Teemu i have read the post. What you say and what the article says, is more efficient than assigning the click event handler and a function that changes hundreds of properties to each of the thousands of divs, going through them with a for loop in one go? – Table Oct 07 '22 at 17:44
  • Teemu the question doesn't say remove the loop, how would you do it with those three lines inside the for loop? – Table Oct 07 '22 at 18:04
  • It's not just "more efficient" when you've thousands of giant elements to listen to, it's a must, your page will probably freeze because of thousands of event listeners. – Teemu Oct 09 '22 at 13:39

0 Answers0