How to remove an event listener and add the listener back on another element click - javascript

I am creating a simple picture matching game and I will love to make sure when the picture is clicked once, the event listener is removed, this will help me stop the user from clicking on the same image twice to get a win, and then when the user clicks on another element the listener should be added back, I tried doing this with an if statement but the listener is only removed and never added back, I decided to reload the page which somehow makes it look like a solution but I need a better solution that can help me not to reload the page but add the listener back so that the element can be clicked again after the last else if statement run.
here is the sample code below.
//Selecting query elements
const aniSpace = document.querySelector(".container");
const firstCard = document.querySelector("#fstcard");
const secondCard = document.querySelector("#sndcard");
const thirdCard = document.querySelector("#thrdcard");
const playGame = document.querySelector('#play');
const scores = document.querySelector('.scoreboard');
count = 0;
var firstIsClicked = false;
var isCat = false;
var isElephant = false;
var isDog = false;
var isButterfly = false;
var isEmpty = false;
const animatchApp = () => {
const animals = {
cat: {
image: "asset/images/cat.png",
name: "Cat"
},
dog: {
image: "asset/images/puppy.png",
name: "Dog"
},
elephant: {
image: "asset/images/elephant.png",
name: "Elephant"
},
butterfly: {
image: "asset/images/butterfly.png",
name: "butterfly"
}
}
var score = 0;
firstCard.addEventListener('click', function firstBtn() {
var type = animals.cat.name;
if (firstIsClicked === true && isCat === true) {
firstCard.innerHTML = `<img src="${animals.cat.image}">`;
firstCard.classList.add('display');
alert("You won");
score = score + 50;
console.log(score);
document.getElementById('scores').innerHTML = score;
firstIsClicked = false;
isElephant = false;
if (score >= 200){
alert("You are unstoppable, Game won.");
count = 0;
score = 0;
document.getElementById('scores').innerHTML = score;
document.getElementById('attempts').innerHTML = count;
}
firstCard.removeEventListener('click', firstBtn);
} else if (firstIsClicked === false) {
firstCard.innerHTML = `<img src="${animals.cat.image}">`;
firstCard.classList.add('display');
firstIsClicked = true;
isCat = true;
firstCard.removeEventListener('click', firstBtn);
} else if (firstIsClicked === true && isCat != true) {
alert("Not Matched");
count++;
document.getElementById('attempts').innerHTML = count;
firstCard.innerHTML = '';
secondCard.innerHTML = '';
thirdCard.innerHTML = '';
firstCard.classList.remove('display');
secondCard.classList.remove('display');
thirdCard.classList.remove('display');
firstIsClicked = false;
isCat = false;
isDog = false;
isElephant = false;
isButterfly = false;
score = 0;
document.getElementById('scores').innerHTML = score;
location.reload(true);
}
})
secondCard.addEventListener('click', function secondBtn() {
var type = animals.elephant.name;
if (firstIsClicked === true && isElephant === true) {
secondCard.innerHTML = `<img src="${animals.elephant.image}">`;
secondCard.classList.add('display');
alert("You won");
score = score + 50;
console.log(score);
document.getElementById('scores').innerHTML = score;
firstIsClicked = false;
isElephant = false;
if (score >= 200){
alert("You are unstoppable, Game won.");
count = 0;
score = 0;
document.getElementById('scores').innerHTML = score;
document.getElementById('attempts').innerHTML = count;
}
secondCard.removeEventListener('click', secondBtn);
} else if (firstIsClicked === false) {
secondCard.innerHTML = `<img src="${animals.elephant.image}">`;
secondCard.classList.add('display');
firstIsClicked = true;
isElephant = true;
secondCard.removeEventListener('click', secondBtn);
} else if (firstIsClicked === true && isElephant != true) {
alert("Not Matched");
count++;
document.getElementById('attempts').innerHTML = count;
firstCard.innerHTML = '';
secondCard.innerHTML = '';
thirdCard.innerHTML = '';
firstCard.classList.remove('display');
secondCard.classList.remove('display');
thirdCard.classList.remove('display');
firstIsClicked = false;
isCat = false;
isDog = false;
isElephant = false;
isButterfly = false;
score = 0;
document.getElementById('scores').innerHTML = score;
location.reload(true);
}
})
thirdCard.addEventListener('click', function thirdBtn() {
var type = animals.dog.name;
if (firstIsClicked === true && isDog === true) {
thirdCard.innerHTML = `<img src="${animals.dog.image}">`;
thirdCard.classList.add('display');
alert("You won");
score = score + 50;
console.log(score);
document.getElementById('scores').innerHTML = score;
firstIsClicked = false;
isDog = false;
if (score >= 200){
alert("You are unstoppable, Game won.");
count = 0;
score = 0;
document.getElementById('scores').innerHTML = score;
document.getElementById('attempts').innerHTML = count;
}
thirdCard.removeEventListener('click', thirdBtn);
} else if (firstIsClicked === false) {
thirdCard.innerHTML = `<img src="${animals.dog.image}">`;
thirdCard.classList.add('display');
firstIsClicked = true;
isDog = true;
thirdCard.removeEventListener('click', thirdBtn);
} else if (firstIsClicked === true && isDog != true) {
alert("Not Matched");
count++;
document.getElementById('attempts').innerHTML = count;
firstCard.innerHTML = '';
secondCard.innerHTML = '';
thirdCard.innerHTML = '';
firstCard.classList.remove('display');
secondCard.classList.remove('display');
thirdCard.classList.remove('display');
firstIsClicked = false;
isCat = false;
isDog = false;
isElephant = false;
isButterfly = false;
score = 0;
document.getElementById('scores').innerHTML = score;
location.reload(true);
}
})
document.getElementById('attempts').innerHTML = count;
}
animatchApp();
.h1 {
text-align: center;
background-color: azure;
background-image: url("");
}
* {
box-sizing: border-box;
}
.container {
width: 500px;
}
.card1 {
background-color: blue;
float: left;
width: 30%;
padding: 10px;
height: 150px; /* Should be removed. Only for demonstration */
border: 1px solid rgb(179, 177, 177);
transition: transform 0.8s;
transform-style: preserve-3d;
}
.card2 {
background-color: blue;
float: left;
width: 30%;
padding: 10px;
height: 150px; /* Should be removed. Only for demonstration */
border: 1px solid rgb(179, 177, 177);
transition: transform 0.8s;
transform-style: preserve-3d;}
.card3 {
background-color: blue;
float: left;
width: 30%;
padding: 10px;
height: 150px; /* Should be removed. Only for demonstration */
border: 1px solid rgb(179, 177, 177);
transition: transform 0.8s;
transform-style: preserve-3d;
}
.scoreboard {
float: left;
width: 100%;
padding: 10px;
height: 150px; /* Should be removed. Only for demonstration */
}
img {
width: 100%;
height: 100%;
background-color: white;
}
.display {
background-color: white;
transform: rotateY(180deg);
}
<div class="container">
<h1 class="h1">Animatch</h1>
<div class="first">
<div class="card1" id="fstcard"></div>
<div class="card1" id="sndcard"></div>
<div class="card1" id="thrdcard"></div>
</div>
</div>
<div class="scoreboard">
<p>
<button id="play" onclick="animatchApp()">Play</button>
<br>
Score: <span id="scores">0</span>
<br>
Failed attempts: <span id="attempts"></span>
</p>
</div>

