Read more / less code but it doesn't change properly - javascript

After doing some research I came to this code shown below. If you try the code yourself you notice the variable is used for every div with a button and text (the whole site). I tried several other codes but I like the slideDown/Up feature.
var status = "less"
$(document).on("click", ".toggle-text-button", function() {
if (status == "less") {
$(this).parent().children(".toggle-text").slideDown();
status = "more";
} else if (status == "more") {
$(this).parent().children(".toggle-text").slideUp();
status = "less";
}
});
.toggle-text-button {
background-color: #000000;
color: yellow;
cursor: pointer;
padding: 18px;
width: 100%;
border: 25%;
text-align: middle;
outline: none;
font-size: 15px;
font-family: verdana, geneva;
font-weight: bold;
}
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/js/uikit-icons.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/js/uikit.min.js"></script>
<div>
<button class="toggle-text-button">Title</button>
<div class="uk-text-justify toggle-text" style="display: none; margin-bottom: 2px;">
<p>The text that is hidden.</p>
</div>
</div>
<div>
<button class="toggle-text-button">Title Two</button>
<div class="uk-text-justify toggle-text" style="display: none; margin-bottom: 2px;">
<p>The text that is hidden two.</p>
</div>
</div>
If somebody knows how I can rearrange this code to make it work for every different div that would be fantastic.
Thank you in advance!

Variable status is "global", it's not unique for your toggle texts. There are various methods of doing this. The easiest is to check, if your .toggle-text class element is visible or not, and slide up/down accordingly.
$(document).on("click", ".toggle-text-button", function() {
var toggleText = $(this).parent().children(".toggle-text");
if (toggleText.is(':visible')) { // when toggleText is visible
toggleText.slideUp();
} else { // when it's not visible
toggleText.slideDown();
}
});
.toggle-text-button {
background-color: #000000;
color: yellow;
cursor: pointer;
padding: 18px;
width: 100%;
border: 25%;
text-align: middle;
outline: none;
font-size: 15px;
font-family: verdana, geneva;
font-weight: bold;
}
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/js/uikit-icons.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-rc.25/js/uikit.min.js"></script>
<div>
<button class="toggle-text-button">Title</button>
<div class="uk-text-justify toggle-text" style="display: none; margin-bottom: 2px;">
<p>The text that is hidden.</p>
</div>
</div>
<div>
<button class="toggle-text-button">Title Two</button>
<div class="uk-text-justify toggle-text" style="display: none; margin-bottom: 2px;">
<p>The text that is hidden two.</p>
</div>
</div>

Related

issue with hiding a Code block for a quiz [duplicate]

