skip to Main Content

What is the correct way to overwrite the text in an anchor element without losing the stored icon?

My current solution changes the text value, but the icon next to it is lost.

This is the element (assembled button):

  <a id="btn_lang" class="lang_btn"> <i class="fa fa-commenting-o"></i>&nbsp; Verfügbare Sprachen und Länder</a>

This is the icon-library i am using:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">

Following actions get performed, by pushing a button (my approach for changing the text):

<script>
    function AT(){
        document.getElementById("btn_lang").innerHTML = "changed value";
    }
</script>

Appearance before pushing the button:

enter image description here

Appearance after pushing the button (-> text gets changed, but icon is missing):

enter image description here

If the complete HTML / CSS script is necessary, I can submit it later (I have reduced it to the code lines listed for better clarity).

Do I have to define the icon again when using .innerHTML?

2

Answers


  1. Problem is you are setting the whole #btn_lang to your new HTML.

    Instead you could just change the html of #btn_lang > span, else you’d have to define the icon (<i>), as you already said, again.

    Here’s an example:

    <a id="btn_lang" class="lang_btn">
        <i class="fa fa-commenting-o"></i>&nbsp; 
        <span id="btn_lang_txt">Verfügbare Sprachen und Länder</span>
    </a>
    
    function AT(){
        document.getElementById("btn_lang_txt").innerHTML = "changed value";
    }
    

    If you don’t want to have an ID on your span you can simply do this:

    <a id="btn_lang" class="lang_btn">
        <i class="fa fa-commenting-o"></i>&nbsp; 
        <span>Verfügbare Sprachen und Länder</span>
    </a>
    
    function AT(){
        document.querySelector("#btn_lang > span").innerHTML = "changed value";
    }
    

    Hope this helps!

    Login or Signup to reply.
  2. Adding an extra element as suggested in this answer is certainly the easiest way to go and a very readable option, but if for whatever reason you couldn’t add an extra tag, then you can still do what you want.

    Aside from HTML tags, all bare blocks of text in a HTML DOM document are TextNode elements. If you get all nodes in the button, find the TextNode you need and then edit its text, the existing HTML (the <i>) is not affected.

    function AT() {
      const btn = document.getElementById('btn_lang');
    
      // btn.childNodes will be an array-like object with 3 entries:
      // an empty TextNode (""),
      // a HTML <i> element,
      // a TextNode with the text "Verfügbare Sprachen und Länder".
    
      // Find the first non-empty text node.
      let txt = Array.from(btn.childNodes).find(function(node) {
        // It should be a text node & it should have more than 1 non-space characters.
        return node.nodeType === Node.TEXT_NODE && node.nodeValue.trim().length;
      });
    
      // If for whatever reason, there is no text node, add one.
      if (!txt) {
        txt = document.createTextNode("");
        btn.appendChild(txt);
      }
    
      // Add a &nbsp; (unicode character 0160, in hexadecimal 00A0) + new text.
      // You must use unicode character escape sequences here (uXXXX),
      // not HTML entities (&nbsp;).
      const nbsp = "u00A0 ";
      txt.nodeValue = nbsp + "Changed value";
    }
    i:before {
      content: '💬';
      font-style: normal;
    }
    <a id="btn_lang" class="lang_btn"> <i class="fa fa-commenting-o"></i>&nbsp; Verfügbare Sprachen und Länder</a>
    
    <hr>
    <button onclick="AT()">Change</button>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search