I would like to make one button do 3 or more things one after the other. I'm trying to make a CYOA and I need one button to go through multiple layers/phases/sections(Start to layer 1 to layer 2) of the CYOA, with as little repeating code* as possible. I have placeholder text in the areas where the text in the title and the buttons go to see that the code runs properly
*Example of repeating code
function change_text(a){
if (a == 1) {
document.getElementById("title").innerHTML = "Phase 2";
document.getElementById("button1").innerHTML = "Ye";
document.getElementById("button2").innerHTML = "N";
} else {
document.getElementById("title").innerHTML = "The End";
}
function change_text(a){
if (a == 2) {
document.getElementById("title").innerHTML = "Phase 3";
document.getElementById("button1").innerHTML = "Ye";
document.getElementById("button2").innerHTML = "N";
} else {
document.getElementById("title").innerHTML = "The End";
}
HTML
<div id="centered"><h1 id="title">Phase 1</h1>
<button onclick="change_text(1)" id="button1">Yes</button>
<button onclick="change_text(2)" id="button2">No</button></div>
Javascript
function change_text(a){
if (a == 1) {
document.getElementById("title").innerHTML = "Phase 2";
document.getElementById("button1").innerHTML = "Ye";
document.getElementById("button2").innerHTML = "N";
} else {
document.getElementById("title").innerHTML = "The End";
}
}
CodePudding user response:
If you want to do it with ifs, you just need one function and update a variable.
var currentStep = 0;
function change_text(a){
currentStep ;
if (currentStep == 1) {
document.getElementById("title").innerHTML = "Phase 2";
document.getElementById("button1").innerHTML = "Ye";
document.getElementById("button2").innerHTML = "N";
} else if (currentStep == 2) {
...
} else {
}
}
Problem with that is you have a lot of repeated code. I would use an array of objects.
var phases = [{
title: "FOO 1",
btn1: "foo 1",
}, {
title: "FOO 2",
btn1: "foo 2",
}, {
title: "FOO 3",
btn1: "foo 3",
}, {
title: "FOO 4",
btn1: "done",
}, ];
var currentStep = 0;
var heading = document.getElementById("heading");
var btn1 = document.getElementById("btn1");
function updateStep() {
var step = phases[currentStep];
if (step) {
heading.textContent = step.title;
btn1.textContent = step.btn1;
currentStep ;
}
}
btn1.addEventListener("click", updateStep);
<h2 id="heading">Welcome</h2>
<button id="btn1">Next</button>
CodePudding user response:
I would suggest you to separate the logic of your app from UI. Try to think about your app as it is described by a state. In your case state may be as simple as the title text ("Stage 1", "Stage 2" etc.) or as complex as you can imagine. Interacting with the UI, user performs actions. In your case there are two buttons so your actions would be "Yes" and "No". Each action updates the state (which is the app logic), and each state could be rendered to the screen (which is UI part). In the code below I defined two functions to do just that. It is actually more code than in your example, so maybe it's not exactly what you asked for), but in my opinion it is much simpler to read and to extend its functionality.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Stages</title>
</head>
<body>
<div id="centered">
<h1 id="title"></h1>
<button onclick="update('yes')" id="button1">Yes</button>
<button onclick="update('no')" id="button2">No</button>
</div>
<script>
let state = "Phase 1"; // current state
render(state);
function render(state) {
const titleElement = document.getElementById("title");
titleElement.innerHTML = state;
}
function update(action) {
/* updating state */
switch (action) {
case "yes":
switch (state) {
case "Phase 1":
state = "Phase 2";
break;
case "Phase 2":
state = "Phase 3";
break;
case "Phase 3":
state = "End";
break;
}
break;
case "no":
state = "End";
break;
}
/* changing UI */
render(state);
}
</script>
</body>
</html>
If you find this approach interesting, I would suggest you to read this.