3

I wanna know how I can change the innerHtml to switch back and forth between two states. I have this html

 <div class="test" id="test">
    <p>this is a test</p>
</div>
<p id="js" class="test" >Change</p>

and this is the JavaScript I have

let button = document.getElementById("js");

button.onclick = function() {
document.getElementById("test").innerHTML = "test";
};

how can I change the innerHTML from "test" to "another test" and vice versa ?

1
  • Hi Sam, If my answer was a help to you, please consider marking it correct. Commented May 4, 2018 at 23:49

4 Answers 4

1

It's better not to store state in the HTML - don't test against what's currently in the HTML, keep a variable in your Javascript instead.

You should also only use let when you want to warn other programmers that you're going to reassign the variable in question - otherwise, use const.

Also, if you're changing the text of an element, assign to textContent instead - it's safer, faster, and more predictable.

const button = document.getElementById("js");
const test = document.getElementById("test");
let clicked = false;
button.onclick = function() {
  clicked = !clicked;
  if (clicked) test.textContent = 'another test';
  else test.textContent = 'test';
};
 <div class="test" id="test">
    <p>this is a test</p>
</div>
<p id="js" class="test" >Change</p>

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

2 Comments

One might say that using HTML for state is exactly the right thing to do since the HTML is the ultimate description of the current state of the program. Adding a JavaScript variable to hold HTML state is certainly not wrong, but it does introduce the possibility of the variable getting out of sync with the HTML and causes you to manage two values that ultimately should be the same at all times.
Instead of a variable, I'd consider using a data attribute on the button to handle the toggle state.
1

First, .innerHTML is only for when you are setting/getting a string that contains HTML. When you are not, use .textContent, which is more efficient and reduces security risks.

Then, you only need a toggling if statement, which can be done with a JavaScript ternary operator.

Also, rather than using event properties, like onclick. Use .addEventListener(), which is more robust and follows the modern standard.

// Get a reference to the <p> that is inside of the element who's id is "test"
let output = document.querySelector("#test p");

// Set up an event handler for the "Change" element
document.getElementById("js").addEventListener("click", function() {
  // Check the current textContent and set it to the other value
  output.textContent === "test" ? output.textContent = "another test" : output.textContent = "test";
});
<div class="test" id="test">
    <p>this is a test</p>
</div>
<p id="js" class="test" >Change</p>

Comments

1

Just toggle between the two with an if statement like this:

let button = document.getElementById("js");
let toggleText = document.getElementById("test");

button.addEventListener('click', function() {
    if (toggleText.innerHTML !== "another test") {
        toggleText.innerHTML = "another test";
    } else {
        toggleText.innerHTML = "test";
    }
});

ALso, as @CertainPerformance mentioned in the other answer, I would recommend that you use textContent rather than innerHTML since you're checking and toggling the element's string content and not the element itself.

Comments

1

I'm going to expand on a couple of excellent answers here.

What if you had more options and wanted to iterate through a list?

In that case, I'd use a data attribute to hold the button state. This is still a valid approach with just two options.

I am going to use Scott's answer as the basis of mine, so everything he says is pertinent.

// Get a reference to the <p> that is inside of the element who's id is "test"
let output = document.querySelector("#test p");

// Set up an event handler for the "Change" element
document.getElementById("js").addEventListener("click", function() {
  //Here is out list of options
  var options = ["test", "another test", "yet another test", "Really? Another Test?"];
  
  //get the current state value and increment it
  var index = parseInt(this.dataset.state, 10) + 1;
  
  
  //if index is out of bounds set it to 0
  if(index > options.length -1 || index < 0)
  {
    index = 0;
  }  
  
  //Set the text
  output.textContent = options[index];
  
  //Set the new state 
  this.dataset.state = index;
});
<div class="test" id="test">
    <p>this is a test</p>
</div>
<p id="js" class="test" data-state="-1" >Change</p>

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.