So here's the code snippet
$(document).ready(function () {
var dmg = 60;
var curr_hp = 1200;
var tot_hp = 1200;
$('#attk_spd').text('1.2 seconds');
$('#dmg').text('60');
$('#curr_hp').text('1200');
$('#tot_hp').text('1200');
var dps_timer;
var attacking = 0;
$("#btn").click(function () {
if (dps_timer) {
// We're already waiting for the next attack, so do nothing
return;
}
$('#attk').text('You are currently attacking your target.');
$('#btn').val('Retreat');
var attack_once = function () {
// Always attack immediately
curr_hp -= dmg;
$('#curr_hp').text(curr_hp);
if (curr_hp > 0) {
dps_timer = setTimeout(attack_once, 1200);
} else if (attacking == 1) {
clearTimeout(attack_once);
attacking = 0;
alert(attacking);
$('#attk').text('You have retreated from battle.');
$('#btn').val('Attack');
} else {
attacking = 0;
alert(attacking);
$('#attk').text('Your target has been destroyed.');
$('#btn').val('Attack');
}
}
if (attacking == 0) {
attack_once();
attacking = 1;
alert(attacking);
}
});
});
I have alerts set up to check that the values are changing. This is basically a button click function. So when i click the button the first time the attacking starts and the button changes to retreat. However when i click retreat, the function should be executed again checking the conditionals, the attacking variable is set to 0 initially, changes to 1 when you click attack. So that if you click attack again it will run the second 'else if' conditional, but it doesn't. Help!
Code in action right here: http://www.evenstar-online.com/Jquery_snippets/dpsloop.php
attacking can never be 1 when attack_once is called because your if statement requires it to be 0 to run.
if (attacking == 0) {
//attacking is 0 when `attack_once()` is called
attack_once();
attacking = 1;
alert(attacking);
}
var attack_once = function () {
//.....
// this can never be 1
} else if (attacking == 1) {
Solution: Move your attacking = 1 up above the attack_once(); line
if (attacking == 0) {
attacking = 1;
attack_once();
alert(attacking);
}
Related
I have a JS code block just like below. the code will redirect user to login page after 30 sec but if the user clicks anywhere on the page the process will be reset. theoretically the code logic is true setInterval and EventListener both works fine but when I click somewhere in the page although global variable (counter) changes to 0 but (if) condition in the setInterval has no effects and still (counter) variable remain unchanged and the redirection will be happened!!!
var counter = 0;
setInterval(function() {
if (counter >= 30) {
// commented below line for testing with run code in stack overflow.
// In real code it will be uncommented.
// document.location = 'http://localhost/login';
console.log('redirect');
} else {
counter++;
}
}, 1000);
document.addEventListener('click', function(e) {
counter = 0;
}, true);
Your code should work
Here is a perhaps more understandable version using clearInterval
let secs = 5;
let tId;
function int() {
clearInterval(tId);
counter = secs;
tId = setInterval(function() {
if (counter <= 0) {
document.location = 'https://github.com';
} else {
counter--;
}
document.getElementById("x").innerText = counter
}, 1000);
}
document.addEventListener('click', int);
int()
<span id="x"></span>
So, I've been trying to figure out JS, and what better way to do so than to make a small project. It's a small trivia game, and it has a question timer I've made using setInterval. Unfortunately, after answering multiple questions, the interval's behaviour gets very weird - it runs the command twice every time. I guess it's my faulty implementation of buttonclicks?
By the way, if my code is awful I am sorry, I've been desperate to fix the issue and messed with it a lot.
function startGame(){
if (clicked === true){
return;
}
else{
$("#textPresented").html("Which anthem is this?");
$("#button").css("display", "none");
currentCountry = getRndInteger(0,8);
console.log(currentCountry);
var generatedURL = anthemnflags[currentCountry];
console.log(generatedURL);
audios.setAttribute("src", generatedURL);
audios.play();
$("#button").html("I know!");
$("#button").css("display", "block");
$("#button").click(function () {
continueManager();
});
y=10;
console.log("cleared y" + y);
x = setInterval(function(){
y = y - 1;
console.log("Counting down..." + y)
}, 1000);
console.log("INTERVAL SET");
}
}
Here is the console output:
cleared y10 flaggame.js:59:17
INTERVAL SET flaggame.js:64:17
AbortError: The fetching process for the media resource was aborted by the user agent at the user's request. flaggame.js:49
Counting down...9 flaggame.js:62:20 ---- THESE TWO ARE BEING PRINTED AT THE SAME TIME
Counting down...8 flaggame.js:62:20 ---- THESE TWO ARE BEING PRINTED AT THE SAME TIME
Counting down...7 flaggame.js:62:20
Counting down...6 flaggame.js:62:20
Counting down...5 flaggame.js:62:20
Counting down...4 flaggame.js:62:20
Counting down...3 flaggame.js:62:20
Counting down...2 flaggame.js:62:20
Counting down...1 flaggame.js:62:20
Counting down...0
THE REST OF MY CODE:
function middleGame(){
$("#button").css("display", "none");
var n = document.querySelectorAll(".flagc").length;
correctIMG = getRndInteger(0,n-1);
showFlags();
var taken = new Array();
for (var i = 0; i < n; ++i){
if (i === correctIMG){
images[i].attr("src", "res/" + flagsfiles[currentCountry]);
taken[currentCountry] = true;
}
else{
var randomFlag = getRndInteger(0, flagsfiles.length);
if (randomFlag !== currentCountry && taken[randomFlag] !== true){
images[i].attr("src", "res/" + flagsfiles[randomFlag]);
taken[randomFlag] = true;
}
}
}
$(".flagc").click(function(){
clickregister(this);
});
}
function continueManager(){
if (!clicked){
audios.pause()
clearInterval(x);
x = 0;
clicked = true;
middleGame();
return;
}
}
function clickregister(buttonClicked){
if ($(buttonClicked).attr("id") != correctIMG){
points = points - 1;
flagARR[$(buttonClicked).attr("id")].css("display", "none");
console.log("INCORRECT");
}
else{
if (y >= 0) {
var addedPoints = 1 + y;
points = points + addedPoints;
$("#points").html(points);
}
else{
points = points + 1;
}
hideFlags();
clicked = false;
startGame();
}
}
$(function(){
hideFlags();
$("#textPresented").html("When you're ready, click the button below!");
$("#button").html("I am ready!");
$("#button").click(function () {
if (!gameStarted){
gameStarted = true;
alert("STARTING GAME");
startGame();
}
});
});
Basically this is how it works:
When the "I am ready" button is clicked, startGame() is called. It plays a random tune and counts down, until the player hits the "I know" button. That button SHOULD stop the interval and start the middleGame() function, which shows 4 images, generates a random correct image and awaits input, checks if it's true, then launches startGame() again.
The first and second cycles are perfect - after the third one things get messy.
I also noticed that the "INCORRECT" log gets printed twice, why?
EDIT: here is the minimized code that has the same issue:
var x;
var gameStarted = false;
var y;
var clicked;
$(function(){
$("#button").click(function () {
if (!gameStarted){
gameStarted = true;
startGame();
}
});
});
function startGame(){
console.log("startgame()");
if (clicked === true){
return;
}
else{
console.log("!true");
$("#button").css("display", "block");
$("#button").click(function () {
continueManager();
});
y=10;
x = setInterval(function(){
y = y - 1;
console.log(y);
}, 1000);
}
}
function continueManager(){
if (!clicked){
clearInterval(x);
x = 0;
clicked = true;
middleGame();
return;
}
}
function middleGame(){
$("#button").css("display", "none");
var taken = new Array();
$(".flagc").click(function(){
clickregister(this);
});
}
function clickregister(buttonClicked){
console.log("clickgregister");
//Irrelevant code that checks the answers
clicked = false;
startGame();
}
EDIT2: It appears that my clickregister() function gets called twice, and that function then calls startGame() twice.
EDIT3: I have found the culprit! It's these lines of code:
$(".flagc").click(function(){
console.log("button" + $(this).attr("id") + "is clicked");
clickregister(this);
});
They get called twice, for the same button
I fixed it!
It turns out all I had to do was to add
$(".flagc").unbind('click');
Before the .click() function!
You need to clear the interval first then call it again. You can do that by creating a variable outside of the event listener scope and in the event listener check if the variable contains anything if yes then clear the interval of x. After clearing the interval you can reset it.
Something like this:
<button class="first" type="submit">Button</button>
const btn = document.querySelector('.first');
let x;
btn.addEventListener("click", () => {
x && clearInterval(x)
x = setInterval(() => console.log("yoo"), 500)
})
This is because if you don't clear the interval of x it will create a new one on every button press.
I have been trying to make a simple "smoothscroll" function using location.href that triggers on the mousewheel. The main problem is that the EventListener(wheel..) gets a bunch of inputs over the span of ca. 0,9 seconds which keeps triggering the function. "I only want the function to run once".
In the code below I have tried to remove the eventlistener as soon as the function runs, which actually kinda work, the problem is that I want it to be added again, hence the timed function at the bottom. This also kinda work but I dont want to wait a full second to be able to scroll and if I set it to anything lover the function will run multiple times.
I've also tried doing it with conditions "the commented out true or false variables" which works perfectly aslong as you are only scrolling up and down but you cant scroll twice or down twice.
window.addEventListener('wheel', scrolltest, true);
function scrolltest(event) {
window.removeEventListener('wheel', scrolltest, true);
i = event.deltaY;
console.log(i);
if (webstate == 0) {
if (i < 0 && !upexecuted) {
// upexecuted = true;
location.href = "#forside";
// downexecuted = false;
} else if (i > 0 && !downexecuted) {
// downexecuted = true;
location.href = "#underside";
// upexecuted = false;
}
}
setTimeout(function(){ window.addEventListener('wheel', scrolltest, true); }, 1000);
}
I had hoped there was a way to stop the wheel from constantly produce inputs over atleast 0.9 seconds.
"note: don't know if it can help in some way but when the browser is not clicked (the active window) the wheel will registre only one value a nice 100 for down and -100 for up"
What you're trying to do is called "debouncing" or "throttling". (Those aren't exactly the same thing, but you can look up the difference in case it's going to matter to you.) Functions for this are built into libraries like lodash, but if using a library like that is too non-vanilla for what you have in mind, you can always define your own debounce function: https://www.geeksforgeeks.org/debouncing-in-javascript/
You might also want to look into requestanimationframe.
a different approach
okey after fiddeling with this for just about 2 days i got fustrated and started over. no matter what i did the browsers integrated "glide-scroll" was messing up the event trigger. anyway i decided to animate the scrolling myself and honestly it works better than i had imagined: here is my code if anyone want to do this:
var body = document.getElementsByTagName("BODY")[0];
var p1 = document.getElementById('page1');
var p2 = document.getElementById('page2');
var p3 = document.getElementById('page3');
var p4 = document.getElementById('page4');
var p5 = document.getElementById('page5');
var whatpage = 1;
var snap = 50;
var i = 0;
// this part is really just to read what "page" you are on if you update the site. if you add more pages you should remember to add it here too.
window.onload = setcurrentpage;
function setcurrentpage() {
if (window.pageYOffset == p1.offsetTop) {
whatpage = 1;
} else if (window.pageYOffset == p2.offsetTop) {
whatpage = 2;
} else if (window.pageYOffset == p3.offsetTop) {
whatpage = 3;
} else if (window.pageYOffset == p4.offsetTop) {
whatpage = 4;
} else if (window.pageYOffset == p5.offsetTop) {
whatpage = 5;
}
}
// this code is designet to automaticly work with any "id" you have aslong as you give it a variable called p"number" fx p10 as seen above.
function smoothscroll() {
var whatpagenext = whatpage+1;
var whatpageprev = whatpage-1;
var currentpage = window['p'+whatpage];
var nextpage = window['p'+whatpagenext];
var prevpage = window['p'+whatpageprev];
console.log(currentpage);
if (window.pageYOffset > currentpage.offsetTop + snap && window.pageYOffset < nextpage.offsetTop - snap){
body.style.overflowY = "hidden";
i++
window.scrollTo(0, window.pageYOffset+i);
if (window.pageYOffset <= nextpage.offsetTop + snap && window.pageYOffset >= nextpage.offsetTop - snap) {
i=0;
window.scrollTo(0, nextpage.offsetTop);
whatpage += 1;
body.style.overflowY = "initial";
}
} else if (window.pageYOffset < currentpage.offsetTop - snap && window.pageYOffset > prevpage.offsetTop + snap){
body.style.overflowY = "hidden";
i--
window.scrollTo(0, window.pageYOffset+i);
if (window.pageYOffset >= prevpage.offsetTop - snap && window.pageYOffset <= prevpage.offsetTop + snap) {
i=0;
window.scrollTo(0, prevpage.offsetTop);
whatpage -= 1;
body.style.overflowY = "initial";
}
}
}
to remove the scrollbar completely just add this to your stylesheet:
::-webkit-scrollbar {
width: 0px;
background: transparent;
}
I'm building a clock inspired from the link below with added features like the single party button will play a music and change the BodyBGcolor per second.
https://codepen.io/codifiedconcepts/pen/bwgxRq
The music plays and pauses fine, but the BG starts changing but doesn't stop if I click to pause, and starts flickering and gets faster if I click the button again.
var partyTime = false;
var catMusic = new Audio("media/party.mp3");
function partyEvent() {
// partyTime and catMusic are defined outside
// otherwise they get re-defined without changing the old definition
if (partyTime === false) {
partyTime = true;
catMusic.play();
partyBtn.innerHTML = "PARTY OVER";
} else {
partyTime = false;
catMusic.pause();
partyBtn.innerHTML = "PARTY TIME";
}
}
var i = 0;
function changeBG() {
var color = ["red", "blue", "brown", "green"];
document.body.style.backgroundColor = color[i];
i = (i + 1) % color.length;
if (partyTime === true) {
var initBG = setInterval(changeBG, 1000);
} else {
clearInterval(initBG);
}
}
I have another function which changes the BGcolor 5 times in a day, for morning, noon, evening etc.. as a switch statement, I'm showing one case here..
switch (true) {
case hour <= 5:
imgTxt.innerHTML = "GET SOME SLEEPZ BRO";
catImg.style.background = "url('img/earlyMorning.jpg')";
catImg.style.backgroundSize = "cover";
document.body.style.backgroundColor= "#2d3037";
clockBody.style.color = "#99ffcc";
break;
please help this noob, and sorry for the indentation, it gets all same after pasting here..
if (partyTime === true) {
var initBG = setInterval(changeBG, 1000);
} else {
clearInterval(initBG);
}
Here you are creating initBG local to if block. In the else block initBG is undefined so it does not stop the interval process.
Solution: Define initBG outside the partyEvent function.
var initBG;
if (partyTime === true) {
initBG = setInterval(changeBG, 1000);
} else {
clearInterval(initBG);
}
I have been trying for a good minute to figure out why my if statement never triggers. Any help would be much appreciated!
var clickcounter = 0;
var buttonclicker = document.getElementById("buttonclicker");
function unblur() {
clickcounter = clickcounter + 1;
console.log(clickcounter);
}
if (clickcounter === 1) {
buttonclicker.textContent = "Unlock More";
alert(clickcounter);
}
the variable clickcounter will be equal to or over 1. I at first tried using if (clickcounter => 1) and also tried if (clickcounter > 0) but none of this worked. What am I doing wrong?
Here is a codepen of the whole thing: https://codepen.io/sage379/pen/JyppZv
Based on your code example, unblur() never gets called so clickcounter remains 0.
Please try with the below code snippet. Let me know if i did not understand your requirement.
var clickcounter = 0;
var buttonclicker = document.getElementById("buttonclicker");
function unblur() {
clickcounter = clickcounter + 1;
console.log(clickcounter);
if (parseInt(clickcounter) >= 1){
buttonclicker.textContent = "Unlock More";
}
}
Put your if statement inside of unblur:
var clickcounter = 0;
var buttonclicker = document.getElementById("buttonclicker");
function unblur() {
clickcounter = clickcounter + 1;
console.log(clickcounter);
if (clickcounter === 1) {
buttonclicker.textContent = "Unlock More";
alert(clickcounter);
}
}
The problem is that once you increment clickcounter, you never check if it's changed. That check is performed once in your script, immediately after setting clickcounter = 0.
Here is an example where I've wrapped that check in a new function called checkClickCounter(). This function is called in unblur() each time it is called by your button click. I changed your if statement back to >= but since you're incrementing by one it will always return true after one click using === so this change doesn't matter in your current code.
var clickcounter = 0;
var buttonclicker = document.getElementById("buttonclicker");
function unblur() {
clickcounter = clickcounter + 1;
checkClickCounter(clickcounter);
}
function checkClickCounter(count){
if (count >= 1) {
buttonclicker.textContent = "Unlock More";
//alert(clickcounter);
}
}