I'm wanting to know how to put a message in every time the timer starts over. And here is my code thus far:
<head>
<script type="text/javascript">
var c=10;
var t;
var timer_is_on=0;
function timedCount() {
document.getElementById('txt').value = c;
c = c - 1;
if (c == 0)
c = 10;
}
function doMining() {
if (!timer_is_on) {
timer_is_on = true;
t = setInterval(function () {
timedCount();
}, 1000);
}
}
</script>
<SPAN STYLE="float:left">
<form>
<input type="button" value="Mining" onClick="doMining()">
<input type="text" id="txt">
</form>
</SPAN>
2 easy steps:
Create a place for your message to show up (i.e. another web element)
In your conditional, when your counter reaches 0, update the message element's value
Here's an example:
<div id='message'></div>
Then, access that element and append your message or modify your method using DOM traversal (preferably using a javascript framework such as dojo or jquery but you can also do it manually):
if (c == 0) {
var _message = document.createTextNode("Timer has finished!");
document.getElementById('message').appendChild(_message);
c = 10;
}
Also, don't put a SPAN around a form. Try a "div" instead. Span's are meant for styling in-line document elements.
Edit: I'm assuming when you say "start over" you mean when the c = 0 or the timer has run 10 times. When it "starts over" could also mean when the method is re-called by the timer (i.e. every 1 second, in which case you'd just put the update code at the top of the function)
You are already catching this event in your "if (c == 0)". Just add the extra code you need there?
You need to better define what it means to start over. Try pulling it out into its own method so you can work with it separately.
<script type="text/javascript">
var c=10;
var t;
var timer_is_on=0;
function timedCount() {
document.getElementById('txt').value = c;
c = c - 1;
if (c == 0)
startOver();
}
function startOver() {
alert("Starting Over, Fool!");
c = 10;
clearTimeout(t);
timer_is_on=0;
doMining();
}
function doMining() {
if (!timer_is_on) {
timer_is_on = true;
t = setInterval(function () {
timedCount();
}, 1000);
}
}
</script>
Related
let timer = document.querySelector("#timer");
var counter = 3;
function myFn() {
counter--
if (counter === -1) {
counter = 3
}
timer.innerText = counter
}
btn.onclick = function() {
text.innerHTML += 'clicked' + '<br>'
}
var myTimer = setInterval(myFn, 1000);
<div id="timer"></div>
<button id="btn">Button</button>
<div id="text"></div>
I'm trying with this small code to read the div#timer every second and check for a click condition in console.log() F12. It gives me different error in every way I try to do it.
let timer = document.querySelector("#timer");
let btn = document.querySelector("#btn");
setInterval(() => {
console.log(timer.textContent)
if (timer.textContent === '0') {
btn.click()
}
}, 1000);
Consider the following jQuery example.
$(function() {
var timer = 0;
var counter = 3;
var timeObj = $("#timer");
var btnObj = $("#btn");
var txtObj = $("#text");
var interval;
function myFn() {
if (--counter >= 0) {
txtObj.append("Clicked<br />");
} else {
clearInterval(interval);
}
}
interval = setInterval(function() {
timeObj.html(++timer);
}, 1000);
btnObj.click(myFn);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="timer">0</div>
<button id="btn">Button</button>
<div id="text"></div>
You will want to use setInterval() and not setTimeout().
The setInterval() method, offered on the Window and Worker interfaces, repeatedly calls a function or executes a code snippet, with a fixed time delay between each call.
This method returns an interval ID which uniquely identifies the interval, so you can remove it later by calling clearInterval().
See more: https://developer.mozilla.org/en-US/docs/Web/API/setInterval
Using the -- and ++ before the variable will also apply the change before it is used.
The decrement operator (--) decrements (subtracts one from) its operand and returns the value before or after the decrement, depending on where the operator is placed.
Adjusting the logic here can also ensure that the button click does allow the user to keep performing actions.
I'm a PLC programmer, i made a html page and i need it script refresh every second, so in my body i placed:
<body onload="changeimage()">
.... code ....
</body>
And the script:
<script>
setInterval(function changeimage() {
var sonde = ["Sonda1","Sonda2","Sonda3","Sonda4"];
var tsonde = ["tsonda1","tsonda2","tsonda3","tsonda4"];
var temperature = [:="OUTPUT".AlarmTemp.Sonda1:,:="OUTPUT".AlarmTemp.Sonda2:,:="OUTPUT".AlarmTemp.Sonda3:,:="OUTPUT".AlarmTemp.Sonda4:];
var hotcold = document.getElementById("Fiocco");
if (:="OUTPUT".Stagione.Estate: > 0){
hotcold.src="sun.jpg"}
if (:="OUTPUT".Stagione.Inverno: > 0){
hotcold.src="Neve.png"}
for (x in temperature) {
var icona = document.getElementById(sonde[x]);
if (temperature[x] > 0 ){
icona.src="Paverde.png"
}
else{
icona.src="Parossa.png"
}
}
}, 1000);
</script>
Anyway i get the error:
ReferenceError: changeimage is not defined
P.S.: Don't get fooled by the arrays who start with ":", is a PLC syntax, is correct.
# Even removing the setinterval option, the script is not working.
Define the function first and make sure the script is loaded.
Example in code pen: https://codepen.io/mikila85/pen/NWPvQPE
function changeimage() {
setInterval(function() {
var sonde = ["Sonda1","Sonda2","Sonda3","Sonda4"];
var tsonde = ["tsonda1","tsonda2","tsonda3","tsonda4"];
var temperature = [:="OUTPUT".AlarmTemp.Sonda1:,:="OUTPUT".AlarmTemp.Sonda2:,:="OUTPUT".AlarmTemp.Sonda3:,:="OUTPUT".AlarmTemp.Sonda4:];
var hotcold = document.getElementById("Fiocco");
if (:="OUTPUT".Stagione.Estate: > 0){
hotcold.src="sun.jpg"
}
if (:="OUTPUT".Stagione.Inverno: > 0){
hotcold.src="Neve.png"
}
for (x in temperature) {
var icona = document.getElementById(sonde[x]);
if (temperature[x] > 0 ){
icona.src="Paverde.png"
}
else{
icona.src="Parossa.png"
}
}
}, 1000);
}
Anyway i get the error: ReferenceError: changeimage is not defined
setInterval(function changeimage() {
Sure it won't be defined, as it was only defined as a callback function to the setInterval() call.
So it won't be visible outside of this setInterval scope, and it won't be visible for the onload event listener of your body.
Solution:
You should define your changeimage() function in the global scope (outside of the setInterval like this:
<head>
<script>
function changeimage() {
var sonde = ["Sonda1", "Sonda2", "Sonda3", "Sonda4"];
var tsonde = ["tsonda1", "tsonda2", "tsonda3", "tsonda4"];
var temperature = [: = "OUTPUT".AlarmTemp.Sonda1: ,: = "OUTPUT".AlarmTemp.Sonda2: ,: = "OUTPUT".AlarmTemp.Sonda3: ,: = "OUTPUT".AlarmTemp.Sonda4: ];
var hotcold = document.getElementById("Fiocco");
if (: = "OUTPUT".Stagione.Estate: > 0) {
hotcold.src = "sun.jpg"
}
if (: = "OUTPUT".Stagione.Inverno: > 0) {
hotcold.src = "Neve.png"
}
for (x in temperature) {
var icona = document.getElementById(sonde[x]);
if (temperature[x] > 0) {
icona.src = "Paverde.png"
} else {
icona.src = "Parossa.png"
}
}
}
setInterval(changeimage(), 1000);
</script>
</head>
<body onload="changeimage()">
.... code ....
</body>
You can see it working in this Demo.
Note:
Make sure to place your script tag in the head of your HTML page before the body tag so it can be accessed in the onload event listener.
try this
function changeImage(){
....
}
// if you need to call every 1 sec
setInterval(changeImage,1000);
// else
changeImage(); or // setTimeout(changeImage,1000)
Is there an easy way to output content when inside a Javascript loop, rather than have it display on screen after the loop has completed.
Code e.g:
var c = 0;
while (c <=1000 ){ //100000
run();
c++;
}
function run() {
console.log(c);
$('#data').append(c);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<div id="data"></div>
It outputs to console straight away (during loop) but on screen does not.
Hoping someone can assist.
Thanks!
Are you wanting to write it to the webpage?
If so then you can write it to a div using the InnerHTML
document.getElementById("yourDivID").innerHTML = yourString;
Your browser's Javascript engine is too fast thus you cannot see the changes in real time. So set a timer and slow down the process.
Run the below code and see the magic happens...
var c = 0;
$(document).ready(function () {
run();
});
function run() {
var timer = setInterval(function () {
//console.log(c);
$('#data').append(c + "\n");
if (c++ == 1000) {
clearInterval(timer);
}
}, 12); //set time in milliseconds
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="data"></div>
These are the changes made to your code :
Removed the while loop and replaced it with setInterval()
Added $(document).ready() function to make sure the run() is executed after the DOM is fully loaded.
Try using clousres and setTimeout:
function run(c) {
console.log(c);
$('#data').append(c + ', ');
}
$(function() {
for (var c = 1; 999 > c; c++) {
(function(c) {
setTimeout(function() {
run(c);
}, 1);
})(c);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="data"></div>
I have 31 images and I want to display them one after another as the background of a div. I only want it to change when the user hovers over the div. My problem right now is that it just flips through all the images really fast. I am attempting to use setTimeout, but it isn't working. How can I make the delay work?
The name of the div is About_Me_Block and the images are called frame1.gif,frame2.gif ...etc
Here is my code:
function changeImg(counter) {
$('#About_Me_Block').attr("style", "background-image: url(playGif/frame" + counter + ".gif);");
}
$(document).ready(function() {
var hoverAnimate = []
"use strict";
$('#About_Me_Block').mouseenter(function() {
hoverAnimate[0] = true;
var counter = 0;
while (hoverAnimate[0]) {
console.log(counter);
setTimeout(changeImg(counter), 1000);
counter++;
if (counter === 32)
hoverAnimate[0] = false;
}
});
$('#About_Me_Block').mouseleave(function() {
hoverAnimate[0] = false;
$(this).attr("style", "background-image: url(play.jpeg);");
});
});
setTimeout doesn't wait for the function to end, it works lile threading in other languages.
To achieve a what you want, you need to call setTimeout from the changeImg function.
var counter = 0;
$(document).ready(function() {
var hoverAnimate = []
"use strict";
$('#About_Me_Block').mouseenter(function() {
hoverAnimate[0] = true;
counter = 0;
changeImg();
});
$('#About_Me_Block').mouseleave(function() {
hoverAnimate[0] = false;
$(this).attr("style", "background-image: url(play.jpeg);");
});
});
function changeImg() {
$('#About_Me_Block').attr("style", "background-image: url(playGif/frame" + counter + ".gif);");
counter++;
if (counter < 32 && hoverAnimate[0]) {
setTimeout(changeImg, 1000);
} else {
hoverAnimate[0] = false;
}
}
the reason they happen all at once is because while statement doesn't have delay, so all setTimeout will be set up at the same time, thus, calling changeImg all at once.
To solve this problem, you can replace setTimeout with setInterval. Instead of using while, you can just call setInterval like
var counter = 0;
var myTimer = setInterval(changeImg, 1000);
and update counter inside changeImg every time it gets called. After looping, don't forget to
clearInterval(myTimer)
It seems you need to read up on how setTimeout works. It essentially places a reminder to run a function after a given amount of milliseconds have passed. So, when you do setTimeout(changImg(counter), 1000) you are calling changImg(counter) which returns undefined. Therein producing this setTimeout(undefined, 1000) which is why it flips really fast.
So, you can use bind to allow the function to be called later with that parameter built in. Also, make sure you remove the reminders once done with clearTimeout.
function changeImg(counter) {
$('#About_Me_Block').attr("style", "background-image: url(playGif/frame" + counter + ".gif);");
}
$(document).ready(function() {
var hoverAnimate = false, id;
function loop(counter) {
if(hoverAnimate || counter < 32) {
changeImg(counter);
id = setTimeout(loop.bind(this, counter++), 1000);
}
}
$('#About_Me_Block').mouseenter(function() {
hoverAnimate = true;
id = setTimeout(loop.bind(this, 0), 1000);
});
$('#About_Me_Block').mouseleave(function() {
hoverAnimate = false;
// Don't want a reminder for a random counter to wake up.
clearTimeout(id);
$(this).attr("style", "background-image: url(play.jpeg);");
});
});
Two methods for timers - setTimeout and SetInterval (single / repeating)
// setInterval is also in milliseconds
var intervalHandle = setInterval(<yourFuncToChangeImage>,5000);
//this handle loop and make example loop stop
yourelement.yourEvent = function() {
clearInterval(intervalHandle);
};
Jquery and Javascript do strange things. If you look to the code there is a "while" loop. It does 3 loops but only fades the last one (#c2).
Here is my code:
<div style="display:none" id="c0">Element 0</div>
<div style="display:none" id="c1">Element 1</div>
<div style="display:none" id="c2">Element 2</div>
<script>
var count = 0;
var exit = false;
var time = 300;
while(exit == false){
if(document.getElementById("c" + count)){
cual = "#c" + count;
$(document).ready(function(){
$(cual).fadeIn(time);
});
}
else
exit = true;
count++;
time += 100;
}
</script>
The reason you see this is because the cual variable will hold the value #c3 by the time the callbacks execute. Because cual is defined within a global scope, and not the callback scope, it is not bounded to the callback scoe.
There is a workaround for this, by adding an intermediary function, something like this:
function scheduleFade(count) {
var cual = "#c" + count;
$(document).ready(function(){
$(cual).fadeIn(time);
});
}
while(exit == false) {
if(document.getElementById("c" + count)) {
scheduleFade(count);
} else {
exit = true;
}
count++;
time += 100;
}
The script is loaded after the DOM is loaded on the page, so you don't need to use $(document).ready(). I have tested the following script:
var count = 0;
var exit = false;
var time = 300;
while(exit == false){
if(document.getElementById("c" + count)){
cual = "#c" + count;
$(cual).fadeIn(time);
}
else
exit = true;
count++;
time += 100;
}
and it works.
(Update based on comments)
The variable cual is overwritten on each loop, but the code inside the ondocumentready event listener is only executed after the DOM is fully loaded. At this point the variable cual is only set to the name of the third element.
You can create an own visibility scope for that variable to make it available inside the event listener callback:
var count = 0;
var exit = false;
var time = 300;
while(exit == false){
if(document.getElementById("c" + count)){
cual = "#c" + count;
$(document).ready((function() {
var elementToFadeIn = cual;
return function() {
$(elementToFadeIn).fadeIn(time);
}
})());
}
else
exit = true;
count++;
time += 100;
}
Here the variable elementToFadeIn is set inside an immediately-invoked-function, which also returns the event listener callback. That way, the locally defined elementToFadeIn will stay with name passed in on the current loop iteration.
–––––
On the other you are using jQuery, why do need the loop in the first place?
Just include this code at the end of the page (i.e. before the closing BODY tag) and you don't need the ondocumentready event, as all relevant parts of the DOM are loaded right before the closing BODY tag.
var time = 1000;
jQuery( '[id^="c"]' ).fadeIn( time );