you have to define function outside of onclick because you will need this function reference to remove or add it to eventlistener later
see a example below
function onload(){
var main = document.querySelector(".main"),
btns = main.querySelectorAll(".buttons input"),
box = main.querySelector(".box")
btns[0].addEventListener("click",function(){
box.addEventListener("click",functionForEvent)
})
btns[1].addEventListener("click",function(){
box.removeEventListener("click",functionForEvent)
})
function functionForEvent(e){
console.log("clicked")
}
}
onload()
<div class="main">
<div class="box" style="height:120px;width:120px;border:1px solid black;">Click Me</div>
<div class="buttons">
<input type="button" value="Add Event">
<input type="button" value="Remove Event">
</div>
</div>

Here is an example, that shows how to remove the click event from the item clicked and add it to the other items.
It colors the items that can be clicked green, and the item that can't be clicked red.
To keep the example short, it doesn't check, if the elements it operates on, are well defined.
function myonload() {
let elems = document.querySelectorAll('.mydiv');
for(let i = 0; i < elems.length; ++i) {
let elem = elems[i];
elem.addEventListener('click', mydiv_clicked);
}
}
function mydiv_clicked(e) {
let elems = document.querySelectorAll('.mydiv');
for(let i = 0; i < elems.length; ++i) {
let elem = elems[i];
if(elem == e.target) {
elem.removeEventListener('click', mydiv_clicked);
elem.classList.add('mycolor_clicked');
elem.classList.remove('mycolor');
// Do additional logic here
} else {
elem.addEventListener('click', mydiv_clicked);
elem.classList.remove('mycolor_clicked');
elem.classList.add('mycolor');
// Do additional logic here
}
}
}
.mydiv {
height:30px;
width: 200px;
border:1px solid black;
margin-bottom:2px;
}
.mycolor {
background-color:#00ff00;
}
.mycolor_clicked {
background-color:#ff0000;
}
<body onload="myonload()">
<div class="mydiv mycolor">First area</div>
<div class="mydiv mycolor">Second area</div>
<div class="mydiv mycolor">Third area</div>
</body>
The example shown here does not need to check if an event handler already exists, as adding the same event handler twice, replaces the existing one.
You could also add a custom attribute to your elements and toggle it, instead of adding and removing event listeners as shown here and name your attribute data-something, for example data-can-be-clicked.

Related

How to make a reset button appear after certain requirements?

So, i want a reset button to appear on my page when the score of the player reaches 5. But i can't seem to make it appear.
if (Score == 5) {
btnQuestion.disabled = true;
txtQuestionFeedback.innerText = "Correct! \n Congratulations, you've got 5 stars!";
imgScore5.src = "Images/StarOn.gif";
document.getElementById(btnReset).innerHTML = btnReset;
}
Try the following:
1) Insert your button element inside a DIV like this for easier reading
<div id="resetButtonDiv">
<button id="resetButton"></button> <!-- here goes your button config -->
</div>
2) Change the style like this using JS
<script>
function showResetButton() {
document.getElementById("resetButton").style.display = "none";
if (Score == 5) {
// Replace "Score" with your variable or element
document.getElementById("resetButton").style.display = "show";
}
}
showResetButton()
</script>
This was my way to do it:
ScoreBoard = function(sId, sIntoNode = '', fnOnChange = null) {
this.m_sId = sId != '' ? sId : 'scoreboard';
this.m_iScore = 0;
this.m_fnOnChange = fnOnChange;
if(sIntoNode != '') {
let TargetNode = document.getElementById(sIntoNode);
if(TargetNode) {
TargetNode.innerHTML = TargetNode.innerHTML + '<div class="scoreboard-score" id="' + this.m_sId + '">0</div>';
}
}
}
ScoreBoard.prototype.SetScore = function(iNewScore) {
this.m_iScore = iNewScore;
let scoreBoard = document.getElementById(this.m_sId);
if(scoreBoard) {
scoreBoard.innerHTML = this.m_iScore;
}
if(this.m_fnOnChange && typeof this.m_fnOnChange == 'function') {
this.m_fnOnChange(this);
}
}
ScoreBoard.prototype.AddScore = function(iAmount) {
this.SetScore(this.m_iScore + iAmount);
}
ScoreBoard.prototype.Reset = function() {
this.SetScore(0);
}
ScoreBoard.prototype.GetScore = function() {
return this.m_iScore;
}
function OnScoreChange(target) {
let resetBtn = document.getElementById('myScore-reset');
if(resetBtn) {
if(target.GetScore() >= 5) {
resetBtn.style.display = "block";
} else {
resetBtn.style.display = "none";
}
}
}
var myScore = new ScoreBoard('myScore', 'score', OnScoreChange);
var i = 0;
function test() {
myScore.AddScore(1);
i++;
if(i < 20) setTimeout(test, 1000);
}
test();
div#score {
padding: 12px;
background-color: darkgrey;
font-family: Arial;
border-radius: 12px;
box-shadow: 0 0 12px 3px black;
}
div.score-head {
background-color: black;
color: white;
padding: 6px;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
}
div.scoreboard-score {
background-color: #EAEAEA;
padding: 6px;
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
}
div#score button {
display: none;
}
<div id="score">
<button onClick="myScore.Reset();" id="myScore-reset">Reset Score</button>
<div class="score-head">Score:</div>
</div>
I've sorted it guys!
Instead, i just used a visibility attribute on the button to hide it on page startup. And then called on that attribute in a Function for HideButton().
```
function ShowResetButton() {
document.getElementById("btnReset").style.visibility = "visible";
}
```
But thank you all for your input! i really appreciate it!
Take it easy,
Happy coding!

How do I implement a timer to deal each card after 2 seconds?

I have this function which will deal a card to a player, then to a dealer, then to a player and then to a dealer.
I have tried to use setTimeout(function, milliseconds); but it doesn't work. For example, if I set 2 seconds, it will wait for 4 seconds, then deal the 2 cards to the player and then straight away to dealer 2 cards or it will wait for 8 seconds, then in one batch deal all the cards out.
Here are my methods:
const dealOneCardToPlayer = () => {
// Take a card from the top deck to be assigned to tempcard.
tempCard = deck.cards.splice(0, 1);
//console.log(tempCard);
player.cards.push(tempCard);
if (player.cards.length === 5) {
player.canHit = false;
}
if (player.canHit) {
$("#btnHit").show();
} else {
$("#btnHit").hide();
}
player.handValue = countHandValue(player.cards);
makeCardPlayer(tempCard[0]);
}
const dealOneCardToDealer = (holeCard) => {
// Take a card from the top deck to be assigned to tempcard.
tempCard = deck.cards.splice(0, 1);
dealer.cards.push(tempCard);
if (dealer.cards.length === 5) {
dealer.canHit = false;
}
if (dealer.canHit) {
$("#btnHit").show();
} else {
$("#btnHit").hide();
}
dealer.handValue = countHandValue(dealer.cards);
makeCardDealer(tempCard[0],holeCard);
}
const deal = () => {
debugger;
newDeck();
// Option: to burn first card before deal a card
// to the first player
burnOneCard;
dealOneCardToPlayer();
dealOneCardToDealer(false);
dealOneCardToPlayer();
// true for hole card
dealOneCardToDealer(true);
showGameButtons(true);
checkEndGame1();
checkGameOver();
}
<link href="check.css" rel="stylesheet" />
<style>
body{
font-size: 2em;
}
h3, h5 {
text-align: center;
}
h5{
margin-top:-40px;
}
/*debugging purpose*/
div#oneDeck {
border: 1px solid green;
margin: 10px;
padding: 10px;
}
/*debugging purpose*/
div#playerCards {
border: 1px solid blue;
margin: 10px;
padding: 10px;
}
/*debugging purpose*/
div#dealerCards {
border: 1px solid red;
margin: 10px;
padding: 10px;
}
#mainContainer {
max-width: 600px;
margin: 0 auto;
}
fieldset {
margin-top: 30px;
border: 1px solid #999;
border-radius: 8px;
box-shadow: 0 0 10px #999;
}
legend {
background: #fff;
}
#cardContainerPlayer {
display: flex;
flex-wrap: wrap;
}
.card {
display: inline-block;
vertical-align: top; /*float: left;*/
text-align: center;
margin: 5px;
padding: 10px;
width: 70px;
height: 100px;
font-size: 26px;
background-color: black;
border: solid 1px black;
color: white;
border-radius: 10px;
}
.holeCard {
/*visibility: hidden;*/
border: solid 1px black;
background: repeating-linear-gradient( 45deg, #606dbc, #606dbc 10px, #465298 10px, #465298 20px );
}
.red {
background-color: red;
border: solid 1px #8C001A;
}
.templatePlayer, .templateDealer {
display: none;
}
#btnGame {
margin: 10px;
}
.winner {
border: solid 5px #7ac142;
}
.btnGame {
background-color: dodgerblue; /* Green */
border: none;
color: white;
padding: 15px 32px;
/*border-radius:10px;*/
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
cursor: pointer;
-webkit-transition-duration: 0.4s; /* Safari */
transition-duration: 0.4s;
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
}
#btnHit {
margin-right: 20px;
}
.flex-container {
padding: 0;
margin: 0;
display: flex;
justify-content: space-between;
max-width: 100%;
overflow: auto;
/*border: 1px solid red*/
}
</style>
<h3>Simple Javascript BlackJack Game</h3>
<h5>developed by Steve Ngai</h5>
<div id="mainContainer">
<div id="btnDevelopment">
<input type='button' value='Create new Deck' onclick='newDeck();' />
<input type='button' value='Burn a card' onclick='burnOneCard();' />
<input type='button' value='Refresh Deck' onclick='showDeck();' />
<input type='button' value='Deal a card to Player' onclick='dealOneCardToPlayer();' />
<input type='button' value='Deal a card to Dealer' onclick='dealOneCardToDealer();' />
<input type='button' value='Show hand value' onclick='showHandValue();' />
<input type='button' value='Check end game' onclick='checkEndGame();' />
<input type='button' value='Refresh deck remaining cards count' onclick='getDeckCardCount();' />
</div>
<fieldset id="deck">
<legend>Remaining cards in the Deck: <span id="deckCardCount"></span></legend>
<div id="oneDeck"></div>
</fieldset>
<fieldset id="containerDealer">
<legend>Dealer (Hand Value: <span id="handValueDealer"></span>)</legend>
<div style="width:30px">
<svg class="checkmarkDealer" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
<circle class="checkmark__circle" cx="26" cy="26" r="25" fill="none" />
<path class="checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8" />
</svg>
</div>
<div id="dealerCards"></div>
<div id="cardContainerDealer">
<div class="card templateDealer">
<span class="dealerCardFace"></span>
<span class="dealerCardSuit"></span>
</div>
</div>
<div id="dealerCardsHandValue"></div>
</fieldset>
<div id="btnGame">
<div class="flex-container">
<div class="btn">
<input type='button' class="btnGame" id="btnDeal" value='Deal' onclick='deal();' />
</div>
<div class="btn">
<input type='button' class="btnGame" id="btnHit" value='Hit' onclick='hit();' />
<input type='button' class="btnGame" id="btnStand" value='Stand' onclick='stand();' />
</div>
</div>
</div>
<fieldset id="containerPlayer">
<legend>Player (Hand Value: <span id="handValuePlayer"></span>)</legend>
<div style="width:30px">
<svg class="checkmarkPlayer" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52">
<circle class="checkmark__circle" cx="26" cy="26" r="25" fill="none" />
<path class="checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8" />
</svg>
</div>
<div id="playerCards"></div>
<div id="cardContainerPlayer">
<div class="card templatePlayer">
<span class="playerCardFace"></span>
<span class="playerCardSuit"></span>
</div>
</div>
<div id="playerCardsHandValue"></div>
</fieldset>
<fieldset id="result">
<legend>Game Result</legend>
<div id="gameResult"></div>
</fieldset>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
"use strict";
// Variable/Object declaration and initialization - Start
const isDebug = false;
const DELAY = 2000;
var gameOver = false;
const deck = {
cards: []
}
var tempCard;
const player = {
cards: [],
handValue: 0,
isWinner: false,
canHit: true
}
const dealer = {
cards: [],
handValue: 0,
isWinner: false,
canHit: true
}
var result = document.getElementById("gameResult");
const cardSuit = ["hearts", "diams", "clubs", "spades"];
const cardFace = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"];
$(".checkmarkDealer").hide();
$(".checkmarkPlayer").hide();
$("#handValueDealer").hide();
//Variable/Object declaration and initialization - End
if (!isDebug) {
document.getElementById("btnDevelopment").style.display = "none";
document.getElementById("deck").style.display = "none";
document.getElementById("oneDeck").style.display = "none";
document.getElementById("playerCards").style.display = "none";
document.getElementById("dealerCards").style.display = "none";
//document.getElementById("result").style.display = "none";
} else {
document.getElementById("btnDevelopment").style.display = "block";
document.getElementById("deck").style.display = "block";
document.getElementById("oneDeck").style.display = "block";
document.getElementById("playerCards").style.display = "block";
document.getElementById("dealerCards").style.display = "block";
//document.getElementById("result").style.display = "block";
}
const showGameButtons = (cardDealt) => {
if (cardDealt) {
$("#btnDeal").hide();
$("#btnHit").show();
$("#btnStand").show();
//document.getElementById("btnDeal").disabled = true;
//document.getElementById("btnHit").disabled = false;
//document.getElementById("btnStand").disabled = false;
} else {
$("#btnDeal").show();
$("#btnHit").hide();
$("#btnStand").hide();
//document.getElementById("btnDeal").disabled = false;
//document.getElementById("btnHit").disabled = true;
//document.getElementById("btnStand").disabled = true;
}
if (player.isWinner === true) {
document.getElementById("containerDealer").classList.remove("winner");
document.getElementById("containerPlayer").classList.add("winner");
$("#handValueDealer").show();
$(".checkmarkPlayer").show();
$(".checkmarkDealer").hide();
} else if (dealer.isWinner === true) {
document.getElementById("containerPlayer").classList.remove("winner");
document.getElementById("containerDealer").classList.add("winner");
$("#handValueDealer").show();
$(".checkmarkPlayer").hide();
$(".checkmarkDealer").show();
} else {
}
}
showGameButtons(false);
// In JavaScript, functions are objects.
// You can work with functions as if they were objects.
function card(suit, face) {
this.suit = suit;
this.face = face;
switch (face) {
case "A":
this.faceValue = 11;
break;
case "J":
case "Q":
case "K":
this.faceValue = 10;
break;
default:
this.faceValue = parseInt(face);
break;
}
};
const createDeck = () => {
deck.cards = [];
deck.cards.length = 0;
cardSuit.forEach(function (suit) {
cardFace.forEach(function (face) {
deck.cards.push(new card(suit, face));
});
});
}
const shuffleDeck = () => {
// Fisher–Yates shuffle algorithm
let temp, i, rnd;
for (i = 0; i < deck.cards.length; i++) {
rnd = Math.floor(Math.random() * deck.cards.length);
temp = deck.cards[i];
deck.cards[i] = deck.cards[rnd];
deck.cards[rnd] = temp;
}
}
const newDeck = () => {
createDeck();
shuffleDeck();
document.getElementById("oneDeck").innerHTML = "";
player.cards = [];
player.handValue = 0;
dealer.cards = [];
dealer.handValue = 0;
var myNode = document.getElementById("cardContainerPlayer");
var fc = myNode.firstChild.firstChild;
while (fc) {
myNode.removeChild(fc);
fc = myNode.firstChild;
}
var myNodeDealer = document.getElementById("cardContainerDealer");
var fcDealer = myNodeDealer.firstChild.firstChild;
while (fcDealer) {
myNodeDealer.removeChild(fcDealer);
fcDealer = myNodeDealer.firstChild;
}
document.getElementById("playerCards").innerHTML = "";
document.getElementById("dealerCards").innerHTML = "";
document.getElementById("oneDeck").innerHTML = JSON.stringify(deck);
}
const burnOneCard = () => {
// Remove the top deck to burn
deck.cards.splice(0, 1);
}
const showDeck = () => {
document.getElementById("oneDeck").innerHTML = JSON.stringify(deck);
}
const dealOneCardToPlayer = () => {
return new Promise(function (resolve) {
setTimeout(function () {
// Take a card from the top deck to be assigned to tempcard.
tempCard = deck.cards.splice(0, 1);
//console.log(tempCard);
player.cards.push(tempCard);
if (player.cards.length === 5) {
player.canHit = false;
}
if (player.canHit) {
$("#btnHit").show();
} else {
$("#btnHit").hide();
}
//player.cards.push(new card("Spades","A"));
//player.cards.push(new card("Spades","10"));
document.getElementById("playerCards").innerHTML = JSON.stringify(player);
player.handValue = countHandValue(player.cards);
document.getElementById("handValuePlayer").innerHTML = player.handValue;
makeCardPlayer(tempCard[0]);
resolve();
}, DELAY);
});
}
const dealOneCardToDealer = (holeCard) => {
return new Promise(function (resolve) {
setTimeout(function () {
// Take a card from the top deck to be assigned to tempcard.
tempCard = deck.cards.splice(0, 1);
dealer.cards.push(tempCard);
if (dealer.cards.length === 5) {
dealer.canHit = false;
}
if (dealer.canHit) {
$("#btnHit").show();
} else {
$("#btnHit").hide();
}
document.getElementById("dealerCards").innerHTML = JSON.stringify(dealer);
dealer.handValue = countHandValue(dealer.cards);
document.getElementById("handValueDealer").innerHTML = dealer.handValue;
makeCardDealer(tempCard[0], holeCard);
resolve();
}, DELAY);
});
}
const hasAceInHand = (cardsOnHand) => {
for (let key in cardsOnHand) {
let arr = cardsOnHand[key];
for (let i = 0; i < arr.length; i++) {
let obj = arr[i];
for (let prop in obj) {
if (prop === "face") {
if (obj[prop] === "A") {
return true;
}
}
}
}
}
return false;
}
const countHandValue = (cardsOnHand) => {
//console.log(hasAceInHand(cardsOnHand));
let sum = 0;
for (let key in cardsOnHand) {
let arr = cardsOnHand[key];
for (let i = 0; i < arr.length; i++) {
let obj = arr[i];
for (let prop in obj) {
if (prop === "faceValue") {
//console.log(prop + " = " + obj[prop]);
sum = sum + obj[prop];
debugger;
if (sum > 21 && hasAceInHand(cardsOnHand)) {
// Transfer Ace's face value from 11 to 1
sum = sum - 11;
sum = sum + 1;
}
}
}
}
}
return sum;
}
const showHandValue = () => {
document.getElementById("playerCardsHandValue").innerHTML = player.handValue;
document.getElementById("dealerCardsHandValue").innerHTML = dealer.handValue;
}
const getDeckCardCount = () => {
document.getElementById("deckCardCount").innerHTML = deck.cards.length;
}
const checkGameOver = () => {
if (gameOver) {
$(".holeCard > :nth-child(1)").show();
$(".holeCard > :nth-child(2)").show();
$(".holeCard").removeClass("holeCard");
$("#handValueDealer").show();
showGameButtons(false);
}
}
const checkEndGame1 = () => {
gameOver = true;
if (player.handValue === 21 && dealer.handValue !== 21) {
result.innerHTML = "BlackJack! Player won.";
player.isWinner = true;
} else if (player.handValue !== 21 && dealer.handValue === 21) {
result.innerHTML = "BlackJack! Dealer won.";
dealer.isWinner = true;
} else if (player.handValue === 21 && dealer.handValue === 21) {
result.innerHTML = "Push.";
} else {
gameOver = false;
}
}
const checkEndGame2 = () => {
if (player.cards.length <= 5 && player.handValue > 21) {
result.innerHTML = "Bust! Dealer won.";
dealer.isWinner = true;
gameOver = true;
}
}
const checkEndGame3 = () => {
if (player.cards.length <= 5 && dealer.cards.length <= 5) {
// Check bust
if (player.handValue <= 21 && dealer.handValue > 21) {
result.innerHTML = "Bust! Player won.";
player.isWinner = true;
} else if (player.handValue === 21 && dealer.handValue !== 21) {
result.innerHTML = "BlackJack! Player won.";
player.isWinner = true;
} else if (player.handValue !== 21 && dealer.handValue === 21) {
result.innerHTML = "BlackJack! Dealer won.";
dealer.isWinner = true;
} else if (player.handValue === dealer.handValue) {
result.innerHTML = "Push.";
} else if (player.handValue > dealer.handValue) {
result.innerHTML = "Player won.";
player.isWinner = true;
} else if (player.handValue < dealer.handValue) {
result.innerHTML = "Dealer won.";
dealer.isWinner = true;
} else {
result.innerHTML = "Error";
}
} else {
result.innerHTML = "Error";
}
gameOver = true;
}
// This function use JQuery lib
function makeCardPlayer(_card) {
// .card is created in the template card css class
var card = $(".card.templatePlayer").clone();
card.removeClass("templatePlayer");
// .cardFace is created in the template card css class
// It will search for this css class and add the content aka innerHTML
card.find(".playerCardFace").html(_card.face);
// .suit is created in the template card css class
// It will search for this css class and add the content aka innerHTML
card.find(".playerCardSuit").html("&" + _card.suit + ";");
// ♠ -> ♠, ♣ -> ♣, ♥ -> ♥, ♦ -> ♦
// more char, https://www.w3schools.com/charsets/ref_utf_symbols.asp
// hearts and diamonds are red color. otherwise, default black color.
if (_card.suit === "hearts" || _card.suit === "diams") {
card.addClass("red");
}
// option: replace previous card with new card (show one card all the time)
$("#cardContainerPlayer").append(card);
}
// This function use JQuery lib
function makeCardDealer(_card, _holeCard) {
// .card is created in the template card css class
var card = $(".card.templateDealer").clone();
card.removeClass("templateDealer");
// .cardFace is created in the template card css class
// It will search for this css class and add the content aka innerHTML
card.find(".dealerCardFace").html(_card.face);
// .suit is created in the template card css class
// It will search for this css class and add the content aka innerHTML
card.find(".dealerCardSuit").html("&" + _card.suit + ";");
// ♠ -> ♠, ♣ -> ♣, ♥ -> ♥, ♦ -> ♦
// more char, https://www.w3schools.com/charsets/ref_utf_symbols.asp
// hearts and diamonds are red color. otherwise, default black color.
if (_card.suit === "hearts" || _card.suit === "diams") {
card.addClass("red");
}
if (_holeCard) {
card.addClass("holeCard");
}
// option: replace previous card with new card (show one card all the time)
$("#cardContainerDealer").append(card);
$(".holeCard > :nth-child(1)").hide();
$(".holeCard > :nth-child(2)").hide();
}
const deal = () => {
debugger;
newDeck();
// Option: to burn first card before deal a card
// to the first player
burnOneCard;
dealOneCardToPlayer()
.then(dealOneCardToDealer)
.then(dealOneCardToPlayer)
.then(dealOneCardToDealer(true));
//dealOneCardToPlayer();
//dealOneCardToDealer(false);
//dealOneCardToPlayer();
//// true for hole card
//dealOneCardToDealer(true);
showGameButtons(true);
checkEndGame1();
checkGameOver();
}
const hit = () => {
dealOneCardToPlayer();
checkEndGame2();
checkGameOver();
}
const stand = () => {
// Recalculate dealer's hand value
//dealer.handValue = countHandValue(dealer.cards);
debugger;
// Simple AI to automate dealer's decision to hit or stand
if (dealer.handValue >= 17) {
checkEndGame3();
} else {
// Hit until dealer's hand value is more than 16
while (dealer.handValue < 17) {
dealOneCardToDealer();
checkEndGame3();
}
}
checkGameOver();
}
</script>
I think the right way to approach is with promises:
const DELAY = 2000;
function dealCardToPlayer() {
return new Promise(function(resolve) {
setTimeout(function() {
console.log('Dealing card to player');
resolve();
}, DELAY);
});
}
function dealCardToDealer() {
return new Promise(function(resolve) {
setTimeout(function() {
console.log('Dealing card to dealer');
resolve();
}, DELAY);
});
}
dealCardToPlayer()
.then(dealCardToDealer)
.then(dealCardToPlayer)
.then(dealCardToDealer);

JavaScript Todo List - When I click 'edit' button, it doesn't show input to be able to change a todo

I'm building a todo list in vanilla JavaScript as a part of the exercise. I'm trying to get the 'edit' option to function properly. When I click the 'edit' button, the corresponding text input should be enabled, and auto-selected, then the user should be able to press 'enter' to submit changes.
The problem is that I cannot make Edit functional. Two of the other buttons are working well.
I know that there is similar question allready, and I have tried what was in that question, and still cannot get it done. Please help guys.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<h1>To-do List</h1>
</header>
<input type="text" id="addTodoTextInput" onkeyup="todoButtons.addTodo()" placeholder="Add new todo" maxlength="80" autofocus>
<div>
<button onclick="todoButtons.toggleAll()">Toggle All</button>
<button onclick="todoButtons.deleteAll()">Delete All</button>
</div>
<ol>
</ol>
<script src="script.js"></script>
</body>
</html>
css
body {
display: flex;
flex-direction: column;
align-items: center;
background-color: #eee; /* Lightblue */
font-family: tahoma, sans-serif;
}
h1 {
font-weight: 100;
color: brown;
}
ol {
list-style-type: none;
padding-left: 0;
min-width: 30%;
}
li {
padding: 10px;
border-radius: 8px;
background-color: white;
box-shadow: 0 10px 50px black;
margin-top: 10px;
transition: all .3s ease;
overflow: hidden;
}
li:hover {
box-shadow: 0 10px 50px 3px black;
}
li button {
float: right;
}
button {
background-color: #bbb; /* Darkgrey */
font-weight: bold;
border-radius: 5px;
padding: 5px;
transition: all .3s ease;
cursor: pointer;
}
button:hover {
background-color: #d8d2d2; /* Grey */
color: brown;
}
/* Input for adding new todos */
#addTodoTextInput {
width: 30%;
margin-bottom: 20px;
}
js
var todoButtons = {
todos: [],
addTodo: function(e) {
// When Enter is pressed, new todo is made
if (e.keyCode === 13) {
var addTodoTextInput = document.getElementById('addTodoTextInput');
this.todos.push({
todoText: addTodoTextInput.value,
completed: false
});
// Reseting value after user input
addTodoTextInput.value = '';
todoView.displayTodos();
}
},
changeTodo: function(position, newTodoText) {
this.todos[position].todoText = newTodoText;
todoView.displayTodos();
},
deleteTodo: function(position) {
this.todos.splice(position, 1);
todoView.displayTodos();
},
toggleCompleted: function (position) {
var todo = this.todos[position];
todo.completed = !todo.completed;
todoView.displayTodos();
},
toggleAll: function() {
var totalTodos = this.todos.length;
var completedTodos = 0;
// Checks for a number of completed todos
this.todos.forEach(function(todo) {
if (todo.completed === true) {
completedTodos++;
}
});
this.todos.forEach(function(todo) {
// If all todos are true, they will be changed to false
if (completedTodos === totalTodos) {
todo.completed = false;
}
// Otherwise, they will be changed to true
else {
todo.completed = true;
}
});
todoView.displayTodos();
},
deleteAll: function() {
this.todos.splice(0, this.todos.length);
todoView.displayTodos();
}
};
// Function for displaying todos on the webpage
var todoView = {
displayTodos: function() {
var todosUl = document.querySelector('ol');
todosUl.innerHTML = '';
// Creating list element for every new todo
for (var i = 0; i < todoButtons.todos.length; i++) {
var todoLi = document.createElement('li');
var todoLiText = document.createElement('input');
todoLiText.type = "text";
todoLiText.disabled = true;
todoLiText.id = 'textInput';
var todoTextWithCompletion = todoButtons.todos[i].todoText;
if (todoButtons.todos[i].completed === true) {
todoLi.style.textDecoration = "line-through";
todoLi.style.opacity = "0.4";
todoLi.textContent = todoButtons.todoText + ' ';
}
else {
todoLi.textContent = todoButtons.todoText + ' ';
}
todoLi.id = i;
todoLiText.value = todoTextWithCompletion;
todoLi.appendChild(this.createDeleteButton());
todoLi.appendChild(this.createToggleButton());
todoLi.appendChild(this.createEditButton());
todoLi.appendChild(todoLiText);
todosUl.appendChild(todoLi);
};
},
// Method for creating Delete button for each todo
createDeleteButton: function() {
var deleteButton = document.createElement('button');
deleteButton.textContent = 'Delete';
deleteButton.className = 'deleteButton';
return deleteButton;
},
// Method for creating Toggle button for each todo
createToggleButton: function() {
var toggleButton = document.createElement('button');
toggleButton.textContent = 'Toggle';
toggleButton.className = 'toggleButton';
return toggleButton;
},
// Method for creating Edit button for each todo
createEditButton: function() {
var editButton = document.createElement('button');
editButton.textContent = 'Edit';
editButton.className = 'editButton';
return editButton;
},
// Event listeners gor the Delete, Edit and Toggle buttons
setUpEventListeners: function() {
var todosUl = document.querySelector('ol');
todosUl.addEventListener('click', function(event) {
var position = event.target.parentNode.id;
var elementClicked = event.target.className;
if (elementClicked === 'deleteButton') {
// Path to the ID of each created todo
todoButtons.deleteTodo(parseInt(position));
}
});
todosUl.addEventListener('click', function(event) {
var position = event.target.parentNode.id;
var elementClicked = event.target.className;
if (elementClicked === 'toggleButton') {
todoButtons.toggleCompleted(parseInt(position));
}
});
todosUl.addEventListener('click', function(event) {
var position = event.target.parentNode.id;
var elementClicked = event.target.className;
if (elementClicked === 'edit') {
var input = document.getElementById(position).childNodes[0];
input.disabled = false;
input.className = "activeTextInput";
input.focus();
input.select();
input.addEventListener('keyup', function(event) {
if(event.keyCode === 13) {
var textInput = input.value;
input.disabled = true;
input.classList.remove("activeTextInput");
todoButtons.changeTodo(position, textInput);
};
});
};
});
}
};
// Starting event listeners when the app starts
todoView.setUpEventListeners();
So, I looked at the code. The first problem is the condition:
if (elementClicked === 'edit') {
It should be:
if (elementClicked === 'editButton') {
The second problem was:
if (elementClicked === 'edit') {
var input = document.getElementById(position).childNodes[0]; //this line
input.disabled = false;
input.className = "activeTextInput";
It should be var input = document.getElementById(position).querySelector('input'); to get the correct element.
https://jsfiddle.net/nh9j6yw3/1/
Reason for "undefined" :
on line todoLi.textContent = todoButtons.todoText + ' ';
todoButtons.todoText is undefined.

Calculate the word amount from an <input>?

The following code converts text into equal paragraphs, based on the users input character amount.
Is it possible for the input box to calculate the amount of words for each paragraph instead of being based on the character amount?
JSFiddle
If an updated fiddle could please be provided, would be much appreciated, as I am still new to coding.
Thank You!
$(function() {
$('select').on('change', function() {
//Lets target the parent element, instead of P. P will inherit it's font size (css)
var targets = $('#content'),
property = this.dataset.property;
targets.css(property, this.value);
sameheight('#content p');
}).prop('selectedIndex', 0);
});
var btn = document.getElementById('go'),
textarea = document.getElementById('textarea1'),
content = document.getElementById('content');
chunkSize = 100;
btn.addEventListener('click', initialDistribute);
content.addEventListener('keyup', handleKey);
content.addEventListener('paste', handlePaste);
function initialDistribute() {
custom = parseInt(document.getElementById("custom").value);
chunkSize = (custom>0)?custom:chunkSize;
var text = textarea.value;
while (content.hasChildNodes()) {
content.removeChild(content.lastChild);
}
rearrange(text);
}
function rearrange(text) {
var chunks = splitText(text, false);
chunks.forEach(function(str, idx) {
para = document.createElement('P');
para.classList.add("Paragraph_CSS");
para.setAttribute('contenteditable', true);
para.textContent = str;
content.appendChild(para);
});
sameheight('#content p');
}
function handleKey(e) {
var para = e.target,
position,
key, fragment, overflow, remainingText;
key = e.which || e.keyCode || 0;
if (para.tagName != 'P') {
return;
}
if (key != 13 && key != 8) {
redistributeAuto(para);
return;
}
position = window.getSelection().getRangeAt(0).startOffset;
if (key == 13) {
fragment = para.lastChild;
overflow = fragment.textContent;
fragment.parentNode.removeChild(fragment);
remainingText = overflow + removeSiblings(para, false);
rearrange(remainingText);
}
if (key == 8 && para.previousElementSibling && position == 0) {
fragment = para.previousElementSibling;
remainingText = removeSiblings(fragment, true);
rearrange(remainingText);
}
}
function handlePaste(e) {
if (e.target.tagName != 'P') {
return;
}
overflow = e.target.textContent + removeSiblings(fragment, true);
rearrange(remainingText);
}
function redistributeAuto(para) {
var text = para.textContent,
fullText;
if (text.length > chunkSize) {
fullText = removeSiblings(para, true);
}
rearrange(fullText);
}
function removeSiblings(elem, includeCurrent) {
var text = '',
next;
if (includeCurrent && !elem.previousElementSibling) {
parent = elem.parentNode;
text = parent.textContent;
while (parent.hasChildNodes()) {
parent.removeChild(parent.lastChild);
}
} else {
elem = includeCurrent ? elem.previousElementSibling : elem;
while (next = elem.nextSibling) {
text += next.textContent;
elem.parentNode.removeChild(next);
}
}
return text;
}
function splitText(text, useRegex) {
var chunks = [],
i, textSize, boundary = 0;
if (useRegex) {
var regex = new RegExp('.{1,' + chunkSize + '}\\b', 'g');
chunks = text.match(regex) || [];
} else {
for (i = 0, textSize = text.length; i < textSize; i = boundary) {
boundary = i + chunkSize;
if (boundary <= textSize && text.charAt(boundary) == ' ') {
chunks.push(text.substring(i, boundary));
} else {
while (boundary <= textSize && text.charAt(boundary) != ' ') {
boundary++;
}
chunks.push(text.substring(i, boundary));
}
}
}
return chunks;
}
#text_land {
border: 1px solid #ccc;
padding: 25px;
margin-bottom: 30px;
}
textarea {
width: 95%;
}
label {
display: block;
width: 50%;
clear: both;
margin: 0 0 .5em;
}
label select {
width: 50%;
float: right;
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
font-family: monospace;
font-size: 1em;
}
h3 {
margin: 1.2em 0;
}
div {
margin: 1.2em;
}
textarea {
width: 100%;
}
button {
padding: .5em;
}
p {
/*Here the sliles for OTHER paragraphs*/
}
#content p {
font-size: inherit;
/*So it gets the font size set on the #content div*/
padding: 1.2em .5em;
margin: 1.4em 0;
border: 1px dashed #aaa;
overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<h3>Import Text below, then press the button</h3>
<textarea id="textarea1" placeholder="Type text here, then press the button below." rows="5">
</textarea>
<input style="width:200px;" id="custom" placeholder="Custom Characters per box">
<br>
<button style="width:200px;" id="go">Divide Text into Paragraphs</button>
</div>
<div>
<h3 align="right">Divided Text Will Appear Below:</h3>
<hr>
<div id="content"></div>
</div>
How about this? It uses jQuery, but as you used the library in your original submission, I hope that won't be an issue:
HTML
<textarea id="input"></textarea>
<br/>
<button id='divide'>Divide</button>
<div id="paras"></div>
CSS
#input {
resize: none;
height: 200px;
width: 100%;
}
JS
$(function() {
$("#divide").click(function() {
var text = $("#input").val();
var wpp = 10 // words per paragraph
var words = text.split(" ");
var paras = [];
for (i = 0; i < words.length; i += wpp) {
paras.push(words.slice(i, i + wpp).join(" "));
}
$.each(paras, function(i, para) {
$("#paras").append("<p>" + para + "</p>");
});
});
})
JSFiddle

Reset counter on spacebar and onclick

I'm trying to make a count-down that counts down from 200 to 0 in steps of 10.
This timer can be stopped and should then be reset to 200, however, I need also the value of the moment is stopped. The countdown fills the div #log with innerHTML. Whenever I "stop" the timer, I take the value of #log and place it in #price and I hide #log. The problem here is that the timer continues in the background, while I want it to reset so it can be started again by clicking on start. However, it just continues counting down and only after it's done, I can start it again.
In the example, it doesn't take so long for it to reach 0, but in the end, it'll take 15-20 seconds to reach 0, which'll be too long to wait for.
So in short: Countdown 200-0, but on click of Start-button or spacebar, it should stop the function running at the moment, so it can be started again.
See this PEN
If you have any suggestions on how to approach it completely different, you're very welcome to share!
HTML
<button id="btn" class="normal">Start</button>
<div id="log">#</div>
<div id="price"></div>
JS
var log = document.getElementById("log");
var btn = document.getElementById("btn");
var price = document.getElementById("price");
var counting = false;
var btnClassName = btn.getAttribute("class");
function start(count) {
if (!counting) {
counting = true;
log.innerHTML = count;
var timer = setInterval(function() {
if (count >= 0) {
log.innerHTML = count;
count -= 10;
} else {
clearInterval(timer);
count = arguments[0];
counting = false;
btn.className = "normal";
}
}, 150);
};
};
btn.onclick = function() {
if (btnClassName == "normal") {
start(200);
price.style.display = 'none';
log.style.display = 'block';
btn.className = "counting";
log.innerHTML = "";
} else {
}
};
document.body.onkeyup = function(e){
if(e.keyCode == 32){
price.innerHTML = log.innerHTML;
price.style.display = 'block';
log.style.display = 'none';
}
}
I "re-code" your code because there are several issues there.
Just read the code and tell me if that's you are looking for or if you have any questions..
var log = document.getElementById("log");
var btn = document.getElementById("btn");
var price = document.getElementById("price");
var counting = false;
var timer;
var c = 0;
function start(count) {
btn.blur();
if (!counting) {
c = count;
counting = true;
log.innerHTML = count;
timer = setInterval(tick, 1500);
tick();
};
};
function tick() {
if (c >= 0) {
log.innerHTML = c;
c -= 10;
}
else {
clearInterval(timer);
c = arguments[0];
counting = false;
btn.className = "normal";
}
}
btn.onclick = function() {
resetTimer();
var btnClassName = btn.getAttribute("class");
if (btnClassName == "normal") {
price.style.display = 'none';
log.style.display = 'block';
btn.className = "counting";
log.innerHTML = "";
start(200);
} else {
pause();
}
};
document.body.onkeyup = function(e) {
if(e.keyCode == 32) {
e.preventDefault();
pause();
}
}
function pause() {
resetTimer();
price.innerHTML = log.innerHTML;
price.style.display = 'block';
log.style.display = 'none';
btn.className = 'normal';
counting = false;
}
function resetTimer() {
clearInterval(timer);
}
body { font: 100% "Helvetica Neue", sans-serif; text-align: center; }
/*#outer {
width: 400px;
height: 400px;
border-radius: 100%;
background: #ced899;
margin: auto;
}
#inner {
width: 350px;
height: 350px;
border-radius: 100%;
background: #398dba;
margin: auto;
}*/
#log, #price {
font-size: 500%;
font-weight: bold;
}
<div id="outer">
<div id="inner">
<div id="arrow">
</div>
</div>
</div>
<button id="btn" class="normal">Start</button>
<div id="log">#</div>
<div id="price"></div>
Though you have already got your answer, you can try something like this:
Also I have taken liberty to reformat your code, and for demonstration purpose, have kept delay for interval as 1000
JSFiddle
function Counter(obj) {
var _initialVaue = obj.initialValue || 0;
var _interval = null;
var status = "Stopped";
var start = function() {
this.status = "Started";
if (!_interval) {
_interval = setInterval(obj.callback, obj.delay);
}
}
var reset = function() {
stop();
start();
}
var stop = function() {
if (_interval) {
this.status = "Stopped";
window.clearInterval(_interval);
_interval = null;
}
}
return {
start: start,
reset: reset,
stop: stop,
status: status
}
}
function init() {
var counterOption = {}
var count = 200;
counterOption.callback = function() {
if (count >= 0) {
printLog(count);
count -= 10;
} else {
counter.stop();
}
};
counterOption.delay = 1000;
counterOption.initialValue = 200
var counter = new Counter(counterOption);
function registerEvents() {
document.getElementById("btn").onclick = function() {
if (counter.status === "Stopped") {
count = counterOption.initialValue;
counter.start();
printLog("")
toggleDivs(counter.status)
}
};
document.onkeyup = function(e) {
if (e.keyCode === 32) {
printLog(counterOption.initialValue);
counter.stop();
toggleDivs(counter.status)
printPrice(count);
}
}
}
function printLog(str) {
document.getElementById("log").innerHTML = str;
}
function printPrice(str) {
document.getElementById("price").innerHTML = str;
}
function toggleDivs(status) {
document.getElementById("log").className = "";
document.getElementById("price").className = "";
var hideID = (status === "Started") ? "price" : "log";
document.getElementById(hideID).className = "hide";
}
registerEvents();
}
init();
body {
font: 100% "Helvetica Neue", sans-serif;
text-align: center;
}
.hide{
display: none;
}
#log,
#price {
font-size: 500%;
font-weight: bold;
}
<div id="outer">
<div id="inner">
<div id="arrow">
</div>
</div>
</div>
<button id="btn" class="normal">Start</button>
<div id="log">#</div>
<div id="price"></div>
Hope it helps!

Categories