This question already has answers here:
Can I have a <pre> Tag inside a <p> tag in Tumblr?
(3 answers)
Closed last year.
Currently I have a "quiz section" for my webpage. At the bottom of the information on the lesson there is a quiz.
Currently I have been able to show/hide standard text. But I want to know show a code block when I click "Show solution".
I have tried changing class names, but I can't seem to get it right.
function show_hide(element)
{
var myAnswer = element.nextElementSibling;
var displaySetting = myAnswer.style.display;
var quizButton = element;
if(displaySetting=="inline-block"){
myAnswer.style.display = 'none';
quizButton.innerHTML = 'Show Solution';
}
else
{
myAnswer.style.display = 'inline-block';
quizButton.innerHTML = 'Hide Solution';
}
}
.quiz-question{
margin-bottom: 10px;
text-align: left;
font-size: 15px;
color: #f44336;
font-weight: 400;
}
.quiz-button{
display: inline-block;
text-decoration: none;
color: #111;
border: 1px solid #f44336;
padding: 5px 5px;
font-size: 13px;
background: transparent;
position: relative;
cursor: pointer;
}
.quiz-button:hover{
color: #fff;
background: #f44336;
transition: 0.5s;
}
#answer{
display: none;
}
<head>
<script src="https://cdn.jsdelivr.net/gh/CDNSFree2/PrismJS#latest/prism.min.js"></script>
</head>
<body>
<!-- Working Code -->
<h4 class="quiz-question">1. What is the difference between a statement and an expression?</h4>
<button onclick="show_hide(this)" class="quiz-button">Show Solution</button>
<p id="answer">
<b>Statements</b> are used when we want the program to perform an action. Expressions are used when
we want the program to calculate a value.
</p>
<br><br><hr>
<!-- Not Working Code -->
<h4>C - Question</h4>
<button onclick="show_hide(this)" class="quiz-button">Show Solution</button>
<p id="answer">
<pre>
<code class="language-cpp line-numbers">
2 //2 is a literal that evaluates to value 2
"Hello World!" //"Hello World!" is a literal that evaluates to text "Hello"
</code>
</pre>
</p>
</body>
You have multiple error in this code:
id must be unique use class instead.
use <div> for contain <pre> instead of <p>
function show_hide(element) {
const myAnswer = element.nextElementSibling;
const displaySetting = myAnswer.style.display;
if (displaySetting === "inline-block") {
myAnswer.style.display = 'none';
element.innerHTML = 'Show Solution';
} else {
myAnswer.style.display = 'inline-block';
element.innerHTML = 'Hide Solution';
}
}
.quiz-question {
margin-bottom: 10px;
text-align: left;
font-size: 15px;
color: #f44336;
font-weight: 400;
}
.quiz-button {
display: inline-block;
text-decoration: none;
color: #111;
border: 1px solid #f44336;
padding: 5px 5px;
font-size: 13px;
background: transparent;
position: relative;
cursor: pointer;
}
.quiz-button:hover {
color: #fff;
background: #f44336;
transition: 0.5s;
}
.answer {
display: none;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.26.0/themes/prism.min.css" integrity="sha512-tN7Ec6zAFaVSG3TpNAKtk4DOHNpSwKHxxrsiw4GHKESGPs5njn/0sMCUMl2svV4wo4BK/rCP7juYz+zx+l6oeQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdn.jsdelivr.net/gh/CDNSFree2/PrismJS#latest/prism.min.js"></script>
<!-- Working Code -->
<h4 class="quiz-question">1. What is the difference between a statement and an expression?</h4>
<button onclick="show_hide(this)" class="quiz-button">Show Solution</button>
<p class="answer">
<b>Statements</b> are used when we want the program to perform an action. Expressions are used when we want the program to calculate a value.
</p>
<br><br>
<hr>
<h4>C - Question</h4>
<button onclick="show_hide(this)" class="quiz-button">Show Solution</button>
<div class='answer'>
<pre>
<code class="language-cpp line-numbers">
2 //2 is a literal that evaluates to value 2
"Hello World!" //"Hello World!" is a literal that evaluates to text "Hello"
</code>
</pre>
</div>
You can use prettify library
function show_hide(element)
{
var myAnswer = element.nextElementSibling
var displaySetting = myAnswer.style.display;
var quizButton = element;
if(displaySetting=="inline-block"){
myAnswer.style.display = 'none';
quizButton.innerHTML = 'Show Solution';
}
else
{
myAnswer.style.display = 'inline-block';
quizButton.innerHTML = 'Hide Solution';
}
}
.quiz-question{
margin-bottom: 10px;
text-align: left;
font-size: 15px;
color: #f44336;
font-weight: 400;
}
.quiz-button{
display: inline-block;
text-decoration: none;
color: #111;
border: 1px solid #f44336;
padding: 5px 5px;
font-size: 13px;
background: transparent;
position: relative;
cursor: pointer;
}
.quiz-button:hover{
color: #fff;
background: #f44336;
transition: 0.5s;
}
#answer{
display: none;
}
code
{
padding: 2px 4px;
color: #000000;
background-color: #eeeeee;
border-radius: 3px;
}
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.css" integrity="sha512-PW9BfYtoXV6XYb/4FTkBoJEBM92TrGk7N324cCmF5i2dY02YvBg6ZPEAnSOZ5i2/nGPbsYFQwVzDxVVoWEKWww==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js" integrity="sha512-/9uQgrROuVyGVQMh4f61rF2MTLjDVN+tFGn20kq66J+kTZu/q83X8oJ6i4I9MCl3psbB5ByQfIwtZcHDHc2ngQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script></head>
<body onload="prettyPrint()">
<!-- Working Code -->
<h4 class="quiz-question">1. What is the difference between a statement and an expression?</h4>
<button onclick="show_hide(this)" class="quiz-button">Show Solution</button>
<p id="answer">
<b>Statements</b> are used when we want the program to perform an action. Expressions are used when
we want the program to calculate a value.
</p>
<br><br><hr>
<!-- Not Working Code -->
<h4>C - Question</h4>
<button onclick="show_hide(this)" class="quiz-button">Show Solution</button>
<p id="answer">
<code class="language-cpp prettyprint line-numbers">
2 //2 is a literal that evaluates to value 2
"Hello World!" //"Hello World!" is a literal that evaluates to text "Hello"
</code>
</p>
</body>

