Stop applying a certain class to a parent of an event target

44 views Asked by At

I am practising event delegation and I stumbled upon this. I have 4 paragraphs setting inside an article tag which sits in a div. I want to apply a .green class that changes background of each paragraph ONLY when I click on it. However the green class gets only applied up to the parent (article) and the grandparent (div) as well. Tell me what's wrong with my code please.

function paintParagraph(e) {
    if (!e) {
        e = window.event;
    }
    var target, parent;
    target = e.target || e.srcElement;
    parent = target.parentNode;
    parent.className = 'green';
    e.stopPropagation();
    
}

var paragraphList = document.querySelector('#p-list');
paragraphList.addEventListener('click', function(e) {

paintParagraph(e);

}
, false);
    p {
        padding: 10px;
        margin: 20px;
        border: 2px solid;
        line-height: 1.5em;
        letter-spacing: 0.2em;
        text-align: center;
    }

  .green {
        background-color: green;
    }
<div id="main">
        <article id="p-list">
            <p class="para">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Vitae perferendis culpa velit excepturi iste reprehenderit quaerat debitis repudiandae itaque beatae. Numquam dolorum ducimus iusto temporibus facilis error possimus amet, illo.</p
            ><p class="para2">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Vitae perferendis culpa velit excepturi iste reprehenderit quaerat debitis repudiandae itaque beatae. Numquam dolorum ducimus iusto temporibus facilis error possimus amet, illo.</p
            ><p class="para3">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Vitae perferendis culpa velit excepturi iste reprehenderit quaerat debitis repudiandae itaque beatae. Numquam dolorum ducimus iusto temporibus facilis error possimus amet, illo.</p
            ><p class="para4">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Vitae perferendis culpa velit excepturi iste reprehenderit quaerat debitis repudiandae itaque beatae. Numquam dolorum ducimus iusto temporibus facilis error possimus amet, illo.</p
        ></article>
    </div>

2

There are 2 answers

11
Deep On BEST ANSWER

You should check if the clicked target is p then only proceed further.

if(target.nodeName !== "P") return false;

Now you will have only p element as the target apply the class on it.

 target.className = 'green';

function color(elem) {
  if (elem.nodeName == "P") {
    elem.className = 'green';
  }

  if (elem.parentNode !== null) {
    color(elem.parentNode)
  }
}



function paintParagraph(e) {
  if (!e) {
    e = window.object;
  }
  var target, parent;
  target = e.target || e.srcElement;
  color(target)

}

var paragraphList = document.querySelector('#p-list');
paragraphList.addEventListener('click', function(e) {

  paintParagraph(e);

}, false);
p {
  padding: 10px;
  margin: 20px;
  border: 2px solid;
  line-height: 1.5em;
  letter-spacing: 0.2em;
  text-align: center;
}
.green {
  background-color: green;
}
<div id="main">
  <article id="p-list">
    <p class="para">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Vitae perferendis culpa velit excepturi iste reprehenderit quaerat debitis repudiandae itaque beatae. Numquam dolorum ducimus iusto temporibus facilis error possimus amet, illo.</p>
    <p class="para2">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Vitae perferendis culpa velit excepturi iste reprehenderit quaerat debitis repudiandae itaque beatae. Numquam dolorum ducimus iusto temporibus facilis error possimus amet, illo.</p>
    <p class="para3">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Vitae perferendis culpa velit excepturi iste reprehenderit quaerat debitis repudiandae itaque beatae. Numquam dolorum ducimus iusto temporibus facilis error possimus amet, illo.</p>
    <p class="para4">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Vitae perferendis culpa <span> HELLO</span>velit excepturi iste reprehenderit quaerat debitis repudiandae itaque beatae. Numquam dolorum ducimus iusto temporibus facilis error possimus amet,
      illo.</p>
  </article>
</div>

0
German On

As far as I understand you want the <article> element to have class .green only when user click <p> element if this is true, then this is my answer.

In this case I reference the <p> elements instead of the <article> element.

function paintParagraph(e) {
  if (!e) {
    e = window.event;
  }
  const { target, srcElement } = e;
  parent = target.parentNode;
  parent.className = 'green';
  e.stopPropagation();
}

var paragraphList = document.querySelectorAll('#p-list > p');
paragraphList.forEach((element) => {
  element.addEventListener('click', paintParagraph, false);
});