I have a jQuery function to fadeIn/Out images in a div. But when the function reaches last image, it gets stopped. Any way to get it in a loop, so that at the end of last image, it will start again from the first image.
here is the code
HTML:
<div id="homeimg">
<img src="image1.jpg" />
<img src="image2.jpg" />
<img src="image3.jpg" />
<img src="image4.jpg" />
</div>
jQuery:
$(document).ready(function(){
$('#homeimg img:first-child').addClass('activeimg');
setInterval('cycleMe()', 4000);
});
function cycleMe() {
$('.activeimg').next().css('z-index', 10);
$('.activeimg').next().fadeIn(1500);
$('.activeimg').fadeOut(1500, function(){
$(this).next().fadeIn(0);
$(this).next().addClass('activeimg');
$(this).css('z-index', 5).removeClass('activeimg');
});
}
Any possibilities?
First of all, you're passing the function in as a string, which is a no-no. I think you're over-complicating your code, and there are some jQuery efficiencies you can leverage.
First, I don't think it's necessary to modify the z-index of your images: the fading should handle all that. Secondly, you can chain jQuery calls (see below how fadeIn and addClass chained). Lastly, every time you do $('.activeimage'), jQuery has to scan the DOM again, which is inefficient. Best to do it once and cache the answer (whenever I store a jQuery object, I begin it with a dollar sign by convention, so I always know I'm dealing with a jQuery-wrapped object).
Here's how I would re-write this:
$(document).ready(function(){
$('#homeimg img:first-child').addClass('activeimg');
setInterval(cycleMe, 4000);
});
function cycleMe() {
var $active = $('#homeimg .activeimg');
var $next = $active.next('img');
if(!$next.length) $next = $('#homeimg img:first-child');
$active.fadeOut(1500, function(){
$(this).removeClass('activeimg');
$next.fadeIn().addClass('activeimg');
});
}
Working jsfiddle: http://jsfiddle.net/6MHDn/
You can also do this with simple array manipulation:
$(document).ready(function () {
$('#homeimg img:first-child').addClass('activeimg');
setInterval(cycleMe, 4000);
// get an array of your images
var arrImgs = $('#homeimg img');
function cycleMe() {
var currImg = arrImgs[0];
var nextImg = arrImgs[1];
// You can do this with simple array splicing and pushing
$(nextImg).css('z-index', 10);
$(nextImg).fadeIn(1500);
$(currImg).fadeOut(1500, function () {
$(nextImg).fadeIn(0);
$(this).css('z-index', 5);
// remove the first item from the array
arrImgs.splice(0,1);
// add it to the end of the array
arrImgs.push(currImg);
});
}
});
jsFiddle: http://jsfiddle.net/mori57/4FbVD/
Taking into consideration some of Ethan's comments, I also tried it this way:
http://jsfiddle.net/mori57/4FbVD/2/
$(document).ready(function () {
$('#homeimg img:first-child').addClass('activeimg');
setInterval(cycleMe, 4000);
// get an array of your images
var arrImgs = $('#homeimg img');
function cycleMe() {
var currImg = $(arrImgs[0]);
var nextImg = $(arrImgs[1]);
// You can do this with simple array splicing and pushing
nextImg.fadeIn(1500);
currImg.fadeOut(1500, function () {
currImg.removeClass('activeimg');
nextImg.fadeIn(0).addClass('activeimg');
// remove the first item from the array
arrImgs.splice(0,1);
// add it to the end of the array
arrImgs.push(currImg);
});
}
});
In my previous attempt, I was having to requery the DOM both for css change and fadeIn ... inefficient. Cache the jQuery object, /then/ do the manipulation, and sans-z-index as in Ethan's approach. I'd still rather not have to requery the DOM at all for each element inside an infinite loop. If I find a way around that, I'll post it as well.
Related
I'm using a simple jQuery function to create a small image slider:
function gridhover() {
$(".grid-item .slide-image").each(function(index) {
$(this).delay(400*index).fadeIn(300);
});
}
$( ".grid-item" ).hover(function() {
gridhover();
});
If the function plays once, it stops. Is there a way to loop the function? Check out my CodePen!
The idea here is that since you fadeIn something you must also fade it out and repeat the same process again and again
function gridhover() {
$(".grid-item .slide-image").each(function(index) {
$(this).delay(2000*index).fadeIn(300);
});
$(".grid-item .slide-image").each(function(index) {
$(this).delay(2000*index).fadeOut(300);
});
}
try this but with better timming
Based on this example I prepared this jsFiddle for you.
<div id="cycler">
<img class="active" src="image1.jpg" alt="My image" />
<img src="image2.jpg" alt="My image" />
...
</div>
What he does in his example is he picks the .active element and looks for it's next sibling to know which one to show next. If it does not exist, it means the current active is the last one, so he takes the first one again. Simple.
I took his function and applied it to the .hover(). And also set the myInterval variable as global so you can access it from the .hover() and it's callback function.
var milisecs = 1000;
var myInterval;
$("#cycler").hover(function(){
myInterval = setInterval(function(){cycleImages()}, milisecs);
}, function(){
clearInterval(myInterval);
});
...
Check out the jsFiddle for the whole thing.
Hope it helps.
Note: Changed code so that images and texts are links.
Basically, I have 3 pictures all with the same class, different ID. I have a javascript code which I want to apply to all three pictures, except, the code needs to be SLIGHTLY different depending on the picture. Here is the html:
<div class=column1of4>
<img src="images/actual.jpg" id="first">
<div id="firsttext" class="spanlink"><p>lots of text</p></div>
</div>
<div class=column1of4>
<img src="images/fake.jpg" id="second">
<div id="moretext" class="spanlink"><p>more text</p></div>
</div>
<div class=column1of4>
<img src="images/real.jpg" id="eighth">
<div id="evenmoretext" class="spanlink"><p>even more text</p></div>
</div>
Here is the Javascript for the id="firsttext":
$('#firstextt').hide();
$('#first, #firsttext').hover(function(){
//in
$('#firsttext').show();
},function(){
//out
$('#firsttext').hide();
});
So when a user hovers over #first, #firsttext will appear. Then, I want it so that when a user hovers over #second, #moretext should appear, etc.
I've done programming in Python, I created a sudo code and basically it is this.
text = [#firsttext, #moretext, #evenmoretext]
picture = [#first, #second, #eighth]
for number in range.len(text) //over here, basically find out how many elements are in text
$('text[number]').hide();
$('text[number], picture[number]').hover(function(){
//in
$('text[number]').show();
},function(){
//out
$('text[number]').hide();
});
The syntax is probably way off, but that's just the sudo code. Can anyone help me make the actual Javascript code for it?
try this
$(".column1of4").hover(function(){
$(".spanlink").hide();
$(this).find(".spanlink").show();
});
Why not
$('.spanlink').hide();
$('.column1of4').hover(
function() {
// in
$(this).children('.spanlink').show();
},
function() {
// out
$(this).children('.spanlink').hide();
}
);
It doesn't even need the ids.
You can do it :
$('.column1of4').click(function(){
$(this); // the current object
$(this).children('img'); // img in the current object
});
or a loop :
$('.column1of4').each(function(){
...
});
Dont use Id as $('#id') for multiple events, use a .class or an [attribute] do this.
If you're using jQuery, this is quite easy to accomplish:
$('.column1of4 .spanlink').hide();
$('.column1of4 img').mouseenter(function(e){
e.stopPropagation();
$(this).parent().find('.spanlink').show();
});
$('.column1of4 img').mouseleave(function(e){
e.stopPropagation();
$(this).parent().find('.spanlink').hide();
});
Depending on your markup structure, you could use DOM traversing functions like .filter(), .find(), .next() to get to your selected node.
$(".column1of4").hover(function(){
$(".spanlink").hide();
$(this).find(".spanlink, img").show();
});
So, the way you would do this, given your html would look like:
$('.column1of4').on('mouseenter mouseleave', 'img, .spanlink', function(ev) {
$(ev.delegateTarget).find('.spanlink').toggle(ev.type === 'mouseenter');
}).find('.spanlink').hide();
But building on what you have:
var text = ['#firsttext', '#moretext', '#evenmoretext'];
var picture = ['#first', '#second', '#third'];
This is a traditional loop using a closure (it's better to define the function outside of the loop, but I'm going to leave it there for this):
// You could also do var length = text.length and replace the "3"
for ( var i = 0; i < 3; ++i ) {
// create a closure so that i isn't incremented when the event happens.
(function(i) {
$(text[i]).hide();
$([text[i], picture[i]].join(',')).hover(function() {
$(text[i]).show();
}, function() {
$(text[i]).hide();
});
})(i);
}
And the following is using $.each to iterate over the group.
$.each(text, function(i) {
$(text[i]).hide();
$([text[i], picture[i]].join(', ')).hover(function() {
$(text[i]).show();
}, function() {
$(text[i]).hide();
});
});
Here's a fiddle with all three versions. Just uncomment the one you want to test and give it a go.
I moved the image inside the div and used this code, a working example:
$('.column1of4').each(function(){
$('div', $(this)).each(function(){
$(this).hover(
function(){
//in
$('img', $(this)).show();
},
function(){
//out
$('img', $(this)).hide();
});
});
});
The general idea is 1) use a selector that isn't an ID so I can iterate over several elements without worrying if future elements will be added later 2) locate the div to hide/show based on location relational to $(this) (will only work if you repeat this structure in your markup) 3) move the image tag inside the div (if you don't, then the hover gets a little spazzy because the positioned is changed when the image is shown, therefore affecting whether the cursor is inside the div or not.
EDIT
Updated fiddle for additional requirements (see comments).
I want to append .item element before .content element but it just simply removes .item from previous location and append before .content.
What i want is to use some animation that slowly remove .item element from its original position and appear slowly on its new position.. how can i do this?
$Item = $('.item');
$('.content').before($Item);
Regards.
How about something like this:
$Item = $('.item');
$Item.fadeOut(1000, function() {
$('.content').before($Item);
$Item.fadeIn(1000);
}
The .fadeOut() method fades the element over the specified time (in milliseconds), and on completion calls the function which then moves the element and fades it back in.
Demo: http://jsfiddle.net/9gGAT/5/
You can also use the hide and show -methods of jquery to achieve a sliding effect. I'd also package the transition within it's own method so it can be reused, so you don't have to write the same code multiple times.
var smoothLikeSilk = function(mover, before) {
$item = $(mover);
$content = $(before);
$item.hide('slow', function() {
$content.before($item);
$item.show('slow');
});
}
$(function(){
$('#btnMove').on('click',function(){
smoothLikeSilk('.item', '.content');
});
});
http://jsfiddle.net/9gGAT/6/
Do you mean something like this:
jsFiddl Link
Try this,
$(function() {
$('#btnMove').on('click', function() {
$Item = $('.item').fadeOut('slow', function() {
$('.content').before($Item);
$Item.fadeIn('slow');
})
});
});
Demo
I'm having a bit of a trouble trying to figure this out today, i want to make 5 items inside my DOM (which is listed under the same attribute element, $('.elements')) fade in and out, and after reading up a bit on the API i thought .each() would be a fabulous idea to implement a fade in and fade out showcase gallery.
However, i'm currently using:
$('.elements').each(function() {
$(this).fadeIn(2000).delay(200).fadeOut(2000).show();
})
but everything gets faded in and out at once.
How do i do a sequential effect where everything is chained together and it starts from the first item in the list (a.k.a - $('elements').eq(0)?) down to the last one, and then restarts again?
Do i really need a while loop to do this in javascript/jquery? I was hoping there would be a similar function that i could chain for jQuery to perform to reduce load and filesize.
Also, is there a way to restrict the images from overflowing out from my div?
(function loop() {
$('.elements').each(function() {
var $self = $(this);
$self.parent().queue(function (n) {
$self.fadeIn(2000).delay(200).fadeOut(2000, n);
});
}).parent().promise().done(loop);
}());
demo: http://jsfiddle.net/uWGVN/2/
updated to have it looping without end.
2nd update: a different, probably more readable, approach:
(function fade(idx) {
var $elements = $('.elements');
$elements.eq(idx).fadeIn(2000).delay(200).fadeOut(2000, function () {
fade(idx + 1 < $elements.length ? idx + 1 : 0);
});
}(0));
demo: http://jsfiddle.net/uWGVN/3/
You can add a callback
offical doc :
('#clickme').click(function() {
$('#book').fadeOut('slow', function() {
// Animation complete.
});
});
and call the same function with i++ et $('.elements').eq(i)
http://jsfiddle.net/dFnNL/
For your overflowing , style it with CSS:
div.(class) { position:relative; overflow:hidden; }
Beautiful way :
(function hideNext(jq){
jq.eq(0).hide("slow", function(){
(jq=jq.slice(1)).length && hideNext(jq);
});
})($('a'))
last first :
(function hideNext(jq){
jq.eq(jq.length-1).hide("slow", function(){
(jq=jq.slice(0,length-1)).length && hideNext(jq);
});
})($('a'))
I've been trying to make this for 2 days, I apologize I'm new to Javascript/Jquery and I'm in the learning process.
I'm trying to create a javascript when the page is loaded will have an image fade in and fade out and after the first image fades in and out then a second, third, etc. however many I need.
I know this is a newby question but I'm clearly not sure what to look for at this point. And I have been doing research and learning along the way, I just would like to have it sooner than I may be able to accomplish.
Any help is appreciated.
This is what I came up with which to me looks completely invalid, but seems to work:
<div class="splashbg1" style="display: none;"></div>
<div class="splashbg2" style="display: none;"></div>
<div class="splashbg3" style="display: none;"></div>
<div class="splashbg4" style="display: none;"></div>
<div class="splashbg5" style="display: none;"></div>
<script>
$(document).ready(function() {
$('.splashbg1').fadeIn(1300, function() {
$('.splashbg1').fadeOut(1300, function() {
$('.splashbg2').fadeIn(1300, function() {
$('.splashbg2').fadeOut(1300, function() {
$('.splashbg3').fadeIn(1300, function() {
$('.splashbg3').fadeOut(1300, function() {
$('.splashbg4').fadeIn(1300, function() {
$('.splashbg4').fadeOut(1300, function() {
$('.splashbg5').fadeIn(1300, function() {
});
});
});
});
});
});
});
});
});
});
</script>
example HTML:
<div id="images>
<img src="">
<img src="">
...
</div>
example Javascript:
function switchImage(){
$('#images img:visible').fadeOut(function(){
$(this).next().length ? $(this).next().fadeIn() : $('#images img').eq(0).fadeIn();
});
};
$('#images img').hide().eq(0).show(); // show only the first image
setInterval(switchImage, 2000); // loop through images every 2000 milliseconds
example: http://jsfiddle.net/ampersand/nhp2v/
You can use an array and a variable containing the current image, then fade them in and out. It depends on how your images are stored. If you have one <img> element with an ID of myImg, for example, you could do this:
var images = ['http://someurl.com/someimg.jpg', 'somethingelse.png', 'hello.gif'];
var currentImage = 0;
function next() {
$('#myImg').fadeOut(function() {
$('#myImg').prop('src', images[currentImage]).fadeIn(); // Set the image and fade in
currentImage++; // Get ready for the next image
});
}
next();
If you wanted it to wrap, you could do images[currentImage % images.length]. If there are a bunch of different images, you can do about the same thing, just keep the IDs of the images in images instead.
I wrote a quick function called sequence below. Make a list of the images you'd like to animate using jQuery selectors like this:
var list = [
$('first'),
$('second'),
$('third')
];
Then call the function below with something like this sequence( list, 200, function(){} );
var sequence = function( array, duration, callback ){
var list = array,
length = list.length,
i = 0,
duration = duration,
callback = callback;
function chainFade(){
if( i < length )
array[i].fadeIn( duration )
.fadeOut( duration, function(){
i++;
chainFade();
});
else
typeof callback == 'function' && callback();
}
chainFade();
};
I haven't tested it yet so let me know if you run into any bugs.