I try to click on btn3 ( kashef) and it's not triggering my function
kashef()
My code is here: https://jsfiddle.net/erezdav12/gn8shkrm/100/
I need that by clicking on button kashef, my running counter (its a
money counter) will subtract by, lets say, 300$ (cost of clicking
to get the feature) e.g: if money roller is in 1000$ on the
moment of clicking event on "kashef" button, money counter reduce
to 700 $ and continue running until the next clicking.
Here is the code:
let start;
const el = document.getElementById('count');
const final = parseInt(el.textContent, 10);
const duration = 100000;
const kashefButton= document.getElementById("btn3");
kashefButton.addEventListener("click", kashef);
function kashef(){
document.getElementById('count').innerHTML=1000-300;
}
const step = ts => {
if (!start) {
start = ts;
}
let progress = (ts - start) / duration;
el.textContent = Math.floor(progress * final) * 100 ;
time = +el.textContent;
if( progress < 1){
requestAnimationFrame(step);
}
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
var btn3 = document.getElementById('btn3');
const OpentButtons = 200;
if (time <= OpentButtons) {
btn1.disabled = true;
btn2.disabled = true;
btn3.disabled = true;
} else {
btn1.disabled = false;
btn2.disabled = false;
btn3.disabled = false;
}
}
requestAnimationFrame(step);
big thanks !!!!
This is a scoping issue. The definition of kashdef is not defined in a scope that the event listener can find it in. Move the definition of kashef outside of the ts block (right after "const duration = 100001;" ) and it works (verified in your fiddle).
Related
hi everyone!
i have a map with dots MAP which every 3 seconds shows a block with info
a function that is already in progress, and I want the function to stop when clicking on a point and display an infoblock for me(and i did it).
sorry in advance below is my code
// map with dots
var isActive = 0;
var isLoading = 1;
const count = document.querySelectorAll("[data-id]");//circle svg around dot
function removeClass() {
let infoCards = document.querySelectorAll("[data-info-id]");// info page name of the project
infoCards.forEach((el) => {
el.classList.remove("show");
});
}
function removeCircle() {
count.forEach((el) => {
el.style.display = "none";
});
}
function ready() {
function setAround(percent, idx) {
removeCircle();
let beforeElemIdx = idx === 0 ? count.length - 1 : idx - 1;
let beforeElem = document.querySelector(
'[data-id="' + beforeElemIdx + '"]'
);
let elem = document.querySelector('[data-id="' + idx + '"]');
elem.style.display = "block";
elem.classList.remove('active-circle');
beforeElem.style.display = "block";
const math = 2 * Math.PI * elem.r.baseVal.value;
elem.style.strokeDasharray = `${math} 1000`;
let a = math * (1 - percent / 100);
elem.style.strokeDashoffset = a;
if (percent >= 99.5) {
removeClass();
let infoShow = document.querySelector(`[data-info-id="${idx}"]`);
infoShow.classList.add("show");
isLoading++;
if (isLoading === count.length) {
isLoading = 0;
}
}
}
requestAnimationFrame(draw);
function draw(t) {
let idx = isLoading;
requestAnimationFrame(draw);
setAround((t / 30) % 100, idx);//timer 3sec
}
}
document.addEventListener("DOMContentLoaded", ready);
and i did this
var dots = document.querySelectorAll(".dota");
var infoCards = document.querySelectorAll("[data-info-id]");
let circle = document.querySelectorAll('[data-id]');
dots.forEach((el) => {
el.addEventListener('click', () => {
let idx = el.dataset.dota;
let circle = el.dataset.dota;
showInfo(idx);
addCircle(idx);
});
});
function showInfo(idx) {
removeClass();
let elem = document.querySelector(`[data-info-id='${idx}']`);
elem.classList.add('show');
}
function addCircle(idx) {
let circle = document.querySelector(`[data-id='${idx}']`);
circle.classList.add('active-circle');
}
and if u want my site pls dm me i'll send my github page
PUG CODE
TY ALL!
Have you tried making a condition into the drawing function that pauses it?
If it's paused you can call another function that will draw the info of the specific dot only once and then create a condition in which it will resume the drawing normally.
When I used drawing function I've simply added a bool variable that stored if paused or not in the recursive function.
I have this code here and i want the background to stop changing when i click the same button (the interval to stop). But i cannot work my way around it.(The else part works because in the console isCicked changes it's value).
let btn = document.querySelector('#btn');
let body = document.querySelector('body');
let isClicked = false;
btn.addEventListener('click', function(){
let x;
let y;
if(isClicked == false){
isClicked = true;
x= setInterval(function(){
let r,g,b;
r = Math.round(Math.random() * 255);
g = Math.round(Math.random() * 255);
b = Math.round(Math.random() * 255);
body.style.backgroundColor = `rgb(${r},${g},${b})`;
btn.classList.toggle('button-style')
},1000)
}else{
isClicked = false;
clearInterval(x);
}
console.log(isClicked);
})
<button type="button" id="btn">Click</button>
To fix your current code you need to declare x outside the event listener since as it stands you redeclare it on each click and overwrite your stored interval id.
let isClicked = false;
let x;
btn.addEventListener('click', function(){
if(isClicked == false){
isClicked = true;
x = setInterval(function(){
...
}
But you can actually simplify a little by combining isClicked and x and just checking if an interval is stored.
let btn = document.getElementById('btn');
let body = document.querySelector('body');
let interval = null;
btn.addEventListener('click', function () {
if (interval === null) {
interval = setInterval(function () {
let r, g, b;
r = Math.round(Math.random() * 255);
g = Math.round(Math.random() * 255);
b = Math.round(Math.random() * 255);
body.style.backgroundColor = `rgb(${r},${g},${b})`;
btn.classList.toggle('button-style');
}, 1000);
} else {
clearInterval(interval);
interval = null;
}
console.log(interval);
});
<button type="button" id="btn">Click</button>
Rather then trying to manage the state of setInterval, you could use setTimeout and recursion (a function calling itself) to create an interval. Likewise, rather than using variable mutation, since you're toggling a class on the button, you can just use the button itself as the exit condition for the recursion.
let btn = document.querySelector('#btn'),
body = document.querySelector('body');
function ChangeBackground() {
if (btn.classList.contains('button-style')) { //check exit condition
body.style.backgroundColor = '#' + Math.random().toString(16).slice(-6);
setTimeout(ChangeBackground, 1000); //recursion
}
}
btn.addEventListener('click', function(){
this.classList.toggle('button-style'); //toggle exit condition
ChangeBackground(); //start recursion
});
<button type="button" id="btn">Click</button>
I'm trying to add stars (images) to a class with JS.
function putStars(){
if(test){
for(var i = 0; i < 5; i++){
var star = document.createElement("img");
star.src = "star.png";
var element = document.querySelector(".java");
element.append(star);
}
test = false;
}
}
So as you can see I add images to the class Java, but what I want to do is adding images but a waiting effect between each image and not just a block of 5 images.
I found the setTimeOut function but I'm not sut if it's the best way to do this.
You can basically replace your for-loop with setInterval like this to achieve a time delay between each iteration.
let i = 0;
const interval = setInterval(() => {
i++;
var star = document.createElement("img");
star.src = "star.png";
var element = document.querySelector(".java");
element.append(star);
if (i === 5) { clearInterval(interval); } // <- after 5 iterations clear the interval
}, 1000); // <- this 1000 is 1 sec. delay
Although you can move var element = document.querySelector(".java"); outside of the interval so that you don't search for it more than once since it is unnecessary.
let i = 0;
var element = document.querySelector(".java");
const interval = setInterval(() => {
i++;
var star = document.createElement("img");
star.src = "star.png";
element.append(star);
if (i === 5) { clearInterval(interval); } // <- after 5 iterations clear the interval
}, 1000); // <- this 1000 is 1 sec. delay
Use setinterval this way, so your images will most likely already be loaded before you append them to your element.
const listToAppend = [];
const element = document.querySelector(".java");
const start = () => {
let si = setInterval(()=>{
if(listToAppend.length === 0){
clearInterval(si);
return;
}
element.append(listToAppend.shift());
}, 1000);
}
function putStars(){
if(test){
for(var i = 0; i < 5; i++){
var star = document.createElement("img");
star.src = "star.png";
listToAppend.push(star);
}
start();
test = false;
}
}
so I seem to be having some real logic errors amidst my timer here, and I'm not quite sure how to fix them. I've made the code somewhat work, but I know for a fact there's a handful of logical errors, and I honestly have been working on it for a few days intermittently and can't seem to get it solved. Based on the code I've laid out you can pretty much understand my thinking of how I want to tackle this issue. I understand this isn't best practice, but I am just trying to work on my problem solving on these issues! Any help is greatly appreciated. I really need the most help on figuring out how to configure the Pause and Play functions with my given timer functionality. (Please no jQuery examples only raw JS)
// Necessary Variables for the program
let timer = document.querySelector(".time");
let button = document.querySelector("#btn");
let subtractBreak = document.querySelector("#subtractBreak");
let addBreak = document.querySelector("#addBreak");
let subtractSession = document.querySelector("#subtractSesssion");
let addSession= document.querySelector("#addSession");
// Keeping up with the current count of the break and session
let currentCount = document.getElementsByClassName("counterNum");
// Keeps up with all the buttons on session and break +/-
let counterBtn = document.getElementsByClassName("counterBtn");
// Pause and play Variables
let pause = document.querySelector("#pause");
let play = document.querySelector("#play");
// keeps up with an offsetting count.
let count = 0;
let timerGoing = false;
let sessionTimeLeft = 1500;
let breakTimeLeft = 5;
let timeWhilePaused = sessionTimeLeft;
let paused = false;
function formatTimer(time){
let minutes = Math.floor(time / 60);
let seconds = time % 60;
return `${minutes.toLocaleString(undefined, {minimumIntegerDigits: 2})}:${seconds.toLocaleString(undefined, {minimumIntegerDigits: 2})}`;
}
// This function needs to be fixed - It allows the timer to go negative past 0.
function countdown(){
timerGoing = true;
count++;
timer.innerHTML = formatTimer(sessionTimeLeft - count);
// Used to remove the listener
button.removeEventListener("click", interval);
console.log("Timer is at: " + formatTimer(sessionTimeLeft - count) + "\nCount is at: " + count + "\nsessionTimeLeft = " + sessionTimeLeft);
// Checking if the time of the current session is up
if(count == sessionTimeLeft){
timerGoing = false;
alert("We're here stop...");
startBreak(breakTimeLeft);
}
}
button.addEventListener("click", interval);
function interval(e){
setInterval(countdown, 1000);
console.log("running");
e.preventDefault();
}
/*
I look through the event listener to be sure to check and see if any of them have been hit
not just the first one, which is what it would check for.
*/
for(let i = 0; i < counterBtn.length; i++){
counterBtn[i].addEventListener("click", changeCount);
}
/*
This functions whole job is to see which button was clicked using the 'event target'
Once found it can determine if the id is subtract - then it will subtract the next element
founds' amount, due to the structure of the HTML this will always be the number following;
this process works vice versa for the addition, with the number being the element before.
*/
function changeCount(e){
let clickedButtonsId = e.target.id;
if(timerGoing == false){
if(clickedButtonsId === "subtractBreak"){
let currentValue = e.target.nextElementSibling.innerText;
if(currentValue != 1){
currentValue--;
e.target.nextElementSibling.innerText = currentValue;
breakTimeLeft -= 1;
}
} else if(clickedButtonsId === "subtractSession"){
let currentValue = e.target.nextElementSibling.innerText;
if(currentValue != 1){
currentValue--;
e.target.nextElementSibling.innerText = currentValue;
sessionTimeLeft = currentValue * 60;
// Allows the timer to update in real time
timer.innerHTML = formatTimer(sessionTimeLeft);
}
}
else if(clickedButtonsId === "addBreak"){
let currentValue = e.target.previousElementSibling.innerText;
currentValue++;
e.target.previousElementSibling.innerText = currentValue;
breakTimeLeft += 1;
}
else{
let currentValue = e.target.previousElementSibling.innerText;
currentValue++;
e.target.previousElementSibling.innerText = currentValue;
sessionTimeLeft = currentValue * 60;
// Allows the timer to update in real time
timer.innerHTML = formatTimer(sessionTimeLeft);
}
}
}
/* These functions below are not working */
pause.addEventListener("click", pauseTimer);
function pauseTimer(){
timeWhilePaused = sessionTimeLeft;
button.removeEventListener("click", interval);
console.log("calling pause"+paused+"\n");
paused = true;
console.log("paused after: " + paused);
}
play.addEventListener("click", playTimer);
function playTimer(){
console.log("Paused = " + paused);
if(paused == true){
console.log("calling play");
console.log("Paused = " + paused);
sessionTimeLeft = timeWhilePaused;
setInterval(countdown, 1000);
}
}
function startBreak(time){
console.log("Calling this function");
timer.innerHTML = formatTimer(breakTimeLeft - count);
}
I've got a simple simulator code where the user selects buttons to vary the inputs, and the outputs change in response (an example extract of which is shown below).
However, the outputs update automatically to the solution, and I was wondering if there's a way to show the numbers ticking over and increasing from what was previously displayed to the new number?
html
<button onClick = "IncTHR()">Increase Throttle</button>
<button onClick = "DecTHR()">Decrease Throttle</button>
<input type="text" id="THR">
<div id="CoolantTemp1"></p>
javascript
var CoolantTemp1 = 366;
var Throttle = 5;
var ControlRodHeight = 50;
var PrimaryPump = 1;
function IncTHR(){
user = ++Throttle;
if (Throttle > 10){
Throttle = 10;
}
CoolantTemp1 = (220+(ControlRodHeight*2.2)+(PrimaryPump*20)+(Throttle*3.2));
update();
displayResults();
function DecTHR(){
user = --Throttle;
if (Throttle < 0){
Throttle = 0;
}
CoolantTemp1 = (220+(ControlRodHeight*2.2)+(PrimaryPump*20)+(Throttle*3.2));
update();
displayResults();
function update() {
document.getElementById("THR").value = Throttle;
}
function displayResults() {
document.getElementById("CoolantTemp1").innerHTML = "Coolant Temperature 1 is " + CoolantTemp1;
}
So currently, as soon as the user clicks either throttle button, the Coolant Temperature is updated immediately to the solution - is there a way for the output to cycle through from the number it previously was to the new number it will become as a result of the calculation change?
Hope that makes sense!
Thank you.
Something like this should work:
var CoolantTemp1 = 366;
var tempCounter = 366;
var Throttle = 5;
var ControlRodHeight = 50;
var PrimaryPump = 1;
function IncTHR(){
Throttle++;
if (Throttle > 10){
Throttle = 10;
}
CoolantTemp1 = (220+(ControlRodHeight*2.2)+(PrimaryPump*20)+(Throttle*3.2));
update();
var incInt = setInterval(function (){
if (tempCounter < CoolantTemp1){
displayResults(tempCounter);
tempCounter++;
} else {
displayResults(CoolantTemp1);
tempCounter = CoolantTemp1;
clearInterval(incInt);
}
}, 1000);
}
function DecTHR(){
Throttle--;
if (Throttle < 0){
Throttle = 0;
}
CoolantTemp1 = (220+(ControlRodHeight*2.2)+(PrimaryPump*20)+(Throttle*3.2));
update();
var decInt = setInterval(function (){
if (tempCounter > CoolantTemp1){
displayResults(tempCounter);
tempCounter--;
} else {
displayResults(CoolantTemp1);
tempCounter = CoolantTemp1;
clearInterval(decInt);
}
}, 1000);
}
function update() {
document.getElementById("THR").value = Throttle;
}
function displayResults(temp) {
document.getElementById("CoolantTemp1").innerHTML = "Coolant Temperature 1 is " + temp;
}