In CSS Tricks (see link at the end), five ways to replace text are shown and explained. The explanations are quite indicative about the cases in which it would be convenient to use one way or another.
1. Via jQuery (Less Marked / More JavaScript)
You must save the text "swap" somewhere. I would say that in most cases it is a design / visualization concern so storage in the markup is a good idea. We will use the example of a button that exchanges text between "Hide" and "Show". A data-*
attribute is a perfectly good place to store the exchange text. So it becomes:
<button data-text-swap="Show">Hide</button>
It's easy to exchange the text in jQuery:
var button = $("button");
button.text(button.data("text-swap"));
But, if you do so, we would lose the original text forever. First we must save the original text. Another attribute data-*
will do it:
var button = $("button");
button.data("text-original", button.text());
button.text(button.data("text-swap"));
To do that in a click event, you would:
var button = $("button");
button.on("click", function() {
button.data("text-original", button.text());
button.text(button.data("text-swap"));
});
But that only goes in one direction. To complete the "exchange", we will have to compare the current text value of the button to see if it matches the exchange text or not. If it does, switch back to the original. If not, to the exchange text:
$("button").on("click", function() {
var el = $(this);
if (el.text() == el.data("text-swap")) {
el.text(el.data("text-original"));
} else {
el.data("text-original", el.text());
el.text(el.data("text-swap"));
}
});
2. Via jQuery (More Marked / Less JavaScript)
If we are willing to establish that data-original-text value in the original markup, we can simplify the JavaScript a bit. We can use a single ternary operator to check if the exchange matches the original and perform the correct action based on truthfulness.
$("button").on("click", function() {
var el = $(this);
el.text() == el.data("text-swap")
? el.text(el.data("text-original"))
: el.text(el.data("text-swap"));
});
3. Vía Vanilla JavaScript
I'm guilty of using too much jQuery around here for things that can be done without it. This is what the first version of "less marked" would look like in "raw" JavaScript:
var button = document.querySelectorAll("button")[0];
button.addEventListener('click', function() {
if (button.getAttribute("data-text-swap") == button.innerHTML) {
button.innerHTML = button.getAttribute("data-text-original");
} else {
button.setAttribute("data-text-original", button.innerHTML);
button.innerHTML = button.getAttribute("data-text-swap");
}
}, false);
4. Via CSS (with jQuery changing class names)
Since this is a vision concern and could be considered a "state", a popular idea is to use JavaScript only to change the classes that represent states and let CSS define what visual change really is.
We could use the class "on" to represent the state of exchange. Then that class would apply a pseudo element that covered the old word and replace it with the word swap. I do not think that the real button elements with default browser style take well to pseudo element so let's use an anchor here.
a {
position: relative;
}
a.on:after {
content: "Hide";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: white;
}
This is a bit funky, to be fair. I think this is almost worse than putting the exchange word in the JavaScript. CSS is not really for this kind of thing and probably has some accessibility concerns.
This also happens because the word "Hide" is smaller than "Show" a little. If the word swap was larger, the original would come out below the white cover. It might be able to prevent the inline blocking of the original, hiding the overflow, and kick the original of the box with the indent text. But the fact that the replacement word is in absolute position removes it from the flow, which could be a problem, not to mention the real world design is not always as simple as flat-color-on-flat-color.
5. Via only CSS
But hey, as long as we're getting funky, we could use the Checkbox Hack here to make the text exchange completely CSS. The replacement happens in exactly the same way, it only happens when an invisible checkbox just before the word is: checked or not. This means that the word must also be in a tag, which can change the status of the check box through the for attribute.
HTML:
<input id="example-checkbox" type="checkbox">
<label for="example" id="example">Show</label>
CSS:
#example {
position: relative;
}
#example-checkbox {
display: none;
}
#example-checkbox:checked + #example:after {
content: "Hide";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: white;
}
Fragments of code with the five tracks
$("#example-one").on("click", function() {
var el = $(this);
el.text() == el.data("text-swap")
? el.text(el.data("text-original"))
: el.text(el.data("text-swap"));
});
$("#example-two").on("click", function() {
var el = $(this);
if (el.text() == el.data("text-swap")) {
el.text(el.data("text-original"));
} else {
el.data("text-original", el.text());
el.text(el.data("text-swap"));
}
});
var button = document.getElementById("example-three");
button.addEventListener('click', function() {
if (button.getAttribute("data-text-swap") == button.innerHTML) {
button.innerHTML = button.getAttribute("data-text-original");
} else {
button.setAttribute("data-text-original", button.innerHTML);
button.innerHTML = button.getAttribute("data-text-swap");
}
}, false);
$("#example-four").on("click", function() {
$(this).toggleClass("on");
});
body {
padding: 0px 10px 10px 10px;
}
#example-four {
position: relative;
}
#example-four.on:after {
content: "Hide";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: white;
text-decoration: underline;
}
#example-five {
position: relative;
}
#example-five-checkbox {
display: none;
}
#example-five-checkbox:checked + #example-five:after {
content: "Hide";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>1. Vía jQuery (más marcado / menos javascript)</h2>
<button id="example-one" data-text-swap="Show" data-text-original="Hide">Hide</button>
<h2>2. Vía jQuery (menos marcado / más javascript)</h2>
<button id="example-two" data-text-swap="Show">Hide</button>
<h2>3. Vía Vanilla JS</h2>
<button id="example-three" data-text-swap="Show">Hide</button>
<h2>4. Vía CSS con cambio de clase desde jQuery</h2>
<a id="example-four" href="#0">Show</a>
<h2>5. Vía CSS solamente</h2>
<input type="checkbox" id="example-five-checkbox" />
<label id="example-five" for="example-five-checkbox">Show</label>
Links: