switch checked check-box with time interval in javascript - javascript

I'm a total noob at javascript and currently having issues with a project.
I'm trying to make a picture slide with specific transitions. The slide builds on and tags for the transition (check-boxes). I tried making a script that changes the checked box after every 5s.
I already got a good chunk of help from a friend but I can't get it to work at all.
This is the script:
var slider_i = 1;
function slider_change(){
if(++slider_i > 4){
slider_i=1;
}
document.getElementById('select-img-'+slider_i).checked = true;
setTimeout(slider_change, 5000);
}
slider_change();
Here is the slider I'm talking about:
http://demo.br-photography.ch/Portal/transitions/index_3.html
I made a jsfiddle, easier to test cause then we can see if the checkboxes without the css properties actually switch. They do, but my slide on the testsite is not switching the images as it should...?
https://jsfiddle.net/t4eapmgb/

For your information, setTimeout(, 50000) is triggerd after 50000 ms = 50sec.
If you want to wait 5 sec you have to write setTimeout(, 5000)

Just place script from top to bottom. There is reference error because elements(checkboxes) are not available when initially page is loaded.
Or you may also add try catch block for this issue as follows:
replace this
var slider_i = 1;
function slider_change(){
if(++slider_i > 4){
slider_i=1;
}
document.getElementById('select-img-'+slider_i).checked = true;
setTimeout(slider_change, 5000);
}
slider_change();
With this one:-
var slider_i = 1;
function slider_change(){
if(++slider_i > 4){
slider_i=1;
}
try{
document.getElementById('select-img-'+slider_i).checked = true;
}catch(err){}
setTimeout(slider_change, 5000);
}
slider_change();

try:
var slider_i = 0; // !!!
var slider_change = function (){
if(++slider_i > 4){
slider_i=0;
}
document.getElementById('select-img-'+slider_i).checked = true;
setTimeout(slider_change, 50000);
};
slider_change();
or
var slider_i = 1;
var slider_change = function (){
if(slider_i++ > 3){ // !!!
slider_i=1;
}
document.getElementById('select-img-'+slider_i).checked = true;
setTimeout(slider_change, 50000);
};
slider_change();
what's actually happening with your code:
slider_i is set to 1.
function slider_change is called
it first increments the slider_i because of ++slider_i
now slider_i has the value of 2
it now checks against <4
if not true, it checks an element with id select-img-<value of slider_i>
The last step generates the id of select-img-2.
select-img-1 will never be reached. I don't know whether this is causing any subsequent errors.

Use
//Repeats forever
var variable = setInterval(functionYouWantToCall, 5000);
//Cancel the interval
clearInterval(variable);

Related

cannot set innerHTML property of null on Qualtrics

