3

Supposed I have a node that looks like this

<a>
  <span class="glyphicons glyphicons-collapse"></span>Collapse All
</a>

And I want to toggle it to this

<a>
  <span class="glyphicons glyphicons-expand"></span>Expand All
</a>

If I use innerHTML or innerText or textContent it just replaces the text. My first pass at a solution is

function toggleLastTextNode(element, textWhenTrue, textWhenFalse, value) {
  element.removeChild(obj.childNodes[1]);
  element.insertAdjacentHTML("beforeend", value ? textWhenTrue: textWhenFalse);
}

As I know where the text is, it's always the obj.childNodes[1] so I just remove it and replace it. The function call would be something like this

toggleLastTextNode(element,"Expand","Collapse",true)

With the current HTML is there a better way to do this? I want to avoid innerHTML if I can.

3
  • If you're not dealing with several languages, a CSS pseudo-element ::before or ::after might also do the trick, leaving that semantically useless text out of your HTML Commented May 6, 2015 at 12:26
  • Thanks for the tip that looks like a nicer solution, I guess something like a css3 toggle switch? Commented May 6, 2015 at 12:39
  • I made it an answer as an alternative. Working through the classes has the advantage of letting you switch text and image/whatever style at the same time, while the other way you need to address those changes in several instructions. I made it in jQuery for quick response, but it can also be done in vanillaJS Commented May 6, 2015 at 12:44

3 Answers 3

6

How about

document.getElementById('elementid').firstChild.nodeValue = new_text;

innerHTML has side effects (like disconnecting existing DOM nodes and rerendering that might be heavy).

Sign up to request clarification or add additional context in comments.

1 Comment

Very nice, that's exactly what I was looking for and that's why I was trying to avoid innerHTML, thanks!
2

Nowadays when I'm confronted with this kind of functionality I always try to look at semantic, removing everything which is not content. In this case, you could leave the text in the CSS as it is kinda part of the UX/UI rather than content (a screen reader shouldn't "read" this for example, Google search bot neither, it can't do anything useful with that content). In your case, not changing the HTML (that might also probably be shortened, I come to a solution like this :

HTML (almost same as yours, added href attribute) :

<a href="#">
  <span class="glyphicons glyphicons-collapse"></span>
</a>

CSS :

.glyphicons-collapse::after{content: 'Collapse All'}
.glyphicons-expand::after{content: 'Expand All'}

JS (jquery) :

$('a').on('click','.glyphicons-collapse',function(e){
    e.preventDefault();
    $(this).removeClass('glyphicons-collapse');
     $(this).addClass('glyphicons-expand');
});

$('a').on('click','.glyphicons-expand',function(e){
     e.preventDefault();
    $(this).removeClass('glyphicons-expand');
     $(this).addClass('glyphicons-collapse');
});

And the fiddle with all that in it

1 Comment

Thanks, I've taken this approach (for the css) even though I accepted the other answer. I'm using function that uses classList.toggle and considering a shim to so I can use the version that allows a second parameter.
2

define your html content with id

<a id="glyphicons">
  <span class="glyphicons glyphicons-collapse"></span>Collapse All
</a>

then toggleExpandCollapse()

var toggleExpandCollapse = function () {
    var oElements = document.getElementById('glyphicons').childNodes;
    if (oElements[1].className === "glyphicons glyphicons-collapse") {
        oElements.childNodes[2].nodeValue = "Expand All";
        oElements[1].className = "glyphicons glyphicons-expand"
    } else {
        oElements.childNodes[2].nodeValue = "Collapse All";
        oElements[1].className = "glyphicons glyphicons-collapse"
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.