I was trying out Pomodoro. Please refer to the snippet. The play and stop buttons are working fine but the second's element(var secEl = document.querySelector('.timesec');) doesn't show up after first 60 seconds.
<div class="timemin mt-4">25 <span>: </span><span class="timesec">00</span></div>
The function runs as expected but the seconds, stop showing up after the first 60sec. I assumed something wrong with document.querySelector.
Thank you.
var playEl = document.querySelector('.play');
var secEl = document.querySelector('.timesec');
var minEl = document.querySelector('.timemin');
var stopEl = document.querySelector('.stop')
playEl.addEventListener('click', startTime);
stopEl.addEventListener('click', stopTime);
let counter = 00;
let minCounter = 25;
var secCountDown;
function startTime(){
counter = 60;
secEl.innerHTML = counter;
// console.log('i am clicked', counter)
secCountDown = setInterval( countDown, 1000);
function countDown(){
counter--;
secEl.innerHTML = counter;
//console.log(secEl.innerHTML);
if( counter == 0){
clearInterval(secCountDown);
minCountDown();
// console.log('i am checked')
}
}
}
function minCountDown(){
minCounter --;
minEl.innerHTML = minCounter;
if( minCounter == 0 ){
//console.log('i am checked');
} else
{
startTime();
}
}
function stopTime(){
clearInterval(secCountDown);
minEl.innerHTML = 25;
secEl.textContent = 00;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<title>Document</title>
<style type = text/css>
.timerBorder{
border: 1px solid black;
min-height: 280px;
}
.time{
font-size: 60px;
}
</style>
</head>
<body>
<div class="row">
<div class="col">
<h1>Pomodoro</h1>
</div>
</div>
<div class="row">
<div class="col">
<div class="row justify-content-center">
<div class="col-5">
<div class="mt-4"><button>Working</button><button>Resting</button></div>
<div class="timemin mt-4">25 <span>: </span><span class="timesec">00</span></div>
<div class="mt-4">
<button class="play">Play</button>
<button class="stop">Stop</button>
<button>Pause</button>
</div>
</div>
<div id="time"></div>
</div>
</div>
</div>
<script src="./script.js"></script>
</body>
</html>
This happens because your HTML structure is not suitable for this. The .timemin element is the parent of the .timesec element, so as soon as you set the HTML of the first, the second is destroyed. Once that happens, the reference to the .timesec element is no longer attached to the document, and any update of its HTML has no visual effect any more:
<div class="timemin mt-4">25 <span>: </span><span class="timesec">00</span></div>
Instead, create a separate span for the minutes:
<div class="mt-4">
<span class="timemin">25</span> : <span class="timesec">00</span>
</div>
Related
i start studying Js and i made this Stopwatch, but if i press reset, the stopwatch dont start again, unless i f5. I've tried some things but nothing seems to work, dont know what to do. I've seen others Js Stopwatch but they didnt help me to correct my mistake.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="cronometro.css">
<script src="cronometro.js"></script>
<title>Online Stopwatch</title>
</head>
<body>
<div class="main">
<header>
<p class="hText">Let's see your performance</p>
</header>
<div id="watch">
<span id="minutes">00</span>:<span id="seconds">00</span>:<span id="hundredths">00</span>
</div>
<br>
<div class="buttons">
<button onclick="startCron()" > Start</button>
<button onclick="pauseCron()" > Pause</button>
<button onclick="resetCron()" > Reset</button>
</div>
</div>
</body>
</html>
var hund = 0;
var sec = 0;
var min = 0;
var interval
function clockDigits(digit) {
if (digit<10) {
return ('0' + digit)
} else {
return digit
}
}
function startCron() {
interval = setInterval(watchTime,10);
}
function pauseCron() {
clearInterval(interval)
}
function resetCron() {
clearInterval(interval)
hund = 0
sec = 0
min = 0
document.getElementById('watch').innerText='00:00:00';
}
function watchTime() {
hund++
document.getElementById('hundredths').innerText=clockDigits(hund);
if (hund==100) {
sec++
hund=0
document.getElementById('seconds').innerText=clockDigits(sec);
} if (sec==60) {
min++
sec=0
document.getElementById('minutes').innerText=clockDigits(min);
}
}
i try to call function startCron() inside resetCron(), but didnt work
on reset, you set the inner text of
document.getElementById('watch')
it replaces minutes, second, and hundredths span.
because of that when you want to start the stopwatch again startCron does not find minutes, second, and hundredths span. that's why it gives an error.
replace document.getElementById('watch').innerText='00:00:00'; with
document.getElementById('minutes').innerText='00';
document.getElementById('seconds').innerText='00';
document.getElementById('hundredths').innerText='00';
and one more thing, disable the start button when the watch is started and enable it when the watch is paused or reset.
In the resetCron function, you set document.getElementById('watch').innerText = 00:00:00, this changed whole elements inside, it should be:
function resetCron() {
clearInterval(interval);
hund = 0;
sec = 0;
min = 0;
document.getElementById('watch').innerHTML='<span id="minutes">00</span>:<span id="seconds">00</span>:<span id="hundredths">00</span>';
}
<!DOCTYPE html>
<html>
<head>
<title>stoplight</title>
<link rel="stylesheet" type="text/css" href="stoplight.css">
</head>
<body>
<div id="controls">
<button id="stop">Stop</button>
<button id="slow">Slow</button>
<button id="go">Go</button>
<button id="caution">Caution</button>
</div>
<div id="mainContainer">
<div id="top" class="off">
</div>
<div id="middle" class="off">
</div>
<div id="bottom" class="off">
</div>
</div>
<script type="text/javascript" src="stoplight.js"></script>
</body>
</html>
Basically, I'm just trying to select each div of the stoplight and change the background color. First, I thought I could just reset each div to its original color. I'm trying to do the same with the setInterval function that starts a flashing yellow light, but it doesn't seem to stop it and breaks the rest of the functions.
document.getElementById('stop').onclick = goRed;
document.getElementById('go').onclick = goGreen;
document.getElementById('slow').onclick = goYellow;
document.getElementById('caution').addEventListener('click', () => {
blink();
});
let middle = document.getElementById('middle');
let blinking;
function goRed() {
reset();
document.getElementById('top').style.backgroundColor = '#FF0000';
};
function goYellow() {
reset();
middle.style.backgroundColor = '#FFFF00';
};
function goGreen() {
reset();
document.getElementById('bottom').style.backgroundColor = '#7FFF00';
};
function blink(){
reset();
blinking = setInterval(() => {
middle.classList.toggle('onYellow');
}, 1000);
};
function reset() {
document.getElementById('top').style.backgroundColor = '#A0522D';
document.getElementById('middle').style.backgroundColor = '#A0522D';
document.getElementById("bottom").style.backgroundColor = '#A0522D';
clearInterval(blinking);
};
You are mixing in-style coloring, with class based coloring, and in some cases, the browser will decide which gets a priority. Unless you add !important in the class background to enforce the attribute.
I suggest removing all in-style coloring and sticking only to classes so that you will not have to use !important.
This way, it is easier to work with blinking and setInterval.
See my code snippet below.
document.getElementById('stop').onclick = goRed;
document.getElementById('go').onclick = goGreen;
document.getElementById('slow').onclick = goYellow;
document.getElementById('caution').addEventListener('click', () => {
blink();
});
let middle = document.getElementById('middle');
let blinking;
function goRed() {
reset();
document.getElementById('top').className = "onRed";
};
function goYellow() {
reset();
middle.className = "onYellow";
};
function goGreen() {
reset();
document.getElementById('bottom').className = "onGreen";
};
function blink() {
reset();
blinking = setInterval(() => {
middle.classList.toggle('onYellow');
middle.classList.toggle('onOff');
}, 1000);
};
function reset() {
document.getElementById('top').className = "onOff";
document.getElementById('middle').className = "onOff";
document.getElementById("bottom").className = "onOff";
clearInterval(blinking);
};
#mainContainer div {
border: 1px solid grey;
width: 40px;
height: 40px;
border-radius: 40px;
}
.onYellow {
background-color: #ffff00;
}
.onOff {
background-color: #A0522D;
}
.onGreen {
background-color: #7FFF00;
}
.onRed {
background-color: #FF0000;
}
<!DOCTYPE html>
<html>
<head>
<title>stoplight</title>
<link rel="stylesheet" type="text/css" href="stoplight.css">
</head>
<body>
<div id="controls">
<button id="stop">Stop</button>
<button id="slow">Slow</button>
<button id="go">Go</button>
<button id="caution">Caution</button>
</div>
<div id="mainContainer">
<div id="top" class="off">
</div>
<div id="middle" class="off">
</div>
<div id="bottom" class="off">
</div>
</div>
<script type="text/javascript" src="stoplight.js"></script>
</body>
</html>
I am making an offline application of a music website using JS and I am handling song queues using arrays. I added song blocks with skip buttons so users can choose which song to skip without spamming another skip button that only allows them to skip the first song of the queue. The problem is, splicing the array with the index of the selected song the users wanted to skip removes the rest of the songs after it.
Example array: ["songA","songB","songC","songD","songE"]
If the user choose to skip songC, the song queue will become ["songA","songB"] and the songC to songE will be removed, but in reality the expected outcome should be ["songA","songB","songD","songE"].
I have no idea what is wrong with the code and I have searched similar topics regarding this problem but still no results. I am still new to JS and my code's a bit rough but I'm pretty sure that's not the cause of the issue.
JS:
//function of skip buttons on song blocks
songPlaylist.addEventListener("DOMNodeInserted", function() {
iconList = document.querySelectorAll(".deleteIcon");
iconList.forEach(function(element) {
element.addEventListener('click', function() {
var nameOfSong = this.parentNode.childNodes[0].dataset.name;
var indexByName = songQueue.indexOf(nameOfSong);
var selectedBlock = this.parentNode;
if (songQueue.length == 1) {
songQueue.shift();
songPlaylist.removeChild(songPlaylist.firstChild);
var emptyMsgSpan = document.createElement("div");
emptyMsgSpan.className += "emptyMsgSpan";
var emptyMsg = document.createTextNode("Playlist is empty! How 'bout adding some music?");
emptyMsgSpan.appendChild(emptyMsg);
document.getElementById("playlistContainer").appendChild(emptyMsgSpan);
setTimeout(function() {
audioPlayer.src = "";
}, 1000);
} else {
songQueue.splice(indexByName,1); // <--- press first block output delete everything
// press any block after first deletes everything beneath it
songPlaylist.removeChild(selectedBlock);
for (var blockIndex = indexByName; blockIndex <= songQueue.length; blockIndex++) {
document.getElementById("playlistContainer").children[blockIndex].childNodes[1].dataset.index -= 1;
}
};
});
});
});
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="index.css">
<link href="https://fonts.googleapis.com/css?family=Bai+Jamjuree" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Jost&display=swap" rel="stylesheet">
<!--<div>Icons made by Roundicons from www.flaticon.com</div>-->
<title>Mue - Custom Playlist</title>
</head>
<body>
<div id="bg">
<div class="titleBar">
<button style="background: none; border: none; cursor: pointer;" onclick="location.reload(); return false;">
<span>MUE</span>
</button>
</div>
<div class="songNameDisplay">
<span id="nowPlaying"></span>
</div>
<div class="trackContainer">
<div class="btn play"></div>
<div class="audioTrack">
<div class="trackBtn"></div>
</div>
<div id="skipBtn">
<div class="triangle1"></div>
<div class="triangle2"></div>
<div class="rect"></div>
</div>
</div>
<button id="fileBtn" class="fileBtn"><span>Upload</span></button>
</div>
<audio id="audioPlayer" controls autoplay></audio>
<input type="file" id="file" />
<div id="playlistContainer"></div>
</body>
<script src="index.js"></script>
<script>
const bg = document.getElementById("bg");
window.addEventListener('scroll' , function() {
let offset= window.pageYOffset;
bg.style.backgroundPositionY = offset * 0.5 + "px";
});
</script>
</html>
Thanks in advance.
I am a newbie to Javascript, I wanted to implement a for loop that would go through each div as selected by its class.
The simple idea is to reveal DIVs when I click on a button. But it has to be sequential: I click DIV1 appears, when I click again DIV2 appears and so on. Currently my code only changes the class of one DIV and not the rest. Here are my code samples:
$(document).ready(function(){
// jQuery methods go here...
var count = document.getElementById("page1").childElementCount;
for(var i = 0; i < count; i++){
var myClass = ".panel" + i;
$("button").click(function(){
$(myClass).addClass("showing animated fadeIn")
});
}
});/**document ready **/
.showing{
background-color: red;
height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title</title>
<link rel="stylesheet" type="text/css" href="mystyle.css">
<link rel="stylesheet" type="text/css" href="animate.css">
</head>
<body>
<button class="one">Click Me!</button>
<div id="page1">
<div class="panel1">
</div>
<div class="panel2">
</div>
<div class="panel3">
</div>
<div class="panel4">
</div>
</div><!-- page one -->
<div id="trial">
</div>
<script src="jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="jquery.touchSwipe.min.js"></script>
<script type="text/javascript" src="trial.js"></script>
</body>
</html>
Please let me know what I am missing especially in the for loop or if I can do something else to be able to grab a DIV and add a class every time I click on the button.
Firstly, the HTML attribute class is made for multiple elements with the same style/behaviour. You should use id if it is to dissociate one panel for another.
You have to store a count variable to know which panel has to appear next.
And always try to do what you want in Javascript without jQuery if it is possible !
var i = 1;
function clickBtn() {
if (!document.getElementById("panel-" + i))
return;
document.getElementById("panel-" + i).classList.add("visible");
i++;
}
.panel {
width: 50px;
height: 50px;
display: none;
margin: 5px;
background-color: #bbb;
}
.panel.visible {
display: block;
}
<button onclick="clickBtn()">click me</button>
<div>
<div id="panel-1" class="panel"></div>
<div id="panel-2" class="panel"></div>
<div id="panel-3" class="panel"></div>
<div id="panel-4" class="panel"></div>
</div>
You could use counter like clickCount instead of for loop
$(document).ready(function(){
// jQuery methods go here...
var clickCount = 1;
$("button").click(function(){
var myClass = ".panel" + clickCount;
$(myClass).addClass("showing animated fadeIn")
clickCount++;
});
});/**document ready **/
.showing{
background-color: red;
height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>title</title>
<link rel="stylesheet" type="text/css" href="mystyle.css">
<link rel="stylesheet" type="text/css" href="animate.css">
</head>
<body>
<button class="one">Click Me!</button>
<div id="page1">
<div class="panel1">
</div>
<div class="panel2">
</div>
<div class="panel3">
</div>
<div class="panel4">
</div>
</div><!-- page one -->
<div id="trial">
</div>
<script src="jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="jquery.touchSwipe.min.js"></script>
<script type="text/javascript" src="trial.js"></script>
</body>
</html>
You've got this a little bit backwards; you're trying to attach an event handler to the button for each element. Instead, you should have one event handler for the button, which cycles through the elements.
You could set a variable to keep track of which element is currently highlit, but it's easier to just determine that based on the current state of the DOM:
$(document).ready(function() {
$('button.one').click(function() {
$('.showing') // find the current element
.removeClass('showing') // clear it
.next() // find its next sibling
.addClass('showing'); // show that
if ($('.showing').length === 0) {
// nothing is showing, so show the first one
$('#page1 div:eq(0)').addClass('showing')
}
})
})
#page1 div {height: 10px}
#page1 div.showing {background-color: red}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="one">Click Me!</button>
<div id="page1">
<div class="panel1"></div>
<div class="panel2"></div>
<div class="panel3"></div>
<div class="panel4"> </div>
</div>
There's a small cheat in the above -- if the current element is the last one, then it won't have a next() to highlight. That's why I waited to check for the case where there's nothing visible until after moving the highlight; that way it will work for both the first click, and for when you need the highlight to loop back around to the first element.
If you intended to have the elements reveal themselves in sequence and not hide earlier ones, just get rid of the .removeClass('showing') line:
$(document).ready(function() {
$('button.one').click(function() {
$('.showing') // find the current element
.next() // find its next sibling
.addClass('showing'); // show that
if ($('.showing').length === 0) {
// nothing is showing, so show the first one
$('#page1 div:eq(0)').addClass('showing')
}
})
})
#page1 div {height: 10px}
#page1 div.showing {background-color: red}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="one">Click Me!</button>
<div id="page1">
<div class="panel1"></div>
<div class="panel2"></div>
<div class="panel3"></div>
<div class="panel4"> </div>
</div>
What you can do is count the amount of children that you have, and compare the amount of clicks through a given iterator you have to see what should be shown.
I added an extra functionality that hides the elements again once the max amount of divs has been shown.
Hope this helps.
$(document).ready(function() {
$('#page1').children().each(function () {
$(this).hide();
});
});
var panel="panel";
var pannelNum=0;
var count = $("#page1").children().length;
$(".one").on( "click", function() {
pannelNum=pannelNum+1;
if(pannelNum > count) {
$('#page1').children().each(function () {
$(this).hide();
});
pannelNum=0;
}
else {
clicked=panel+""+pannelNum;
$('.'+clicked).show();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="one">Click Me!</button>
<div id="page1">
<div class="panel1">
this is panel 1!
</div>
<div class="panel2">
this is panel 2!
</div>
<div class="panel3">
this is panel 3!
</div>
<div class="panel4">
this is panel 4!
</div>
</div><!-- page one -->
<div id="trial">
</div>
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am coding a simple game recently, it runs normally on PC, but it runs slowly on mobile phone. I am just wondering whether the problem is caused by my code or by jquery.
Should I use jquery while writing game for mobile phone
here is the demo:my game demo link
js code:
$(document).ready(function() {
var min = 0;
var max = 3;
var windowHeight = $(window).height();
var windowWidth = $(window).width();
var rowHeight = windowHeight / 4 - 1;
var colWidth = windowWidth / 4 - 1;
var totalTime = 30;
var score = 0;
function layout() {
$('.row').height(rowHeight);
$('.col').width(colWidth);
}
function init () {
layout();
$('.row').each(function () {
//var rand = Math.floor(Math.random() * (max - min + 1) + min); // return random number between min and max;
var rand = Math.floor(Math.random() * max);
$(this).children().eq(rand).addClass('active');
});
$('#time').text(totalTime);
}
function insertNewRow () {
var rand = Math.floor(Math.random() * max);
var newRowStr = '<div class="row">';
for (var i = 0; i < 4; i++) {
newRowStr += '<div class="col"></div>';
}
newRowStr += '</div>';
var $newRow = $(newRowStr);
$newRow.height(rowHeight).children().width(colWidth).eq(rand).addClass('active');
$newRow.prependTo('#wrapper');
}
function removeLastRow () {
$('.row:last').remove();
}
var counting;
function startCountDown () {
counting = setInterval(countDown, 1000);
}
function countDown() {
var timeLeft = $('#time').text();
timeLeft -= 1;
$('#time').text(timeLeft);
if (timeLeft == 0) {
gameover();
}
}
function gameover () {
clearInterval(counting);
$('#end').show().find('#score').text("your scoreļ¼" + score);
}
function restartGame () {
score = 0;
$('#time').text(totalTime);
startCountDown();
}
init();
$('#wrapper').on('click', '.row:eq(3) .active', function (event) {
event.preventDefault();
score++;
$(this).removeClass('active').addClass('clicked').parent().remove();
//setTimeout(removeLastRow, 200);
insertNewRow();
});
$('#launch').click(function (event) {
event.preventDefault();
$('#start').hide();
startCountDown();
});
$('#retry').click(function (event) {
event.preventDefault();
$('#end').hide();
restartGame();
});
});
html code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">
<title>Game</title>
<link rel="stylesheet" type="text/css" href="files/style.css">
<script src="files/jquery.min.js"></script>
<script src="files/game.js"></script>
</head>
<body>
<div id="start">
<a id="launch" href="#">START</a>
</div>
<div id="time"></div>
<div id="end">
<h1 id="score"></h1>
<a id="retry" href="#">AGAIN</a>
</div>
<div id="wrapper">
<div class="row">
<div class="col"></div>
<div class="col"></div>
<div class="col"></div>
<div class="col"></div>
</div>
<div class="row">
<div class="col"></div>
<div class="col"></div>
<div class="col"></div>
<div class="col"></div>
</div>
<div class="row">
<div class="col"></div>
<div class="col"></div>
<div class="col"></div>
<div class="col"></div>
</div>
<div class="row">
<div class="col"></div>
<div class="col"></div>
<div class="col"></div>
<div class="col"></div>
</div>
</div>
</body>
</html>
In general jQuery is very slow, which one rarely experiences since we have such fast computers. But you seem to use jQuery for almost every interaction here. You might consider make some improvements to that. Check out this nice article about the issue.
jQuery Newbs: Stop Jumping in the Pool