I am using Qualtrics to make a survey, and I need to do a bit of JS to make a timer. Unfortunately, I'm constantly running into "cannot set innerHTML property of null" for element "s5".
I've read the other thread about this issue (albeit the OP doesn't seem to be using qualtrics), and thought that perhaps changing "Qualtrics.SurveyEngine.addOnload" to "Qualtrics.SurveyEngine.addReady" might do the trick, but it doesn't, and I've already tried changing the id's quite a few times to no avail. Could someone help me find where my error is?
I got marked previously for the same question (as something that's already been answered), but that thread didn't help me at all. I've tried ready() as shown in the commented out section in the first code snippet, but that only gave me a "startThinkingTimer is not defined" error. When I tried it the second way in the second code snippet, I didn't get any errors, but my timer wasn't visible/working at all either. I can't move script or use defer b/c Qualtrics does not have all the HTML/CSS/JS in one file, but has different sections for them and honestly I'm not sure how they connect the different files. Regarding using .on(), I'm not sure which event to use here, and would really like some help.
I've tried replacing all the document.getElementById for element "s5" with something like this:
$("s5").innerHTML="10";
but this doesn't work, either.
(Should I try to move the html code inside the JS portion (esp. the div timeShower part)? I'm not too sure how to do that though, so if someone could help me do that, that'd be awesome.)
window.thinkingTimer_;
window.typingTimer_;
Qualtrics.SurveyEngine.addOnload(function(){
that = this;
var thinkingTimeLimit = 15;
var typingTimeLimit = 10;
jQuery(".InputText").hide();
$('NextButton').hide();
document.getElementById("instructions5").innerHTML = "You have 15 seconds to think about the prompt and come up with your two most favourite fruits, either from the list or from your previous choices. Textboxes will appear when the time is up.";
function startTypingTimer() {
that.enableNextButton();
typingTimer_ = setInterval( function(){
if (typingTimeLimit > 0) {
document.getElementById("s5").innerHTML=pad(--typingTimeLimit%60);
document.getElementById("minutes5").innerHTML=pad(parseInt(typingTimeLimit/60,10));
}
if (typingTimeLimit == 0) {
clearInterval(typingTimer_);
jQuery("#NextButton").click();
}
}, 1000);
}
/*
$(function startThinkingTimer() {
that.disableNextButton();
thinkingTimer_ = setInterval( function(){
if (thinkingTimeLimit >0) {
document.getElementById("s5").innerHTML=pad(--thinkingTimeLimit%60);
document.getElementById("minutes5").innerHTML=pad(parseInt(thinkingTimeLimit/60,10));
}
if (thinkingTimeLimit == 0) {
clearInterval(thinkingTimer_);
document.getElementById("s5").innerHTML="10";
document.getElementById("minutes5").innerHTML="00";
jQuery(".InputText").show();
document.getElementById("instructions5").innerHTML = "You now have 10 seconds to type in the two fruits. The page will automatically move on to the next page once time is up.";
startTypingTimer();
}
}, 1000);
});
*/
function startThinkingTimer() {
that.disableNextButton();
thinkingTimer_ = setInterval( function(){
if (thinkingTimeLimit >0) {
document.getElementById("s5").innerHTML=pad(--thinkingTimeLimit%60);
document.getElementById("minutes5").innerHTML=pad(parseInt(thinkingTimeLimit/60,10));
}
if (thinkingTimeLimit == 0) {
clearInterval(thinkingTimer_);
document.getElementById("s5").innerHTML="10";
document.getElementById("minutes5").innerHTML="00";
jQuery(".InputText").show();
document.getElementById("instructions5").innerHTML = "You now have 10 seconds to type in the two fruits. The page will automatically move on to the next page once time is up.";
startTypingTimer();
}
}, 1000);
}
function pad (val) {
return val > 9 ? val : "0" + val;
}
startThinkingTimer();
});
<div id="instructions5"> </div>
<div id="timeShower1">time: <span id="minutes5">00</span>:<span id="s5">15</span></div>
window.thinkingTimer_;
window.typingTimer_;
Qualtrics.SurveyEngine.addOnload(function(){
that = this;
var thinkingTimeLimit = 15;
var typingTimeLimit = 10;
jQuery(".InputText").hide();
$('NextButton').hide();
document.getElementById("instructions5").innerHTML = "You have 15 seconds to think about the prompt and come up with your two most favourite fruits, either from the list or from your previous choices. Textboxes will appear when the time is up.";
function startTypingTimer() {
that.enableNextButton();
typingTimer_ = setInterval( function(){
if (typingTimeLimit > 0) {
document.getElementById("s5").innerHTML=pad(--typingTimeLimit%60);
document.getElementById("minutes5").innerHTML=pad(parseInt(typingTimeLimit/60,10));
}
if (typingTimeLimit == 0) {
clearInterval(typingTimer_);
jQuery("#NextButton").click();
}
}, 1000);
}
$(function () {
that.disableNextButton();
thinkingTimer_ = setInterval( function(){
if (thinkingTimeLimit >0) {
document.getElementById("s5").innerHTML=pad(--thinkingTimeLimit%60);
document.getElementById("minutes5").innerHTML=pad(parseInt(thinkingTimeLimit/60,10));
}
if (thinkingTimeLimit == 0) {
clearInterval(thinkingTimer_);
document.getElementById("s5").innerHTML="10";
document.getElementById("minutes5").innerHTML="00";
jQuery(".InputText").show();
document.getElementById("instructions5").innerHTML = "You now have 10 seconds to type in the two fruits. The page will automatically move on to the next page once time is up.";
startTypingTimer();
}
}, 1000);
});
/*
function startThinkingTimer() {
that.disableNextButton();
thinkingTimer_ = setInterval( function(){
if (thinkingTimeLimit >0) {
document.getElementById("s5").innerHTML=pad(--thinkingTimeLimit%60);
document.getElementById("minutes5").innerHTML=pad(parseInt(thinkingTimeLimit/60,10));
}
if (thinkingTimeLimit == 0) {
clearInterval(thinkingTimer_);
document.getElementById("s5").innerHTML="10";
document.getElementById("minutes5").innerHTML="00";
jQuery(".InputText").show();
document.getElementById("instructions5").innerHTML = "You now have 10 seconds to type in the two fruits. The page will automatically move on to the next page once time is up.";
startTypingTimer();
}
}, 1000);
}*/
function pad (val) {
return val > 9 ? val : "0" + val;
}
//startThinkingTimer();
});

Chrome Extensions: Javascript not not running clearInterval();

I'm trying the make a chrome extension in javascript. So far, my popup.js looks like this:
let bg;
let clock;
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('button1').addEventListener('click', butClicked);
bg = chrome.extension.getBackgroundPage();
//clock = document.getElementById("label1");
});
let timeStamp;
let isClockRunning = false;
function butClicked() {
let test = bg.getURL();
document.getElementById('test').innerHTML = test;
timeStamp = new Date();
isClockRunning = !isClockRunning;
runCheckTimer();
}
function runCheckTimer() {
var handle;
if(isClockRunning == true) {
handle = setInterval(updateClock, 1000);
}
else if(isClockRunning == false) {
clearInterval(handle);
handle = 0;
}
}
function updateClock() {
let seconds = bg.returnTimeSince(timeStamp);
document.getElementById("label1").innerHTML = "Seconds: " + seconds;
}
The program works just fine when I click the button once; it starts the timer. But when I click the button the second time, timeStamp gets set to 0, but the updateClock keeps running at the same interval; the interval doesn't get cleared even though I'm toggling the isClockRunning boolean. It's almost as if javascript is forgetting to run the else if part in runCheckTimer(). How can I fix this?
EDIT: On a sidenote, am I doing the timer thing the right way? Or is there a better way to do it? I basically want a timer to keep ticking every second since you've pressed the button, and then when you click it again it'll stop and reset to 0.
You have scoped handle to runCheckTimer. When runCheckTimer starts, it will create a new handle every time.
Move handle outside of the function.
var handle;
function runCheckTimer() {
if(isClockRunning == true) {
handle = setInterval(updateClock, 1000);
}
else if(isClockRunning == false) {
clearInterval(handle);
handle = 0;
}
}

Change background images using setTimeout

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);
};

Restarting setInterval in javaScript

var myImage = document.getElementById("mainImage");
var imageArray = ["_images/overlook.jpg","_images/winery_sign.jpg","_images/lunch.jpg",
"_images/bigSur.jpg","_images/flag_photo.jpg","_images/mission_look.jpg"];
var imageIndex = 0;
function changeImage() {
myImage.setAttribute("src",imageArray[imageIndex]);
imageIndex++;
if (imageIndex >= imageArray.length) {
imageIndex = 0;
}
}
I tried to refactor this question restarting a setInterval, but couldn't get it right. Any help would be appreciated!
***Added context****
Basically I have a bunch of images that cycle through and stop upon clicking them. I'd like to restart the cycling upon clicking again...
var intervalHandle = setInterval(changeImage,5000);
//Basically I want a clearInterval on a click and then restart this changing image function it.
myImage.onclick = function(){
clearInterval(intervalHandle);
intervalHandle = setInterval(changeImage,5000);
};
I expect the problem is that setInterval doesn't fire immediately, and you're expecting it to call changeImage as soon as you click myImage. The first call to changeImage will be 5 seconds after clicking the image. You could do something like this to call changeImage immediately:
myImage.onclick = function () {
clearInterval(intervalHandle);
intervalHandle = setInterval(changeImage, 5000);
changeImage();
};
Another choice is to do away with intervals entirely (as with this answer) — intervals can queue up when the window isn't focused in some browsers, so you could have changeImage set its own timeouts:
var timeoutHandle = setTimeout(changeImage, 5000);
function changeImage() {
// ...
timeoutHandle = setTimeout(changeImage, 5000);
}
myImage.onclick = function () {
clearTimeout(timeoutHandle);
changeImage();
};
Basically I have a bunch of images that cycle through and stop upon clicking them. I'd like to restart the cycling upon clicking again...
Well why didn't you say so? ;)
So you want to start the interval if its not started, and stop it if it is started.
var intervalHandle = setInterval(changeImage, 5000); // start the interval by default
var running = true; // true if the interval is running, false if its not.
myImage.onclick = function(){
if (running) {
clearInterval(intervalHandle); // stop interval
running = false; // mark interval as stopped
} else {
intervalHandle = setInterval(changeImage, 5000); // start interval
running = true; // mark interval as started
changeImage(); // also change the image right now
}
};
the only reason why i think this would not work is if you define intervalHandle in a "dom ready" event or some other function so try putting it in global scope rather than defining it.
EDIT: sorry for the first reply it was indeed false beacause i didnt had full information of what you wanted to do so home this will help you
var intervalHandle = setInterval(changeImage,5000);
myImage.onclick = function(){
if (intervalHandle > -1) {
clearInterval(intervalHandle);
intervalHandle = -1;
} else {
intervalHandle = setInterval(changeImage,5000);
}
};

