Why am I required to click twice in order to change the classes after 'reseting'? How can I fix this issue?
The desired result is to bring the function back to the initial state and cycle through the arrays normally. Demo below.
$(function () {
var weights = ["jHairline", "jThin", "jLight", "jMedium"];
var currentIndex = 0;
$('#text').on('click', function (e) {
$("h1").removeClass().addClass(weights[currentIndex]);
$("h1").html(weights[currentIndex]);
if (currentIndex == weights.length - 1)
currentIndex = 0;
else
currentIndex++;
e.preventDefault();
});
$('#reset').click(function () {
currentIndex = 0;
$("h1").removeClass().addClass(weights[currentIndex]);
$("h1").html(weights[currentIndex]);
});
});
Demo
Because you reset it to 0 and don't increment it on the next update.
The quick fix would be
$('#reset').click(function() {
currentIndex = 0;
$("h1").removeClass().addClass(weights[currentIndex]);
$("h1").html(weights[currentIndex]);
currentIndex=1;
});
The proper way would be to do the incrementing at the beginning of the $('#text').on('click', function(e) { function
--Edit for clarification request--
This is how I would personally recommend writing it:
$(function () {
var weights = ["jHairline", "jThin", "jLight", "jMedium"];
var currentIndex = -1;
$('#text').on('click', function (e) {
currentIndex=(currentIndex+1)%weights.length;
$("h1").removeClass().addClass(weights[currentIndex]);
$("h1").html(weights[currentIndex]);
e.preventDefault();
});
$('#reset').click(function () {
currentIndex = 0;
$("h1").removeClass().addClass(weights[currentIndex]);
$("h1").html(weights[currentIndex]);
});
});
The 2 lines I added/modified were var currentIndex = -1; and currentIndex=(currentIndex+1)%weights.length; .
So essentially, you are incrementing the number by 1 when the text.click function starts. If you start it at -1 at the beginning, then when text.click enters, it will increment it to 0. And setting it to 0 in reset will make sure it increments to 1 next time text.click is ran.
Further,
if (currentIndex == weights.length - 1)
currentIndex = 0;
else
currentIndex++;
is a bit more concise and clear when written as currentIndex=(currentIndex+1)%weights.length; . It is adding 1 to the number, and then modding (taking the remainder when dividing) to loop it back around to 0 once weight.length is hit.
Related
// .items direct child
var itemsContainer = $('.blog-ticker').children();
// each item in .items
var items = $('.blog-ticker').children().children();
setInterval(function(){
var i = 0;
itemsContainer.css({
'top': -(items[i].clientHeight)+'px'
});
if(i <= items.length) {
i++;
}
}, 2000);
it stops after the first round... confusion sets in. What Should I do?
No it probably doesn't stop after the first round.
The problem is that you are declaring i to 0 each time the function runs, so you are just setting the first item to the same position and it appears to be doing nothing.
You just need to declare i outside of the function and it should work fine:
// .items direct child
var itemsContainer = $('.blog-ticker').children();
// each item in .items
var items = $('.blog-ticker').children().children();
// counter
var i = 0;
setInterval(function(){
itemsContainer.css({
'top': -(items[i].clientHeight)+'px'
});
if(i <= items.length) {
i++;
}
}, 2000);
I've a script which works fine when written like this:
var isPaused = false,
jQuery(function () {
var $els = $('div[id^=film]'),
i = 0,
len = $els.length;
$els.slice(1).hide();
setInterval(function () {
if (!isPaused) {
if (len > 1) {
$els.eq(i).fadeOut(function () {
i = (i + 1) % len;
$els.eq(i).fadeIn();
});
}
}
}, 3500);
});
But I wanted to add a next and prev button so I rewrote like this, which I thought would work.
var isPaused = false,
$els = $('div[id^=film]'),
i = 0,
len = $els.length;
$els.slice(1).hide();
setInterval(Slide(1), 3500);
function Slide (x) {
if (!isPaused) {
if (len > 1) {
$els.eq(i).fadeOut(function () {
i = (i + x) % len;
if (i<0) {
i = len;
}
$els.eq(i).fadeIn();
});
}
}
}
$('#next').click(Slide(1));
$('#prev').click(Slide(-1));
But this code is just displaying all the divs when the page is loaded and then doesn't fade them in and out or allow the next and prev buttons to work. What am I doing wrong?
UPDATE
Perhaps I should ask this differently. Given the first block of code, how should I change it to enable Prev and Next buttons?
You want to do:
$('#next').click(function(){Slide(1);});
$('#prev').click(function(){Slide(-1);});
and
setInterval(function(){Slide(1);}, 3500);
instead, as with your current code, Slide(1) is already being computed, and the click function will just call the value returned from it (as it has no return in the function, this will not be defined)
By wrapping your calls to Slide in a function, this makes the clicks call that function, which in turn calls Slide
You also want to set your index to len - 1 if you go negative, rather than to len, as you're dealing with a zero indexed array:
if (i<0) {
i = len - 1;
}
You jQuery event callbacks must be inside a load structure like:
// Wait for DOM load
$(document).ready(function() {
$('#next').click(function(){ Slide(1); });
$('#prev').click(function(){ Slide(-1); });
});
And I would like to suggest you to change your:
setInterval(Slide(1), 3500);
to
setInterval(function() {
Slide(1);
}, 3500);
Hope it helps
I have a full width slideshow. So I have a few problems with it.
One is that clearTimeout won't work. If I call the function by a click, it should clear the Timeout.
Does someone know why this won't work? Please explain and show where exactly the problem is.
Thank you and sorry for my bad English.
var index = 0;
var slideSpeed = 1000;
function mainSlider(menuLink){
clearTimeout(slide);
if(menuLink !== false){
alert('You call this function by a click event.');
clearTimeout(slide);
}
var sliderIndex = $('.main_slider_content').length - 1;
$('.main_slider_content').hide();
index++;
if(index > sliderIndex){
index = 0;
}
$('.main_slider_content:eq(' + index + ')').show();
var slide = setTimeout(function(){mainSlider(false)}, slideSpeed);
setTimeout(countContentImg(index), slideSpeed);
}
$(document).on('click', '.main_slider_menu_link',function(){
var linkIndex = $(this).index();
mainSlider(linkIndex);
});
function countContentImg(index){
$('#main_slider_selected_img').html('');
var sliderIndex = $('.main_slider_content').length;
for(var i = 0; i < sliderIndex; i++) {
if(i === index)
$('#main_slider_selected_img').append('<li class="main_slider_menu_link main_slider_menu_link_slected"></li>');
else
$('#main_slider_selected_img').append('<li class="main_slider_menu_link"></li>');
}
}
$(document).ready(function(){
countContentImg(index);
mainSlider(false);
});
This looks like a scope issue. You're trying to clear a timeout from a variable that doesn't contain a timeout reference yet. Each call to mainSlider creates a new, locally scoped timeout reference, long after you've tried to clear it.
function mainSlider(menuLink){
clearTimeout(slide); // Clearing a timeout that doesn't exist yet
if(menuLink !== false){
alert('You call this function by a click event.');
clearTimeout(slide); // Clearing a timeout that doesn't exist yet
}
var sliderIndex = $('.main_slider_content').length - 1;
$('.main_slider_content').hide();
index++;
if(index > sliderIndex){
index = 0;
}
$('.main_slider_content:eq(' + index + ')').show();
// Now the timeout exists, but only in the scope of this current call
var slide = setTimeout(function(){mainSlider(false)}, slideSpeed);
setTimeout(countContentImg(index), slideSpeed);
}
Change it to:
var slide;
function mainSlider(menuLink){
clearTimeout(slide);
if(menuLink !== false){
alert('You call this function by a click event.');
clearTimeout(slide);
}
var sliderIndex = $('.main_slider_content').length - 1;
$('.main_slider_content').hide();
index++;
if(index > sliderIndex){
index = 0;
}
$('.main_slider_content:eq(' + index + ')').show();
// Remove var
slide = setTimeout(function(){mainSlider(false)}, slideSpeed);
setTimeout(countContentImg(index), slideSpeed);
}
I have a problem, I have 3 button lets say it's called #pos1, #pos2 and #pos3.
I want to makes it automatically click #pos1 button in 2 seconds, after that click the #pos2 after another 2 seconds, and #pos3 after another 2 seconds,
after that back to the #pos1 in another 2 seconds and so on via jQuery.
HTML
<button id="pos1">Pos1</button>
<button id="pos2">Pos2</button>
<button id="pos3">Pos3</button>
Anyone can help me please?
Try
$(function() {
var timeout;
var count = $('button[id^=pos]').length;
$('button[id^=pos]').click(function() {
var $this = $(this);
var id = $this.attr('id');
var next = parseInt(id.substring(4), 10) + 1;
if( next >= count ){
next = 1
}
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(function() {
$('#pos' + next).trigger('click');
}, 2000);
})
timeout = setTimeout(function() {
$('#pos1').trigger('click');
}, 2000);
})
var posArray = ["#pos1", "#pos2", "#pos3"];
var counter = 0;
setInterval(function() {
$(posArray[counter]).triggerHandler('click');
counter = ((counter<2) ? counter+1 : 0);
}, 2000);
That should do the trick, though you did not mention when you want it to stop running.
Well I don't know what you already have but technically it could be done via triggerHandler()
var currentPos = 1,
posCount = 3;
autoclick = function() {
$('#pos'+currentPos).triggerHandler('click');
currentPos++;
if(currentPos > posCount) { currentPos = 1; }
};
window.setInterval(autoclick,2000);
If I have understood you question right, you need to perform click in a continuous loop in the order pos1>pos2>pos3>pos1>pos2 and so on. If this is what you want, you can use jQuery window.setTimeout for this. Code will be something like this:
window.setTimeout(performClick, 2000);
var nextClick = 1;
function performClick() {
if(nextClick == 1)
{
$("#pos1").trigger("click");
nextClick = 2;
}
else if(nextClick==2)
{
$("#pos2").trigger("click");
nextClick = 3;
}
else if(nextClick == 3)
{
$("#pos3").trigger("click");
nextClick = 1;
}
window.setTimeout(performClick, 2000);
}
This is quite buggy but will solve your problem.
using setInterval()
Calls a function or executes a code snippet repeatedly, with a fixed time delay between each call to that function.
var tempArray = ["pos1", "pos2", "pos3"]; //create an array to loop through
var arrayCounter = 0;
setInterval(function() {
$('#' + tempArray[arrayCounter ]).trigger('click');
arrayCounter = arrayCounter <2 ? arrayCounter +1 : 0;
}, 2000);
fiddle here
check your console for fiddle example
I have a jQuery/JS function that is using setInterval to loop through some image slides I have. It just flips through every 5 seconds...
Now I want it to pause if my mouse is hovered over it. How do I go about doing that on the setInterval function?
var current = 1;
function autoAdvance() {
if (current == -1) return false;
jQuery('#slide_menu ul li a').eq(current % jQuery('#slide_menu ul li a').length).trigger('click', [true]);
current++;
}
// The number of seconds that the slider will auto-advance in:
var changeEvery = jQuery(".interval").val();
if (changeEvery <= 0) {
changeEvery = 10;
}
var itvl = setInterval(function () {
autoAdvance()
}, changeEvery * 1000);
Something like this would work assuming interval is defined in an outer scope:
$('.slideshow img').hover(function() {
interval = clearInterval(interval);
}, function() {
interval = setInterval(flip, 5000);
});
(function () {
var imgs = $('#your_div img'), index = 0, interval,
interval_function = function () {
imgs.eq(index).hide();
index = (index + 1) % imgs.length;
imgs.eq(index).show();
};
imgs.eq(0).show();
interval = setInterval(interval_function, 5000);
$('#your_div').hover(function () {
clearInterval(interval);
}, function () {
interval = setInterval(interval_function, 5000);
});
}());
Example: http://jsfiddle.net/Zq7KB/3/
I reused some old code I wrote for a question the other day, but I figured it didn't matter that much. The trick is to store your interval in a variable that you keep in the background. Then, when you hover over the container, clear the interval. When you hover out of the container, re-set the interval. To get a better feel of how this works, change those 5000s to 1000s so it passes more quickly for testing.
Hope this helps.