How can I delay focus event in jquery? - javascript

I have a few buttons on my page and I want to switch focus on each on of them with a certain delay. How I can achieve that with jquery or pure javascript. This is the idea I have for iterating along all my buttons but I obviously end up with the focus on my last button.
$(document).ready(function() {
var allButtons = $(":button");
for (i=0;i<=allButtons.length;i++) {
$('.category_button')[i].focus()
}
});

You can do this by creating a closure within your for loop and passing the index to the setTimeout delay:
var allButtons = $(":button");
for (i = 0; i < allButtons.length; i++) {
(function(index) {
setTimeout(function() {
allButtons[index].focus();
}, 1000*index);
}(i));
}
See example here.

You can use setTimeout to call a function after a delay. The function can set the focus on your next button.
So pseudocode --
setTimeout(2000, focusOn(0));
// somewhere else
function focusOn(i) {
$('.category_button')[i].focus();
if (i + 1 < numButtons)
{
setTimeout(2000, focusOn(i + 1);
}
}

var currentButtonIndex = 0;
function FocusButton()
{
// focus current button index here
// increment counter
// some condition when to stop
// call FocusButton again with delay
// window.setTimeout(FocusButton,1000);
}

Related

How to make a button in JavaScript execute code only once?

I created a button that creates a grid. However, clicking on the button repeatedly executes the code repeatedly and I only want it to execute once. The code is below:
inputBtn.addEventListener("click", function () {
createGrid();
});
function createGrid() {
for (let i = 0; i < 256; i++) {
div = document.createElement("div");
div.classList.add("grid-child");
if (gridContainer) {
randomColor();
}
gridContainer.appendChild(div);
}
}
I created a loop that I thought would stop executing after 256 times. I also tried adding a break at the very end but that led to some other problems.
Set the once option to true when adding the listener:
inputBtn.addEventListener(
"click",
function () {
createGrid();
},
{ once: true }
);

Click on every instance of a certain word in a page using Javascript

Im trying to program something using JQuery that will search a webpage for every instance of a certain word and then click on it. How would I do this?
I currently have something like this:
$(document).ready(function(){
function follow(texttofind, texttoexclude, setinterval){
var buttons = $( "*:contains('"+texttofind+"'):not(:contains('"+texttoexclude+"'))" );
var i = 0;
interval = setInterval(function() {
while(i <= buttons.length) {
i++
buttons[i].scrollIntoView();
buttons[i].click();
}
}, setinterval);
}
follow("text", "200");
});
The value of i is changing every time the while loops.
You can simplify it all by using $.each() instead of while/[i]:
$(document).ready(function() {
function follow(texttofind, texttoexclude, setinterval) {
var buttons = $("*:contains('" + texttofind + "'):not(:contains('" + texttoexclude + "'))");
interval = setInterval(function() {
buttons.each(function(i, button) {
button.scrollIntoView();
button.click();
});
}, setinterval);
}
follow("text", "stop", "2000");
});
See demo here.

Scoping issue with using clearTimeout

I am using setTimeout to run a slideshow. I want to have button to stop it. The markup is:
<h3> Modest Mouse at Fillmore in Miami <h3>
<div>
<img id="photo" src="http://the305.com/blog/wp-content/uploads/2014/05/modestmouse3.jpg" alt= "Modest Mouse at Fillmore">
<span>•</span>
<span>•</span>
<span>•</span>
</div>
<button onclick="stopShow();">Stop</button>
The JS is:
var aSlideShowPics = ["http://the305.com/blog/wp-content/uploads/2014/05/modestmouse3.jpg",
"http://the305.com/blog/wp-content/uploads/2014/05/modestmoude7.jpg",
"http://the305.com/blog/wp-content/uploads/2014/05/modestmouse8.jpg"
];
// Timer for SlideShow
var i = 0;
function changeSlide() {
var stopShowID;
stopShowID = window.setTimeout(function() {
newPic = aSlideShowPics[i];
$("#photo").attr("src", newPic);
i++;
if (i < aSlideShowPics.length) {
changeSlide(); // recursive call to increment i and change picture in DOM.
} else {
i = 0; // reset loop to keep slideshow going
changeSlide(); // Recursive call on loop end
}
function stopShow() {
window.clearTimeout(stopShowID);
}
}, 3000)
}
changeSlide();
I keep getting a reference error on button click of no stopShow. I've tried putting the clearTimeout function in several places in code but get same error. Perhaps a new set of eyes can see my error. Here is the jsfiddle. Thanks for any input.
Move the stopShow outside of the timeout and outside of changeSlide.
var stopShowID;
function changeSlide() {
stopShowID = window.setTimeout( function(){}, 3000);
}
function stopShow() {
if(stopShowID) {
window.clearTimeout(stopShowID);
stopShowID = null;
}
}
the stopShow() method does not exists at the window level, it only exists within the body of changeSlide(). Directly attach it to window
window.stopShow = function() ...
or pull it out of the closure
var i = 0;
var stopShowId;
function stopShow() {
window.clearTimeout(stopShowID);
}
function changeSlide() {
stopShowID = window.setTimeout(function() {
if (i >= aSlidesShowPics.length - 1)
i = 0;
var newPic = aSlideShowPics[i++];
$("#photo").attr("src", newPic);
changeSlide();
}, 3000);
}
I couldn't launch your jsfidle example, so I update the content of your code, 2 issues raised:
1- Your stopShow was undefined, so I attached it to window scope:
window.stopShow = stopShow;
2- For your ClearTimeout scope issue: your stopShowID variable was inside your function changeSlide: your stopShow was using a local copy. I basically put it as a global variable so both function could have access to it.
var aSlideShowPics = ["http://the305.com/blog/wp-content/uploads/2014/05/modestmouse3.jpg",
"http://the305.com/blog/wp-content/uploads/2014/05/modestmoude7.jpg",
"http://the305.com/blog/wp-content/uploads/2014/05/modestmouse8.jpg"
];
// Timer for SlideShow
var stopShowID;
var i = 0;
function stopShow() {
window.clearTimeout(stopShowID);
}
window.stopShow = stopShow;
function changeSlide() {
stopShowID = window.setTimeout(function() {
newPic = aSlideShowPics[i];
$("#photo").attr("src", newPic);
i++;
if (i < aSlideShowPics.length) {
changeSlide(); // recursive call to increment i and change picture in DOM.
} else {
i = 0; // reset loop to keep slideshow going
changeSlide(); // Recursive call on loop end
}
}, 3000)
}
changeSlide();
working jsfiddle:
http://jsfiddle.net/fLw2a4vs/44/

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

JQuery not executing within a For loop

Im a JQuery noob trying to write a simple jQuery code to get a text to blink three times. My initial code was as follows:
$("#welcome").click(function () {
var i = 1;
while (++i < 10) {
$("#welcome").fadeOut("slow", function () { $("#welcome").fadeIn("slow"); })();
}
});
But since I probably meddled in forces I could not comprehend, the above code made the text blink only once. I read up on closures and got convinced that the below code could make a change. Unfortunately, it doesnt.
$("#welcome").click(function () {
var i = 1;
while (++i < 10) {
(function (i) {
$("#welcome").fadeOut("slow", function () { $("#welcome").fadeIn("slow"); })();
})(i);
}
});
Can anyone tell me whats going on here?
You need make use of the animation queue
var $welcome = $("#welcome").click(function () {
var i = 1;
//clear previous animations
$welcome.stop(true, true);
while (++i < 10) {
$welcome.fadeOut("slow").fadeIn("slow");
}
});
Demo: Fiddle
Fading in and out takes some time, and you have to wait for your animation to be over before you can run the next one.
The provided answers solve your problem since jQuery is clever enough to bufferize your animation queue, but it may creates even more confusion for begginers, and also if you want to do something else between the fading animations, you can't rely on it anymore.
You then have to write your code on what is called an asynchronous recursive way (woah). Simply trying to understand that snippet may help you a lot with javascript general programming.
function blink(nbBlinks) {
// Only blink if the nbBlinks counter is not zero
if(nbBlinks > 0) {
$('#welcome').fadeOut('slow', function() {
// Do stuff after the fade out animation
$(this).fadeIn('slow', function() {
// Now we're done with that iteration, blink again
blink(nbBlinks-1);
})
});
}
}
// Launch our blinking function 10 times
blink(10);
This works perfectly. Demo http://jsfiddle.net/X5Qy3/
$("#welcome").click(function () {
for (var x = 0; x < 3; x += 1) {
$("#welcome").fadeOut("slow");
$("#welcome").fadeIn("slow");
}
});
Also, if you know how many times you want to do something. You should use a For Loop. While Loops are for when you don't know how many times you want it to run.
Set in queue
$("#welcome").click(function () {
var i = 1;
//clear animations whcih are running at that time
$(this).stop(true, true);
while (++i < 10) {
$(this).fadeOut("slow").fadeIn("slow");
}
});
You can not use jQuery delay function inside a looping/iteration hence you have to user closures:
$(document).ready(function(){
$(".click1").click(function () {
for (i=0;i<=10;i++) {
setTimeout(function(x) {
return function() {
$("#wrapper").fadeOut("slow", function () { $("#wrapper").fadeIn("slow"); })();
};
}(i), 1000*i);
}
});
});
<div id="wrapper"></div><div class="click1">click</div>
You can later change the count how many times you want to blink the <div>.

Categories