Why will my JQuery only run if I place window load function within?

My following code will not function, unless I place it all
$(window).load(function(){
// within here
}
How can I get my code to run without requiring the above function?
Thanks!
My code:
// Player controls
var timer = null;
$('#left').mousedown(function() {
moveLeft(); // Do it now
timer = setInterval(moveLeft, 5); // Then every 100 ms
}).mouseup(function() {
clearInterval(timer); // And stop it
});
function moveLeft() {
var nextpos = parseInt($('#player').css('left')) - 5;
if (nextpos > 0) {
$('#player').css('left', nextpos + 'px');
}
}
$('#right').mousedown(function() {
moveRight(); // Do it now
timer = setInterval(moveRight, 5); // Then every 100 ms
}).mouseup(function() {
clearInterval(timer); // And stop it
});
function moveRight() {
var nextpos = parseInt($('#player').css('left')) + 5;
if (nextpos < PLAYGROUND_WIDTH - 100) {
$("#player").css("left", ""+nextpos+"px");
}
}
// Timer
$(function(){
var timercount = 30;
countdown = setInterval(function(){
$("#timer").html(timercount);
if (timercount <= 0) {
$("#timer").html("TIMES UP");
}
timercount--;
}, 1000);
});
I'm going to assume you're not trying to get a comparison of why you need $(window).load and not $.ready. Anyway, javascript is run as it's seen. You've got jquery looking up elements (#right, #player, etc) that probably haven't been loaded into the page yet. So, because these elements are not on the page, jQuery can't bind these events to them.
Read this through - it may more thoroughly answer your question. http://api.jquery.com/ready/
If you run the code at the end of the page, rather than in the header, those elements should be loaded by the time the javascript runs.
That said, if your code is comparing the size of images, the images need to be loaded first...
You have to put it below your HTML..
<body>
//your html stuff here that uses the script
<script type="text/javascript">
// the js code here
</script>
</body>

Categories