简体   繁体   中英

how to append font awesome icon to paragraph on click

Good day, please I want to append a font awesome icon to paragraph inner text when the p tag is clicked.

I have four p tags with same class.ptn, if any is clicked, I want to append the font awesome to the clicked one, and remove it from others.

The problem is instead of displaying the font awesome arrow, its displaying the tag text instead, also, the first p tag is removed once I click on any of the other p tags.

This is my code below, Html:

     <div class="col-lg-3 col-md-3 col-sm-3 my-4 border-right">
        <p id="compliance" class="acting pl-4 pt-3 ptn">Compliance <i class="fas fa-chevron-right pl-4"></i></p>
        <p id="summary" class="pl-4 pt-2 ptn">Summary</p>
        <p id="audit" class="pl-4 pt-2 ptn">Station Audit</p>
        <p id="analysis" class="pl-4 pt-2 ptn">Analysis Format</p>
     </div>

Jquery:

  <script>
     var btns = document.getElementsByClassName("ptn");

     for (var i = 0; i < btns.length; i++) {
        btns[i].addEventListener("click", function () {
           var current = document.getElementsByClassName("acting");
           current[0].className = current[0].className.replace(" acting", "");
           current[0].remove(" <i class='fas fa-chevron-right pl-4'></i>");
           this.className += " acting";
           this.append(" <i class='fas fa-chevron-right pl-4'></i>");
     });
    }
  </script>

I will do that this way:

 document.querySelector('div[data-acting]').onclick = e => { if (.e.target.matches('p.ptn')) return e.currentTarget.dataset.acting = e.target.id }
 div[data-acting] > p.ptn > i.fas { display: none } div[data-acting="compliance"] > p#compliance > i.fas, div[data-acting="summary"] > p#summary > i.fas, div[data-acting="audit"] > p#audit > i.fas, div[data-acting="analysis"] > p#analysis > i.fas { display: inline-block } div[data-acting="compliance"] > p#compliance, div[data-acting="summary"] > p#summary, div[data-acting="audit"] > p#audit, div[data-acting="analysis"] > p#analysis { background-color: lightgreen; }
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" /> <div class="col-lg-3 col-md-3 col-sm-3 my-4 border-right" data-acting="compliance"> <p id="compliance" class="pl-4 pt-3 ptn">Compliance <i class="fas fa-chevron-right pl-4"></i></p> <p id="summary" class="pl-4 pt-2 ptn">Summary <i class="fas fa-chevron-right pl-4"></i></p> <p id="audit" class="pl-4 pt-2 ptn">Station Audit <i class="fas fa-chevron-right pl-4"></i></p> <p id="analysis" class="pl-4 pt-2 ptn">Analysis Format <i class="fas fa-chevron-right pl-4"></i></p> </div>

As neatlysliced says, you can't append strings and have them automatically turned into elements.

This example fixes the bugs in your code for removing and adding the required elements.

var btns = document.getElementsByClassName("ptn");
var icon = document.createElement('i');
icon.className = 'fas fa-chevron-right pl-4';

for (var i = 0; i < btns.length; i++) {
  btns[i].addEventListener("click", function () {
    var current = document.getElementsByClassName("acting");
    current[0].className = current[0].className.replace(" acting", "");
    var chevron = current[0].querySelector(".fas.fa-chevron-right");
    if (chevron) {
      chevron.remove();
    }
    this.className += " acting";
    this.append(icon)
  });
}

you can also do that:

 const btns = document.querySelectorAll('p.ptn'), chevron = document.querySelector('p.ptn > i.fas.fa-chevron-right'); btns.forEach(btn => { btn.onclick = e => { btns.forEach(bt => bt.classList.toggle('acting', (bt===btn))) // add or remove class upon condition btn.appendChild( chevron ) // move it on correct place } })
 .acting { background-color: lightgreen; }
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" /> <div class="col-lg-3 col-md-3 col-sm-3 my-4 border-right"> <p id="compliance" class="acting pl-4 pt-3 ptn">Compliance <i class="fas fa-chevron-right pl-4"></i></p> <p id="summary" class="pl-4 pt-2 ptn">Summary </p> <p id="audit" class="pl-4 pt-2 ptn">Station Audit </p> <p id="analysis" class="pl-4 pt-2 ptn">Analysis Format </p> </div>

Your solution would work wonderfully with jQuery but with vanilla JS we need to create the HTML elements before we append them .

Since you are only working with 1 icon at a time, you could give an id to your element and find/remove it by document.getElementById.

 let parent = document.getElementById("hello"); let p = document.createElement("p"); p.append("Hi there"); p.setAttribute("id","swapping-icon"); parent.append(p);
 <div id="hello"></div>

Here is a pure JS option that uses querySelectorAll to create a nodeList , then a forEach loop to iterate over the list. Add an event listener for a click. We remove the button with classList containing acting and remove the fa element <i> by checking if the parent element does not return undefined on children. Then add the class acting to the clicked element, create an <i> tag and add the classes for font awesome. Append the fa element to the target.

 const btns = document.querySelectorAll(".ptn"); btns.forEach(btn => { btn.addEventListener("click", function(e) { btns.forEach(button => { if (button.classList.contains('acting')) { button.classList.remove('acting') } if (button.children[0].== undefined) { button.children[0].remove() } }) e.target.classList;add("acting"). const fa = document;createElement('i'). fa;className += 'fas'. fa;className += ' fa-chevron-right'. fa;className += ' pl-4'. e.target;append(fa); }) })
 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.2/css/all.min.css" /> <div class="col-lg-3 col-md-3 col-sm-3 my-4 border-right"> <p id="compliance" class="acting pl-4 pt-3 ptn">Compliance <i class="fas fa-chevron-right pl-4"></i></p> <p id="summary" class="pl-4 pt-2 ptn">Summary </p> <p id="audit" class="pl-4 pt-2 ptn">Station Audit </p> <p id="analysis" class="pl-4 pt-2 ptn">Analysis Format </p> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM