I want to use a button to display a text with the styles and to revert to the original text when I click the button again. I have done the first part which is to display the text but I cant revert back to the original text. This is what I have so far:
function myFunction() {
document.getElementById("second").innerHTML = "Hello Javascript";
document.getElementById("second").style.fontSize = "25px";
document.getElementById("second").style.color = "red";
}
<button type="button" onclick="myFunction()">Click here</button>
<p id="second">This is me</p>
Declaring a a variable let count = 1; outside the function which will help me to check the state i am in currently in.so first i assigned the value of 1 to it.
in my function i am saying is count is equal to 1 change it to Hello Javascript with other properties and change count to zero.so when you click the next time count is now zero and the first if gets rejected instead it goes to the second if else
condition and makes it this is me and changes count to 1 this time.
basically changing the text with count as a statemanagement.
let count = 1;
function myFunction() {
if (count == 1) {
document.getElementById("second").innerHTML = "Hello Javascript";
document.getElementById("second").style.fontSize = "25px";
document.getElementById("second").style.color = "red";
count = 0;
} else if (count == 0) {
document.getElementById("second").innerHTML = "This is me";
document.getElementById("second").style.fontSize = "16px";
document.getElementById("second").style.color = "black";
count = 1;
}
}
<button type="button" onclick="myFunction()">Click here</button>
<p id="second">This is me</p>
perhaps using sequence style 😉
const sequence = [
['This is me', '20px', 'blue'],
['Hello Javascript', '25px', 'red'],
['stackoverflow', '50px', 'green'],
];
let index = 0;
function myFunction() {
const element = document.getElementById("second");
element.innerText = sequence[index][0];
element.style.fontSize = sequence[index][1];
element.style.color = sequence[index][2];
// increment the index then wrap index to the start when needed
index = (index + 1) % sequence.length;
}
// intialize
myFunction();
One way to do so would be to toggle your styles on the element. The code to do so is given below.
function myFunction() {
document.getElementById("second").classList.toggle("mystyle");
}
.mystyle {
font-size: 25px;
color: red;
}
<button type="button" onclick="myFunction()">Click here</button>
<p id="second">This is me</p>
<!DOCTYPE html>
<html>
<script>
var count = 0;
function myFunction() {
count += 1;
if (count % 2 > 0) {
document.getElementById("second").style.fontSize = "25px";
document.getElementById("second").style.color = "red";
document.getElementById("second").innerText = "Hello Javascript";
} else if (count % 2 == 0) {
document.getElementById("second").style.fontSize = "15px";
document.getElementById("second").style.color = "black";
document.getElementById("second").innerText = "This is me";
}
}
</script>
<body>
<button type="button" onclick="myFunction()">Click here</button>
<p id="second">This is me</p>
</body>
</html>
You should store the button style somewhere, and you should store your element reference, interrogating the DOM is performance consuming.
You can get compute styles with window.getComputedStyle(element)
Something like
const buttonRef = document.getElementById("second")
const buttonDefaultStyle = window.getComputedStyle(buttonRef)
const isDefaultStyle = true
let buttonInnerHTML = "text"
function myFunction() {
if (isDefaultStyle) {
buttonRef.innerHTML = "Hello Javascript";
buttonRef.style.fontSize = "25px";
buttonRef.style.color = "red";
isDefaultStyle = false;
} else {
buttonRef.innerHTML = buttonInnerHTML;
buttonRef.style.fontSize = buttonDefaultStyle.fontSize;
buttonRef.style.color = buttonDefaultStyle.color;
isDefaultStyle = true;
}
}
You have to pardon me, as I'm still learning JS, but I thought i'd give it a try as an exercise. There are probably simpler ways to do this, but this is what I came up with.
For a faux 'boolean', if you will, you can go through even and odd numbers with a counter increasing each time you press the button. If left to its own devices, a counter will go to infinity, so adding an if clause (or a case switch, could be either), for the counter if it goes above a certain number will keep it reasonable.
Rather than adding font styles, I think it would be easier to toggle between classes, that way you can just edit the CSS instead of having to go change JS every time you want to change the output style of one of the states.
Using an event listener instead of an onclick assigned to the html Button tag will allow the function to count up the clicks, because essentially the function is continually running instead of just firing once every time the button is clicked.
let counter = 0; //establishing the counter
button.addEventListener("click", function() { //using an event listener instead of an onclick event allows the function to continually run instead of firing once each time the button is clicked
let button = document.querySelector("#button");
let print1 = 'Goodbye Foo'; //making the change state the first state assigned by the click means that the content will in fact change the first time you click the button, which took me a hot second to figure out
let print2 = 'Hello World';
let printer = document.getElementById('second');
if (counter % 2 == 0) { //if the counter, when divided by two has a remainder of 0
printer.innerHTML = print1; //then print "print1" as the inner html
printer.classList.replace('print2', 'print1'); //and toggle the classes
} else { //else, if the remainder of the counter divided by 2 is not zero
printer.innerHTML = print2; //print the other state
printer.classList.replace('print1', 'print2'); //and replace the css
}
if (counter >= 9) { //if the counter ever gets to 9 (an odd number)
counter = 0; //then restart the counter at zero (which gives a remainder of 0, making it "even" in this case
} else {
counter++; //otherwise count up one each time the button is pressed
}
});
.print1 {
color: red;
font-size: 24px;
}
.print2 {
color: blue;
font-size: 12px;
}
<button id="button" type="submit">
Click me
</button>
<p id="second" class="print2">
Hello World
</p>
here it is in jsfiddle:
https://jsfiddle.net/slingtruchoice/wkt3pz9v/
you can switch from a class to another using toogle to change the style like this :
document.getElementById("second").classList.toggle("mystyle");
and you keep inner-html to change the text like this:
if (document.getElementById("second").innerHTML === "Click here")
{
document.getElementById("second").innerHTML = "Hello Javascript";
} else {
document.getElementById("second").innerHTML = "Click here";
}
I eventually used this and it worked perfectly fine for me. it also changed the text on the button as well.
let count = 1;
function mySecond() {
if (count == 1) {
document.getElementById("button3").innerHTML = "Hello Javascript";
document.getElementById("button3").classList.toggle("myStyle");
document.getElementById("button2").innerHTML = "Back";
count = 0;
} else if (count == 0) {
document.getElementById("button3").innerHTML = "This is the best";
document.getElementById("button3").classList.toggle("myStyle");
document.getElementById("button2").innerHTML = "Start";
count = 1;
}
}
<button id="button2" onclick="mySecond()">Start</button>
<p id="button3">This is the best</p>
.myStyle {
color: brown;
}
Related
I am trying to build a gambling simulator that lets you gamble with fake money to see if you'd win more often times than not. The game I am sort of trying to replicate is Mines from Roobet. In my game, there are 9 squares laid out in a grid like format. One of the squares is the bomb square, which means if you click it, you lose. The player does not know which square is the bomb square though. You have to click 4 squares, and if all of the ones you have clicked are non-bomb squares, then you win $50. If you click the bomb square, then you lose $50.
What I have been trying to figure out for like a week now is how do you make the game wait until either 4 non-bomb squares have been clicked, or 1 bomb square to have been clicked in order to do certain functions(subtract 50 from gambling amount, restart the game). I have tried while loops, but that crashes the browser. I have also tried if-else statements, but the code doesn't wait until either 4 non-bomb squares or 1 bomb square has been clicked. It just checks it instantly. So it results in it not working right. I also have tried for the function to call itself, and then check for either case, but it just results in an error saying "Maximum call stack size exceeded."
function bombClicked () {
for (let i = 0; i < array.length; i++) { //each square is put into an array named array
array[i].addEventListener("click", () => {
if (array[i].value == "bomb") {
array[i].style.background = "red";
redCounter++;
didLose = true
}
else{
array[i].style.background = "green";
greenCounter++;
didLose = false;
}
})
}
if (greenCounter >= 4 || redCounter >= 1) {
if (didLose == true) {
gamblingAmount.value = parseInt(gamblingAmount.value) - 50;
}
else {
gamblingAmount.value = parseInt(gamblingAmount.value) + 50;
}
reset();
}
}
What a fun little exercise! Here's my quick and dirty jquery solution.
const NO_OF_TRIES_ALLOWED = 4;
const SCORE_WON_LOST = 50;
var score = 0;
var tries = 0;
var bombId;
function restart() {
tries = 0;
$("button").removeClass("ok");
$("button").removeClass("bang");
bombId = Math.floor( Math.random() * 9);
$("#bombLabel").text(bombId);
}
function win() {
window.alert('you win!');
score += SCORE_WON_LOST;
$("#scoreLabel").text(score);
restart();
}
function lose(){
window.alert('you lose!');
score -= SCORE_WON_LOST;
$("#scoreLabel").text(score);
restart();
}
$(document).on("click", "button", function() {
if( !$(this).is(".bang") && !$(this).is(".ok") ) {
let buttonId = $(this).data("id");
if(buttonId === bombId) {
$(this).addClass('bang');
setTimeout(lose, 100); // bit of a delay before the alert
}
else {
$(this).addClass('ok');
tries++;
if(tries === NO_OF_TRIES_ALLOWED) {
setTimeout(win, 100); // bit of a delay before the alert
}
}
}
});
restart();
button{
width: 50px;
height: 50px;
padding: 0;
}
.ok{
background-color: green;
}
.bang{
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button data-id="0"></button>
<button data-id="1"></button>
<button data-id="2"></button><br>
<button data-id="3"></button>
<button data-id="4"></button>
<button data-id="5"></button><br>
<button data-id="6"></button>
<button data-id="7"></button>
<button data-id="8"></button><br>
Score: <span id="scoreLabel"></span>
It looks like you need some sort of state. I don't know what the rest of your code looks like, but maybe creating a helper to keep track of your counts might help:
class Counter {
constructor() {
this.count = 0;
}
inc() {
this.count ++;
}
getCount() {
return this.count
}
}
const counter = new Counter();
counter.inc();
counter.inc();
counter.inc();
counter.getCount(); // 3
Javascript should keep this in memory for you. I might have to see the rest of your code to understand how exactly to fix the issue, but maybe this will put you on the right track!
This is my code and it runs, but I have to change the background color to red when the counter reaches zero.
<script>
window.onload = function () {
const tag = document.getElementById("tag1");
var time = 100;
const getTime = ()=>{
time = time - 1;
tag.innerHTML = "Goodbye Aliens: ship leaves in " + time + " secs ";
}
setInterval(getTime, 500);
}
</script>
<body>
<div>
<h1 id="tag1">Hello Earthling</h1>
</div>
</body>
<script>
const tag = document.getElementById("tag1");
tag.innerHTML = "Goodbye Aliens";
</script>
</html>
I thought of something like this in order to do it:
function changeColor() {
if (time == 0) {
document.change.bgColor = "red";
}
}
but it does not work and I do not understand where to put the code in the first place.
Please explain if someone has time. Thanks
My approach would be to check the time variable inside the GetTime method and calling changeColor when its 0.
Then you need to clear the interval using clearInterval to stop the loop.
function changeColor() {
document.querySelector("body").style.backgroundColor = "red";
}
window.onload = function () {
const tag = document.getElementById("tag1");
var time = 10;
const getTime = () =>{
time = time - 1;
tag.innerHTML = "Goodbye Aliens: ship leaves in " + time + " secs ";
if(time === 0){
changeColor();
window.clearInterval(interval);
}
}
var interval = setInterval(getTime, 500);
}
const tag = document.getElementById("tag1");
tag.innerHTML = "Goodbye Aliens";
<div>
<h1 id="tag1">Hello Earthling</h1>
</div>
I tend to favour setTimeout over setInterval. It seems more managable.
Note: I've used a class here instead of directly setting the style on the element.
const tag = document.getElementById('tag1');
// `getTime` accepts a time argument which
// we initialise as 100
function getTime(time = 100) {
// Print the message using `textContent` rather than `innerHTML`
tag.textContent = `Goodbye Aliens: ship leaves in ${time} secs`;
// If time reaches 0 set the background to red using a class
if (time === 0) {
tag.classList.add('red');
// Otherwise call `getTime` again passing in a decremented
// `time` value as the argument
} else {
setTimeout(getTime, 50, --time);
}
}
// Call `getTime` after showing the initial message
setTimeout(getTime, 2000);
.red { background-color: red; }
<div>
<h3 id="tag1">Hello Earthling</h3>
</div>
I have a function that chooses a random string from an array and types it in a paragraph. I trigger this function by pressing a button.
var myArray = ['something', 'something else', 'another thing',];
var rand = myArray[Math.floor(Math.random() * myArray.length)];
var i = 0;
var speed = 55;
function typeWriter() {
if (i < rand.length) {
document.getElementById("question").innerHTML += rand.charAt(i);
i++;
setTimeout(typeWriter, speed);
}
}
<button class="button next" id = "next" onclick="typeWriter()"> Next</button>
<p id="question"></p>
Pressing the "next" button triggers the typeWriter function, which chooses a random string from myArray and begins to type it in the paragraph "question". What I want to happen is, upon pressing "next" again (either while the typing is going on or after the typing is done), the text that has been typed already is deleted and the typeWriter triggers again, choosing another string and typing it in paragraph "question".
You want something like this?
var myArray = ['something', 'something else', 'another thing',];
var speed = 100;
var target = document.getElementById("question");
var char;
var timer;
var sentence;
function type(){
if(char < sentence.length) {
target.innerHTML += sentence.charAt(char++);
} else {
clearInterval(timer);
}
}
function reset() {
clearInterval(timer);
sentence = myArray[Math.floor(Math.random() * myArray.length)];
char = 0;
target.innerHTML = '';
}
function typeWriter() {
reset();
timer = setInterval(type, speed);
}
<button class="button next" id = "next" onclick="typeWriter()"> Next</button>
<p id="question"></p>
The setTimeout you have used implies that each time a character is "pressed", a new timer is started. My approach is to use an interval timer, which is simply writing the next character until the sentence ends or the typewriter is reset. In these two cases, the timer is cleared.
if you are fetching random string then you need to write that code inside your function.
please try below solution.
<button class="button next"
id = "next"
onclick="typeWriter()">
Next
</button>
<p id="question"></p>
<script>
var myArray = ['a', 'b', 'c',];
var i = 0;
var speed = 55;
function typeWriter() {
var rand = myArray[Math.floor(Math.random() * myArray.length)];
if (i < rand.length) {
document.getElementById("question").innerHTML = rand.charAt(i);
i++;
setTimeout(typeWriter, speed);
}
else
{
i--;
}
}
</script>
I am making a website that whenever I click and x is equal to a range of numbers, it plays audio, but after i click once when x is between those numbers, i will also play if x is not in the range. Please Help. Here is my code. by the way, i will not use jquery because it does not work on chrome.
if(x<=1200&&x>=600){
var n=true;
};
if(x<=1200&&x>=600&&n==true){
document.getElementById('a').onclick = function(){
audio.play();
n=false;
}
}
else{n=false}
What your code does is that it adds a click event listener on that element, and afterwards the click handler will trigger regardless of your x value because you don't have any checks inside the click handler.
The solution is to do create the click listener only once, and check for the value of x inside it. Something like this:
document.getElementById('a').onclick = function(){
if(x <= 1200 && x >= 600 && n == true) {
audio.play();
n = false;
}
}
See this (I've replaced audio playing with div highlighting, but it's the same principle):
var r = document.getElementById('r');
var n = true;
var x = 1000;
document.getElementById('a').onclick = function(){
if(x <= 1200 && x >= 600 && n == true) {
r.className = 'playing';
n = false;
printN();
setTimeout(function(){
r.className = '';
}, 2000);
}
}
function toggleN(){n = !n;printN()}
function printN(){document.getElementById('n').textContent = 'n is set to ' + n;}
function randomizeX(){x = Math.floor(Math.random() * 1200);printX()}
function printX(){document.getElementById('x').textContent = 'x equals ' + x;}
#r {display: inline-block; width: 50px; height: 50px; background: #ccc; transition: background 1s linear;}
#r.playing {background: green}
<button id="a">Hit me</button><br><br>
<div id="r"></div>
<p id="x">x equals 1000</p>
<p id="n">n is set to true</p>
<button onclick="toggleN()">Toggle n</button>
<button onclick="randomizeX()">Randomize x</button>
I'm not quite sure what you're trying to do but here a guest :
if(x<=1200&&x>=600){
var n=true;
var clicked = false;
};
if(x<=1200&&x>=600&&n==true || clicked==true){
document.getElementById('a').onclick = function(){
audio.play();
n=false;
clicked = true;
}
}
else{
n=false;
clicked = false;
}
This should do what you want, if i understood you correctly.
no reason to check x several times + check n, since n is only true if x is between your ranges.
var ab = document.getElementById('a');
var n = false;
if( x <= 1200 && x >= 600 ){
n = true; //If x is within range.
} else {
n = false; //Reset when x goes out of range.
}
ab.onclick = function(){
if(n){
audio.play();
}
}
Note: If a user clicks the button several times,
the audio plays several times.
This can be fixed by adding another variable checking if a user already clicked once,
Since i don't know your setup, i.e. should users be able to click to play the audio several times in a row(when it finish playing once), i can't supply you with a solution for that without knowing.
I'm creating a counter and I'm having a hard time making it.
The goal of the counter is that for ever second passed a number will increase by 170.
As you can see below the number does not add up and is made on a new line, mostly because I dont know how to make it add up. Some thing like this clock from The Economist
<!DOCTYPE html>
<html>
<body>
<p>Click the button see how much AirHelps market increases by every second.</p>
<button onclick="counterFunction()">See it now</button>
<p id="counter"></p>
<script>
function counterFunction() {
setTimeout(function () {
var text = "";
var i = 170;
while (i < 3500) {
text += "<br>The number is " + i;
i+=170;
}, 1000) }
document.getElementById("counter").innerHTML = text;
}
</script>
</body>
</html>
Any ideas on how I can make this and what is wrong with my code?
Don't use inline JavaScript (JavaScript inside HTML element attributes), it is horrible for maintainability and readability.
You seem to have a misconception about how timeouts, intervals and while loops work, what you want is an interval.
Define a count variable outside of the event listener function, then on each iteration of the interval increment the count variable by one and multiply that number by 170.
I added a little bit in there to hide the button once it has been clicked, just to stop the user from restarting the counter.
var clicker = document.getElementById('clicker');
var counter = document.getElementById('counter');
var count = 0;
clicker.onclick = function() {
setInterval(function () {
counter.textContent = "The number is " + ++count * 170;
}, 1000);
clicker.style.display = 'none';
}
<p>Click the button see how much AirHelps market increases by every second.</p>
<button id="clicker">See it now</button>
<p id="counter"></p>
http://jsfiddle.net/mblenton/Le4vxzrn/2/
function counterFunction() {
var text = ""; var i = 170; var delay = 0; var k = 1;
while (i < 3500) {
text = "The number is " + i;
i += 170;
delay = k * 1000;
doSetTimeout(text, delay);
k++;
}
}
function doSetTimeout(text, delay) {
setTimeout(function () {
document.getElementById("counter").textContent = text;
}, delay);
}
You need to use setInterval, not setTimeout`. Note that if you click the button, it will reset your timer.
You also need to declare var i and var text outside the scope of the Interval, or they will also be reset each iteration.
There were a few things wrong with your code. Among other things:
your i variable was declared in the wrong place to be reused
your closing braces were in the wrong place for the callback function
you were using a while loop, which runs synchronously, whereas you really want to just use a setInterval call.
This should work:
function counterFunction() {
var i = 170;
var text = "";
var interval = setInterval(function () {
text += "<br>The number is " + i;
i+=170;
document.getElementById("counter").innerHTML = text;
if (i >= 3500) {
clearInterval(interval);
}
}, 1000);
}
<p>Click the button see how much AirHelps market increases by every second.</p>
<button onclick="counterFunction()">See it now</button>
<p id="counter"></p>
Ok so the adder variable should be declared outside of the timeout function, because if not you are replacing the value. and you should use setInterval
var p =0;
function counterFunction(){
setInterval(function(){ p+=170;
console.log('value of p '+p);
}, 3000);
}
if you dont want to roll your own here is a nice counter
http://keith-wood.name/countdown.html