I'm pretty new to JavaScript, so please forgive me if this is a stupid question. I am using the below code to get an image to slide onto the screen and 2 more images to appear one after the other. This works fine for Chrome and IE 7-9. Unfortunately, on Firefox I get an error saying:
move is not defined [ mover = setInterval(move, 1000); ]
My Code:
//define variables
var mover = 0
var bubble1move = 0
var bubble2move = 0
if(mover != 0)
{//interval is finished
function move ()
{
console.log("moving")
clearInterval(mover)
var moving_img = document.getElementById("i_sliding_image")
var left = 0
function frame()
{
left -= 2 // update parameters
moving_img.style.left = left + 'px'// show frame
if (left == -274) // check finish condition
{
clearInterval(id)
bubble1move = setInterval(function() {bubble1()}, 2000);
}
}
var id = setInterval(frame, 10) // draw every 10ms
}
}
if(bubble1move != 0)
{//interval is finished
function bubble1()
{
clearInterval(bubble1move);
document.getElementById("img-bubble1").style.zIndex = "1";
bubble2move = setInterval(function() {bubble2()}, 2000);
}
}
if(bubble2move != 0)
{//interval is finished
function bubble2()
{
clearInterval(bubble2move)
var vBubble2 = document.getElementById("img-bubble2").style
vBubble2.zIndex = "1";
}
}
window.onload = function initialiser()
{
mover = setInterval(move, 1000);//initial time to animation
}
All getElementByIds are getting div tags containing the images.
Thanks for your time.
Looks like you are initializing your mover variable at the begining of your js to 0 and your if statement is only declaring the function if mover != 0. Initialize mover = 1; or take your function outside of the if statement(recommended). You're just trying to call move() before it exists
Move your function outside of the if. There is no reason for it to be within the if. It doesn't work on Firefox because of the way Firefox interprets functions (differently to other browsers).
See this question for more info.
Thanks to #freakish for the link.
Related
I have this function running on a mousemove event. The functionality is to iterate a list of images and move to the top (z-index) each one at a time. This is working right but my problem is that the script is running really fast and the images displays really fast. How can I add a delay to the function or the event? I tried with setTimeOut with no positive effects
Here's the code
// creating variables
const imgQty = 6;
const holder = document.getElementById('holder')
var counter = 1;
var isMoving = false;
var bgtimeout, imgtimeout;
var bkgImgs = []
// this creates the containers for each img
for (let i = 1; i <= imgQty; i++) {
var newDiv = document.createElement('div');
newDiv.classList.add('background')
newDiv.classList.add(`background--${i}`)
newDiv.setAttribute("style", `background-image: url('imgs/${i}.jpg'); z-index: 0;`);
holder.appendChild(newDiv);
bkgImgs.push(newDiv)
}
//this moves the counter and also hides the images when the mouse is not moving
function changeBkg(e){
counter >= imgQty ? counter = 1 : counter++
holder.classList.add('isActive')
clearTimeout(bgtimeout);
clearTimeout(imgtimeout);
bgtimeout = setTimeout(function(){holder.classList.remove('isActive')}, 150);
moveImgs();
}
// and here is where my issue is, this function is working but not as I expected
function moveImgs(){
for(var i = 0; i < bkgImgs.length; i++){
if(bkgImgs[i].classList.contains(`background--${counter}`)){
bkgImgs[i].style.zIndex = "1";
} else{
bkgImgs[i].style.zIndex = "0";
}
}
}
Is my logic right? or do I have to rethink the code?
the event is fired in the section:
<section class="main" onmousemove="changeBkg(event)"></section>
Use Debounce
Something like this should work (remove the timeout from inside changeBkg):
//change 300ms to suite your needs
<section class="main" onmousemove="debounce(changeBkg(event),300)"></section>
A debounce is a higher-order function, which is a function that returns another function. This is done to form a closure around the func , wait , and immediate function parameters and the timeout variable so that their values are preserved.
Further reading/if you prefer to implement yourself: Debounce Article
It has been resolved.
As what I needed was some sort of animation I figured it out using greensock
So my event have inside this animation that triggers when animPlay is true and when is playing remains false
if(animPlay){
animPlay = false
var tl = new TimelineMax();
tl.staggerFromTo(bkgImgs, .5, {zIndex:0}, {zIndex:1}, .15, 0)
.set(bkgImgs, {zIndex:0, onComplete:() => animPlay = true}, '+=0' )
}
I am busy making a memory game, where an image is to be displayed to the user, and after some 10 seconds of the image flashing, it should hide and four options are to be shown for the user to choose either the correct or incorrect answer.
So far, all I have accomplished is to load the images and cycle through all the puzzles that my code can find.
What I'm trying to do now is to make the image flash and hide after some time, while also just refreshing that section of the page, and not the entire page.
I am using C# and a user control on my page.
What I have tried so far is only
<script>
var x;
function BlinkImage() {
x = 1;
setInterval(change, 2000);
}
function change() {
if (x === 1) {
var image = document.getElementById('<%=imgMain.ClientID %>');
image.visible = false;
x = 2;
}
else {
var image = document.getElementById('<%=imgMain.ClientID %>');
image.visible = true;
x = 1;
}
}
</script>
And on loading my puzzle for that instance (in code behind)
Page.ClientScript.RegisterStartupScript(typeof(game), "Start", "<script language=javascript> BlinkImage(); </script>");
Which does fire, as I can step through the code in debugging on Firefox. But my image does not flash or blink. I understand I am just using visiblity as my "blinker". I don't know what else to use exactly.
What can I do to make the image flash or blink for, say 20 seconds, then hide the image after that time has passed? Then repeat the process once the user has made a choice.
You can try the following (comments in code):
var blinkInterval = setInterval(change, 2000), // set the interval into a variable
image = document.getElementById('test'), // replace test with your client id: <%=imgMain.ClientID %>
x = 1;
function change() {
if (x % 2 === 1) { // see if it is odd or even by modding by 2 and getting remainder
image.style.display = 'none';
} else {
image.style.display = 'block';
}
x++; // increment x
if (x === 10) { // should have happened 10 times (which is 20 seconds with your intervals being at 2 seconds)
clearInterval(blinkInterval); // clear the interval (should end hidden as odd is display none and we clear beforethe 20th is run)
}
}
<div id="test">test</div>
After the code has finished, wherever the user is making their selection, you just need to reset the blinkInterval variable:
blinkInterval = setInterval(change, 2000); // notice no need for the var declaration when you reset this
Use style attribute and change if visible/hidden
function change() {
var image = document.getElementById('<%=imgMain.ClientID %>');
//check if visible
if (image.style.visibility=="visible") {
image.style.visibility="hidden";
}
else {
image.style.visibility="visible";
}
}
;
Try this:
function flashAndHide(img_id){
var img = $("#"+img_id);
var x = 0;
var inter = setInterval(function(){
if(x % 2 == 0){
img.hide();
}else{
img.show();
}
x += 1;
}
},1000);
if(x === 20){
img.hide();
clearInterval(inter);
}
}
Haven't tested this, but it should work,
I'm developing a simple slideshow system.
I've got the slideshow wrapped in a hidden div, which is shown when a thumbnail from the gallery is clicked.
The slideshow works through a function called commence(), which is executed when the play button is clicked.
At the moment I've got it set to hide to whole div again when stop is clicked, but I would like to keep the div shown, simply stop the slideshow, in other words, stop the commence() function.
Can anyone tell me how to do this?
Here is my JS:
function commence() {
hidden = document.getElementById("hidden");
hidden.style.display = 'block';
pause = document.getElementById("pause");
pause.style.display = 'block';
play = document.getElementById("play");
play.style.display = 'none';
pic = document.getElementById("picbox"); // Assign var pic to the html element.
imgs = []; // Assign images as values and indexes to imgs array.
/* --------------------------- IMAGE URLS FOR IMGS ARRAY -------------------------*/
imgs[0] = "/snakelane/assets/images/thumb/_1.jpg"; imgs[10] = "/snakelane/assets/images/thumb/_19.jpg";
imgs[1] = "/snakelane/assets/images/thumb/_2.jpg"; imgs[11] = "/snakelane/assets/images/thumb/_20.jpg";
imgs[2] = "/snakelane/assets/images/thumb/_3.jpg"; imgs[12] = "/snakelane/assets/images/thumb/_21.jpg";
imgs[3] = "/snakelane/assets/images/thumb/_4.jpg"; imgs[13] = "/snakelane/assets/images/thumb/_22.jpg";
imgs[4] = "/snakelane/assets/images/thumb/_5.jpg"; imgs[14] = "/snakelane/assets/images/thumb/_23.jpg";
imgs[5] = "/snakelane/assets/images/thumb/_6.jpg"; imgs[15] = "/snakelane/assets/images/thumb/_24.jpg";
imgs[6] = "/snakelane/assets/images/thumb/_7.jpg"; imgs[16] = "/snakelane/assets/images/thumb/_25.jpg";
imgs[7] = "/snakelane/assets/images/thumb/_8.jpg"; imgs[17] = "/snakelane/assets/images/thumb/_26.jpg";
imgs[8] = "/snakelane/assets/images/thumb/_9.jpg"; imgs[18] = "/snakelane/assets/images/thumb/_27.jpg";
imgs[9] = "/snakelane/assets/images/thumb/_10.jpg"; imgs[19] = "/snakelane/assets/images/thumb/_28.jpg";
/* -----------------------------------------------------------------------------------------------------*/
var preload = []; // New array to hold the 'new' images.
for(i = 0 ; i < imgs.length; i++) // Loop through imgs array
{
preload[i] = new Image(); // Loop preload array and declare current index as a new image object.
preload[i].src = imgs[i]; // Fill preload array with the images being looped from ims array.
}
i = 0; // Reset counter to 0.
rotate(); // Execute rotate function to create slideshow effect.
}
// Function to perform change between pictures.
function rotate() {
pic.src = imgs[i]; // Change html element source to looping images
(i === (imgs.length -1))?(i=0) : (i++); // counter equals imgs array length -1.
setTimeout( rotate, 4000); // Sets the time between picture changes. (5000 milliseconds).
}
function init() {
[].forEach.call(document.querySelectorAll('.pic'), function(el) {
el.addEventListener('click', changeSource);
});
function changeSource() {
hidden = document.getElementById("hidden");
hidden.style.display = 'block';
newpic = this.src;
var pic = document.getElementById("picbox");
pic.src = newpic;
}
}
document.addEventListener("DOMContentLoaded", init, false);
function stopSlide() {
var hidden = document.getElementById("hidden");
hidden.style.visibility = 'hidden';
pause.style.display = 'none';
var play = document.getElementById("play");
play.style.display = 'block';
}
The pause and play statements are not relevant to my question, they simply hide the play button and show the pause button if the slideshow is running, and vice versa.
It looks to me like you actually want to stop the rotate() function, rather then commence, since rotate is what is actually changing the images (ie running the slideshow).
There are two ways. The first, like thriqon posted, is to use the clearTimeout function. However I'd recommend doing it like this:
// somewhere in global space
var rotateTimeout;
// in commence
rotateTimeout = window.setInterval(rotate,4000); // this will tell the browser to call rotate every 4 seconds, saving the ID of the interval into rotateTimeout
// in stopSlide
window.clearInterval(rotateTimeout); // this will tell the browser to clear, or stop running, the interval.
The second, which is a bit messier, is to use a sentinel.
// somewhere in global space
var running;
// in commence
running = true;
rotate();
// in stopSlide
running = false;
// in rotate
if (running) {
setTimeout(rotate,4000);
}
You want to use window.clearTimeout using the id you get by call window.setTimeout.
But you should also consider switching to window.setInterval, which gives you an function call every 4 seconds (and not 4 seconds after the last call), the not-needing of repeated calls to re-set the timeout and a better handling of missed events.
See this jsFiddle: http://jsfiddle.net/D3kMG/ for an example on how to use these functions for a simple counter.
As mentioned by #thriqon you will want to use window.clearTimeout. To do this you need to save a "global" reference to the id returned by window.setTimeout, as follows:
var timeoutID;
//... function declarations
function rotate() {
//...
timeoutID = setTimeout( rotate, 4000);
}
Then in your stopSlide function you'll simply call clearTimout( timeoutID ) to stop the rotation.
http://www.ultralocal.fr/refonte/test.php
As you can see, I have a menu with a few links. All of them, except one, launch a small script that changes the background color according to the onclick thing. The "Talweg" link work another way, it launches a bigger script that actually makes the background color change from time to time, progressively.
What I would like to know is how I can make the other links stop the Talweg script and just change the bgcolor for once.
the menu:
× Désœuvrements<br />
× Recettes<br />
× Talweg<br />
the simple script:
function changeBGC(color){
document.bgColor = color;
}
the bigger script that can be launched when one clicks on Talweg but I want to stop when one clicks on the other links.
// Set 1 dark to medium
// Set 2 light to medium
// Set 3 very dark to very light light
// Set 4 light to very light
// Set 5 dark to very dark
var fade_effect=4
// What type of gradient should be applied Internet Explorer 5x or higher?
// Set "none" or "horizontal" or "vertical"
var gradient_effect="none"
var speed=800
var browserinfos=navigator.userAgent
var ie4=document.all&&!document.getElementById
var ie5=document.all&&document.getElementById&&!browserinfos.match(/Opera/)
var ns4=document.layers
var ns6=document.getElementById&&!document.all
var opera=browserinfos.match(/Opera/)
var browserok=ie4||ie5||ns4||ns6||opera
if (fade_effect==1) {
var darkmax=1
var lightmax=127
}
if (fade_effect==2) {
var darkmax=180
var lightmax=254
}
if (fade_effect==3) {
var darkmax=1
var lightmax=254
}
if (fade_effect==4) {
var darkmax=204
var lightmax=254
}
if (fade_effect==5) {
var darkmax=1
var lightmax=80
}
var hexc = new Array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F')
var newred
var newgreen
var newblue
var oldred
var oldgreen
var oldblue
var redcol_1
var redcol_2
var greencol_1
var greencol_2
var bluecol_1
var bluecol_2
var oldcolor
var newcolor
var firsttime=true
var stepred=1
var stepgreen=1
var stepblue=1
function setrandomcolor() {
var range=(lightmax-darkmax)
if (firsttime) {
newred=Math.ceil(range*Math.random())+darkmax
newgreen=Math.ceil(range*Math.random())+darkmax
newblue=Math.ceil(range*Math.random())+darkmax
firsttime=false
}
oldred=Math.ceil(range*Math.random())+darkmax
oldgreen=Math.ceil(range*Math.random())+darkmax
oldblue=Math.ceil(range*Math.random())+darkmax
stepred=newred-oldred
if (oldred>newred) {stepred=1}
else if (oldred<newred) {stepred=-1}
else {stepred=0}
stepgreen=newgreen-oldgreen
if (oldgreen>newgreen) {stepgreen=1}
else if (oldgreen<newgreen) {stepgreen=-1}
else {stepgreen=0}
stepblue=newblue-oldblue
if (oldblue>newblue) {stepblue=1}
else if (oldblue<newblue) {stepblue=-1}
else {stepblue=0}
fadebg()
}
function fadebg() {
if (newred==oldred) {stepred=0}
if (newgreen==oldgreen) {stepgreen=0}
if (newblue==oldblue) {stepblue=0}
newred+=stepred
newgreen+=stepgreen
newblue+=stepblue
if (stepred!=0 || stepgreen!=0 || stepblue!=0) {
redcol_1 = hexc[Math.floor(newred/16)];
redcol_2 = hexc[newred%16];
greencol_1 = hexc[Math.floor(newgreen/16)];
greencol_2 = hexc[newgreen%16];
bluecol_1 = hexc[Math.floor(newblue/16)];
bluecol_2 = hexc[newblue%16];
newcolor="#"+redcol_1+redcol_2+greencol_1+greencol_2+bluecol_1+bluecol_2
if (ie5 && gradient_effect!="none") {
if (gradient_effect=="horizontal") {gradient_effect=1}
if (gradient_effect=="vertical") {gradient_effect=0}
greencol_1 = hexc[Math.floor(newred/16)];
greencol_2 = hexc[newred%16];
bluecol_1 = hexc[Math.floor(newgreen/16)];
bluecol_2 = hexc[newgreen%16];
redcol_1 = hexc[Math.floor(newblue/16)];
redcol_2 = hexc[newblue%16];
var newcolorCompl="#"+redcol_1+redcol_2+greencol_1+greencol_2+bluecol_1+bluecol_2
document.body.style.filter=
"progid:DXImageTransform.Microsoft.Gradient(startColorstr="+newcolorCompl+", endColorstr="+newcolor+" GradientType="+gradient_effect+")"
}
else {
document.bgColor=newcolor
}
var timer=setTimeout("fadebg()",speed);
}
else {
clearTimeout(timer)
newred=oldred
newgreen=oldgreen
newblue=oldblue
oldcolor=newcolor
setrandomcolor()
}
}
Thanks
The longer-running script keeps re-executing itself with selfTimeout. If you want to stop it, all you need to do is call clearTimeout on the returned variable:
clearTimeout(timer)
Of course, you may need to be a bit more careful, because the script may be in the middle of the execution when you clear the timeout. One way to deal with it would be to set a flag indicating that the script need not be re-executed again. You can pull variable declarations out of the functions to make the code easier to read. So your code can look like this:
//variable declaration for use in fadebg function
var timer;
//variable declaration for the flag
var contBg = true;
//stop your previous script
function stopRandomBg() {
clearTimeout(timer);
contBg = false;
}
//changes to fadebg function
function fadebg() {
...
//change this line
//var timer=setTimeout("fadebg()",speed);
//to
if(contBg) {
timer=setTimeout("fadebg()",speed);
}
...
}
These additional changes will take care of the case when the script is in the middle of execution when you try to stop it - it will complete the execution pass and then stop.
Now all you need to do is to add onClick event listener to your link to call stopRandomBg function.
You have to make the timer variable global instead of local.
var timer;
then clear the timer when ever you call other links.
function changeBGC(color){
clearTimeout(timer);
document.bgColor = color;
}
I`m having a troubble with a simple thing.
I have an div, when clicked, an amination start (an infinite loop of images changing, simulating an animated gif).
But, when i click on the other div, the first one need to stop, and start just the other animation, and this goes on to every animation (will be 8 on total).
Here is the code for just one image loop:
var t1;
var t2;
var anim1 = new Array ('img/testes2/anim1_1.png','img/testes2/anim1_2.png');
var anim2 = new Array ('img/testes2/anim2_1.png','img/testes2/anim2_2.png');
var index = 1;
var verifica1 = 0;
var verifica2 = 0;
function rotateImage1(){
$('#imagemPrinc').fadeOut(0, function(){
$(this).attr('src', anim1[index]);
$(this).fadeIn(0, function(){
if (index == anim1.length-1){
index = 0;
}
else{
index++;
}
});
});
return false;
}
function stopTimer1(){
if(verifica1 = 1){
clearInterval(t2);
}
}
function muda1(){
if (verifica1 = 1){
//stopTimer2();
//$('#bgImagem').css({'background-image':'url(img/testes2/anim1_1.png)'});
t1 = setInterval(rotateImage1,500);
}
}
The same function for the second animation.
The verifica var, and the stopTimer function, i tried to make one stop, and just the other plays, but doesn't seems to be working. That's why it's commented on the code.
It will be easier to look the code running, so thats it ---HERE---
The clickable divs are those two Red Squares.
Someone can help me please!?
Thanks!
clearTimeout takes as argument the timer id returned by the setInterval function (here it's t1).
Instead of using fadeOut and fadeIn with a duration of 0, you should simply use hide and show.
As an aside, you can simplify this block :
if (index == anim1.length-1){
index = 0;
}
else{
index++;
}
in
index = [(index+1)%anim1.length];
And this is very wrong :
if(verifica1 = 1){
This is not a test : it always change verifica1 and is always true. You probably want ==.
Is there a point in your code where you (voluntarily) set verifica1 ?