Prototype Pollution script alert doesn't work

This below is my code.
<html>
<head>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://raw.githack.com/alrusdi/jquery-plugin-query-object/9e5871fbb531c5e246aac2aaf056b237bc7cc0a6/jquery.query-object.js"></script>
<style>
.dropbtn {
background-color: #3498DB;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #2980B9;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 10px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
font-size: small;
}
.dropdown a:hover {background-color: #ddd;}
.show {display: block;}
</style>
</head>
<body>
<h1 id="root"></h1>
<script>
function myFunction() {
document.getElementById("myDropdown").classList.toggle("show");
}
var pages = {
home: `HOME </br>
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">home</button>
<div id="myDropdown" class="dropdown-content">
about
contact
</div>
</div>`,
about: `ABOUT </br>
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">about</button>
<div id="myDropdown" class="dropdown-content">
home
contact
</div>
</div>`,
contact: `CONATCT </br>
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">contact</button>
<div id="myDropdown" class="dropdown-content">
home
about
</div>
</div>`
};
var pl = $.query.get('page');
// var pl = new URLSearchParams(window.location.search).get("page");
if (pl == null) {
document.location.search = "?page=home"
}
if(pages[pl] != undefined){
// $('#root').html(pages[pl])
document.getElementById("root").innerHTML = pages[pl];
}else{
document.location.search = "?page=home"
}
</script>
</body>
</html>
And when I try to do a prototype pollution attack on the above code,
example like this,
https://exaple.com?page=hol&__proto__[hol]=<img src=x onerror=alert(1)></img>
it works perfectly and gives an alert popup.
but when I use the script tag it doesn't give me an alert popup,
example like this,
https://exaple.com?page=hol&__proto__[hol]=<script>alert(1)</script>
Can anybody help that what's going on?
why the <img> tag work but not <script> tag?
The version with <script>alert(1)</script> is harmless because HTML5 specifies that a <script> tag inserted with innerHTML should not execute.
See mdn on innerHTML - Security considerations.

In Blogger, Hide/Show Quiz Answers based on button click with javascript

I have a quiz blog/website on blogger. To show the answers of questions I have following html code:
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>
And JavaScript like this:
<script type='text/javascript'>
//<![CDATA[
var acc = document.getElementsByClassName("acc");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
var pnl = this.nextElementSibling;
if (pnl.style.display === "block") {
pnl.style.display = "none";
} else {
pnl.style.display = "block";
}
});
}
//]]>
</script>
And CSS like this:
.acc {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active, .acc:hover {
background-color: #ccc;
}
.pnl {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
}
If some one clicks on all of the buttons, the buttons are acting as toggles rather than, showing one answer, then when the next button is clicked, hiding the previous answer and showing the new one in its place. What needs to be changed to enable this?
Thanks
Remove the buttons.
Add the following over each .pnl
<!-- #ids must be unique so btn* = btn1, btn2, etc -->
<!-- [for] of label must match #id of input -->
<input id='btn*' class="acc" name='acc' type='radio' hidden>
<label for='btn*'>Show Answer</label>
Explination: A label and a form control (ex. <input>, <select>, etc) can be associated with each other if the form control has an #id and the label has a [for] that match. If one gets clicked, checked, etc then the other one does as well.
Add the following CSS:
.acc:checked+label+.pnl {
display: block
}
Explination: If an input is checked then the .pnl that is front of the label that is in front of the input. Note, when a group of radio buttons share a [name] only one may be checked at a time. Also, the radio buttons are hidden so it looks as if the label is the only tag interacting with the user.
.acc {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active,
.acc:hover {
background-color: #ccc;
}
.pnl {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
}
.acc:checked+label+.pnl {
display: block
}
label {
display: block
}
<input id='btn1' class="acc" name='acc' type='radio' hidden>
<label for='btn1'>Show Answer</label>
<div class="pnl">
<p>Correct Answer</p>
</div>
<input id='btn2' class="acc" name='acc' type='radio' hidden>
<label for='btn2'>Show Answer</label>
<div class="pnl">
<p>Correct Answer</p>
</div>
<input id='btn3' class="acc" name='acc' type='radio' hidden>
<label for='btn3'>Show Answer</label>
<div class="pnl">
<p>Correct Answer</p>
</div>
Try this one by using a forEach.
var acc = document.getElementsByClassName("acc");
let pn1 = document.getElementsByClassName("pnl");
for (let i = 0; i < acc.length; i++) {
acc[i].addEventListener("click", function() {
this.classList.toggle("active");
[...acc].forEach((item,index) =>{
if(item == acc[i]){
pn1[index].style.display = "block";
}else{
pn1[index].style.display = "none";
}
})
})
}
.acc {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
.active, .acc:hover {
background-color: #ccc;
}
.pnl {
padding: 0 18px;
display: none;
background-color: white;
overflow: hidden;
}
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>
<button class="acc">Show Answer</button>
<div class="pnl">
<p>Correct Answer</p>
</div>

How to filter out results based off of an Array with jQuery

My program currently has a contenteditable area where users can input text and when they press the button it shoots out the text inputted to another div below it. I am trying to make it so when the user presses the button it shoots out the text inputted but also filters out each div line produced if it contains any of the following words within a specified array.
Any help is appreciated. Thank you.
Here is my code
<body>
<div id="pbf-container">
<div class="pbf-header">
<h1> VERO Filter Program </h1>
<h3> Input Links Here </h3>
</div>
<div class="pbf-link-container" contenteditable="true">
</div>
<div class="pbf-button-control">
<button id="pbf-filter"> Filter </button>
</div>
<div class="pbf-link-output">
</div>
</div>
<!-- uncomment when finished <script src="C:\Users\andrew.lee\Desktop\VERO Filter\pbf.js"></script> -->
<script>
$('#pbf-filter').click(function(){
var $pbfOutput = $('.pbf-link-container[contenteditable]').html();
var pbfFilterWords = ['red', 'blue', 'purple', 'green', 'orange'];
$('.pbf-link-output').html($pbfOutput)
.filter(pbfFilterWords).remove('div');
});
</script>
</body>
Here is the CSS:
#pbf-container {
display: block;
width: 1080px;
margin: 0 auto;
background-color: #333;
padding: 3%;
}
.pbf-header {
text-align: center;
}
.pbf-link-container {
width: 1080px;
min-height: 300px;
background-color: #f8f8f8;
font-size: 20px;
font-family: 'Lato', sans-serif;
}
.pbf-button-control {
text-align: center;
padding: 2%;
}
.pbf-link-output {
font-family: 'Lato', sans-serif;
font-size: 20px;
color: #fff;
}
example picture
You need to use .each() to loop through the array and check if div:contains any of this .. if yes .remove() it .. Actually the bad thing that contenteditable div doesn't make the div for the first line .. BUT I think I found a solution for this by append an empty <div> to the contenteditable div
$('.pbf-link-container[contenteditable]').html('<div><br/></div>');
$('#pbf-filter').click(function(){
var $pbfOutput = $('.pbf-link-container[contenteditable]').html();
var pbfFilterWords = ['red', 'blue', 'purple', 'green', 'orange'];
$('.pbf-link-output').html($pbfOutput);
$.each(pbfFilterWords , function(i , val){
$('.pbf-link-output > div:contains("'+val+'")').remove();
});
});
#pbf-container {
display: block;
width: 1080px;
margin: 0 auto;
background-color: #333;
padding: 3%;
}
.pbf-header {
text-align: center;
}
.pbf-link-container {
width: 1080px;
min-height: 300px;
background-color: #f8f8f8;
font-size: 20px;
font-family: 'Lato', sans-serif;
}
.pbf-button-control {
text-align: center;
padding: 2%;
}
.pbf-link-output {
font-family: 'Lato', sans-serif;
font-size: 20px;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="pbf-container">
<div class="pbf-header">
<h1> VERO Filter Program </h1>
<h3> Input Links Here </h3>
</div>
<div class="pbf-link-container" contenteditable="true">
</div>
<div class="pbf-button-control">
<button id="pbf-filter"> Filter </button>
</div>
<div class="pbf-link-output">
</div>
</div>

Creating a function to be called again and again

I want to create a simple text game of choices of sorts where you always have two choices and depending on your choice, something is displayed and the current content disappears. My problem is each of the choices are different so i can't figure out a way to not repeat myself again and again in the javascript code.
HTML :
<!Doctype html>
<html>
<head>
<script type="text/javascript" src="jquery-2.1.4.min.js"></script>
<link rel="stylesheet" href="style.css" type="text/css"/>
<title>Game</title>
</head>
<body>
<div id="console">
<div class="storyCard" id="start">
<p class="q">Some stuff.
<p class="a">getup</p>
<p class="a">sleep</p>
</div>
<div class="storyCard" id="getup">
<p class="q">Something happened</p>
<p class="a">do this</p>
<p class="a">do that</p>
</div>
<div class="storyCard" id="sleep">
<p class="q">something else happened</p>
<p class="a">do something</p>
<p class="a">do something else</p>
</div>
<!--and there will be a lot of such storyCards based on the choices.-->
</div>
<script type="text/javascript" src="js.js"></script>
</body>
</html>
CSS :
body {
margin: 0 auto;
align-content: center;
font-family: 'Open Sans', sans-serif;
font-weight: 400;
}
#console {
width: 100%;
}
.storyCard {
min-width: 100px;
max-width: 600px;
background-color: rgba(0, 0, 0, 0.51);
box-shadow: 1px 1px 7px;
padding: 50px;
color: white;
margin: 0 auto;
border-radius: 4px;
display: none;
}
#start {
display: block;
}
.storyCard .a {
background-color: dodgerblue;
border-bottom-color: dodgerblue;
border-top-color: white;
border-left-color: white;
border-right-color: dodgerblue;
padding: 10px;
text-align: center;
color: white;
width: 30%;
display: inline;
margin: 0 auto;
box-shadow: 1px 1px 7px black;
float: right;
cursor: pointer;
}
.storyCard .a:hover {
background-color: white;
color: black;
}
}
Javascript :
document.querySelector('#console').addEventListener('click', function (e) {
var answer = e.target.textContent;
switch (answer) {
case 'getup':
e.target.parentNode.style.display = 'none';
document.querySelector('#getup').style.display = 'block';
break;
case 'sleep':
e.target.parentNode.style.display = 'none';
document.querySelector('#sleep').style.display = 'block';
break;
case 'do this':
e.target.parentNode.style.display = 'none';
/*display another content like above*/
case 'do that':
/*hide the current content again and display another content and add more cases*/
}, false);
I assume that the question must defined in html like your sample. There are many others way to do this better.
You can use class name to specify next question.
document.addEventListener('click', function (e) {
var target = e.target;
if (target.className.match('answer')) {
var nextQuestionId = target.className.replace('answer ', '');
hideAllStoryCards();
showStoryCard(nextQuestionId);
}
});
function hideAllStoryCards () {
var i, elm, elms = document.getElementsByClassName('storyCard');
for (i = 0; i < elms.length; i++) {
elm = elms[i];
elm.style.display = 'none';
}
}
function showStoryCard (id) {
var storyCard = document.getElementById(id);
storyCard.style.display = 'block';
}
hideAllStoryCards();
showStoryCard('first-question');
<div id="console">
<div class="storyCard" id="first-question">
<p class="q">Are you hungry?</p>
<p class="answer what-do-you-want-to-eat">yes</p>
<p class="answer may-i-help-you">no</p>
</div>
<div class="storyCard" id="what-do-you-want-to-eat">
<p class="q">Some stuff.</p>
<p class="answer NEXT_QUESTION_ID">a pie</p>
<p class="answer ANOTHER_QUESTION_ID">a buger</p>
</div>
<div class="storyCard" id="may-i-help-you">
<p class="q">Some stuff.</p>
<p class="answer NEXT_QUESTION_ID">bye</p>
<p class="answer ANOTHER_QUESTION_ID">bye again</p>
</div>
</div>
You can try something like performAction(e, '#getup'); - a generalized method with parameters, in this link.
Please refer below for the code:
HTML:
<div id="console">
<div class="storyCard" id="start">
<p class="q">Some stuff.</p>
<p class="a">getup</p>
<p class="a">sleep</p>
</div>
<div class="storyCard" id="getup">
<p class="q">Something happened</p>
<p class="a">do this</p>
<p class="a">do that</p>
</div>
<div class="storyCard" id="sleep">
<p class="q">something else happened</p>
<p class="a">do something</p>
<p class="a">do something else</p>
</div>
<!--and there will be a lot of such storyCards based on the choices.-->
</div>
CSS:
body {
margin: 0 auto;
align-content: center;
font-family: 'Open Sans', sans-serif;
font-weight: 400;
}
#console {
width: 100%;
}
.storyCard {
min-width: 100px;
max-width: 600px;
background-color: rgba(0, 0, 0, 0.51);
box-shadow: 1px 1px 7px;
padding: 50px;
color: white;
margin: 0 auto;
border-radius: 4px;
display: none;
}
#start {
display: block;
}
.storyCard .a {
background-color: dodgerblue;
border-bottom-color: dodgerblue;
border-top-color: white;
border-left-color: white;
border-right-color: dodgerblue;
padding: 10px;
text-align: center;
color: white;
width: 30%;
display: inline;
margin: 0 auto;
box-shadow: 1px 1px 7px black;
float: right;
cursor: pointer;
}
.storyCard .a:hover {
background-color: white;
color: black;
}
JS:
document.querySelector('#console').addEventListener('click', function(e) {
var answer = e.target.textContent;
switch (answer) {
case 'getup':
performAction(e, '#getup');
break;
case 'sleep':
performAction(e, '#sleep');
break;
case 'do this':
performAction(e, '#getup'); /**Use any 'id' or target of your choice.*/
/*display another content like above*/
break;
case 'do that':
performAction(e, '#getup'); /*Use any 'id' or target of your choice.*/
/*hide the current content again and display another content and add more cases*/
break;
}
}, false);
function performAction(event, target) {
event.target.parentNode.style.display = 'none';
document.querySelector(target).style.display = 'block';
}
You need to separate your data from your UI.
Your data could be something simple like this:
var stories;
function StoryCard(q, option1, option2) {
this.q = q
this.option1 = option1;
this.option2 = option2;
}
function displayStory(storyCard) {
document.getElementById('q').innerHTML = storyCard.q;
document.getElementById('option1').innerHTML = storyCard.option1;
document.getElementById('option2').innerHTML = storyCard.option2;
}
Your "console" UI could change to something more like this:
<div id="console">
<div class="storyCard" id="start">
<p class="q" id="q"> </p>
<p class="a" id="option1"> </p>
<p class="a" id="option2"> </p>
</div>
</div>
Your click function may be more like this:
document.querySelector('#console').addEventListener('click', function (e) {
var answer = e.target.id;
switch (answer) {
default: // for when they click within the div, but not on an option
break;
case 'option1':
case 'option2':
var story = stories[e.target.innerHTML];
if (null != story) {
displayStory(story);
}
break;
}
}, false);
You would set up your stories perhaps in an onload:
function init() {
stories = { "start": new StoryCard("Some stuff", "getup", "sleep")
, "getup": new StoryCard("Something happened", "do this", "do that")
, "sleep": new StoryCard("something else happened", "do something", "do something else")
};
displayStory(stories["start"]);
}

Categories

Resources