I use the function below to show a list of items. I want to change the function so that I can display the navigation when the pseudo recussion is finished. Is there a way to dtect when it is finished?
function fadeItem() {
$('ul li:hidden:first').fadeIn(fadeItem);
}
(update: added this first part) Loads all embed images then recursively fades everything in every half second, then does an alert (replace with the concept you commented back on)
var selector = "ul li:hidden:first";
function fadeIn($item) {
$item.fadeIn(500,function() {
var n = $(selector);
if(n.length > 0) {
fadeIn($(selector));
} else {
// add a div
alert("added a div");
}
})
}
$(document).ready(function() {
// load images first
var imgs = []; // cached
$("ul li img").each(function() {
// create a separate img tag because img is not active due do [assumed css] display:none;
var cacheImage = document.createElement('img');
cacheImage.src = $(this).attr("src");
imgs.push(cacheImage);
});
// this is a quick method, you can change window to the image nodes to optimize better
$(window).load(function() {
fadeIn($(selector));
});
});
Source: http://jsfiddle.net/MattLo/ukLaG/1/ (using a very large image to test)
See the documentation. You can pass a callback function:
function fadeItem() {
$('ul li:hidden:first').fadeIn(fadeItem, function() {
// do something
});
}
Related
Is there a way to use jQuery selectors in modular way:
var logo = $('.logo', function() {
function show () {
console.log('logo has appeared');
$(this).addClass('logo-animated');
};
function hide() {
console.log('logo has been removed');
};
});
I want to be able to assign selector to variable and have some functions within it that I could be able access from outer it's scope.
NOTICE, that is pseudo code, I just drew you a picture of how I see it.
var selector = $('.someclass',
# here goes functions that I could access from outside;
);
UPDATE
var parallax = function() {
var images = ["http://localhost:8000/static/assets/images/hero-image-welcome.jpeg"];
var selector = $('.parallax-module');
var reload = function() {
console.log('reload')
};
$(selector).each(function(index) {
var image = {};
image.element = $(this);
image.height = image.element.height();
images.push(image);
$(this).css('background-image', 'url(' + images[index] + ')');
});
return {
images: images,
reload: reload()
}
}();
parallax.reload;
console.log(parallax.images[0])
// This goes without error, but isn't right;
var sParallax = $('.parallax-module');
sParallax.addClass('someClass');
// This would cause error;
parallax.addClass('someClass');
In this case I can use parallax public properties and methods, but I can't use selector (as I did in the beginning) without creating a new link to it. I know I can use public properties to access selector, but it's not the way I looking for.
You can just set the variable with your desired selector and then just add functions to that variable
var logo = $('.logo');
logo.show = function () {
console.log('logo has appeared');
$(this).addClass('logo-animated');
}
logo.hide = function () {
console.log('logo has been removed');
}
logo.show();
logo.hide();
JSFIDDLE
You can access through this:
logo.prevObject[0].show()//or hide()
I think I found the way, but it does not look right to me, it is working thought:
var parallax = function() {
var images = ["http://localhost:8000/static/assets/images/hero-image-welcome.jpeg"];
var selector = $('.parallax-module');
var reload = function() {
console.log('reload')
};
$(selector).each(function(index) {
var image = {};
image.element = $(this);
image.height = image.element.height();
images.push(image);
$(this).css('background-image', 'url(' + images[index] + ')');
});
return {
images: images,
reload: reload()
}
}().selector;
With selector reference in the end it is now valid to use parallax variable as simple link to DOM element, as well as to access functions that within it.
I am trying to write a script, so that when someone hovers over an image, that same images changes to a different one, ie. I hover over up.png, and it changes to up_highlighted.png, when the mouse goes off the image it should change back.
However I can't seem to get it working despite all my attempts, here is the relevant code of what I have tried so far:
print "<img src=\"/images/up.png\" class=\"thumbsbtn1\" style=\"position:absolute;top:60px;left:1px;width:28px;\" onhover=\"hover_up()\" onclick=\"increase_rating()\">";
function hover_up(){
$(document).ready(function() {
var oldSrc = $('.thumbsbtn1').attr('src');
$('.thumbsbtn1').hover(function() {
//on hover of your element
$('.thumbsbtn1').attr('src','/images/up_hover.png');
}, function() {
//when the cursor leaves your element
$('.thumbsbtn1').attr('src', oldSrc);
});
});
}
PS. I do not wish to use sprites.
Old School: http://jsfiddle.net/PAGUp/
var elem = document.getElementById('targetImg');
var oldSrc;
elem.onmouseover = function() {
oldSrc = elem.src;
elem.src = 'http://www.eclipse-developers.com/images/up_hover.png';
}
elem.onmouseout = function() {
if(typeof oldSrc !== 'undefined') {
elem.src = oldSrc;
}
}
I'm sure the jquery is more pithy. Essentially you need a variable to hold the 'old' src URL, and mouseover and mouseout handlers to set the new URL and back it out.
You don't have to wrap $(document).ready inside hover_up function. Note that I have removed onhover from HTML
Try
print "<img src=\"/images/up.png\" class=\"thumbsbtn1\" style=\"position:absolute;top:60px;left:1px;width:28px;\" onclick=\"increase_rating()\">";
$(document).ready(function() {
var oldSrc;
$(document).on('hover', '.thumbsbtn1', function () {
oldSrc = $('.thumbsbtn1').attr('src');
$('.thumbsbtn1').attr('src','/images/up_hover.png');
}, function () {
$('.thumbsbtn1').attr('src', oldSrc);
});
});
try this
print "<img src=\"/images/up.png\" class=\"thumbsbtn1\" style=\"position:absolute;top:60px;left:1px;width:28px;\" onhover=\"hover_up(this)\" onclick=\"increase_rating()\" onmouseout=\"hover_out(this)\">";
var oldSrc;
function hover_up(e){
oldSrc = $('.thumbsbtn1').attr('src');
$('.thumbsbtn1').attr('src','/images/up_hover.png');
}
function hover_out(e){
$('.thumbsbtn1').attr('src',oldSrc);
}
I do what something like:
$('div > img').onAll('load', function() { alert('Loaded!') })
Which would alert "Loaded!" only once
I don't want this:
$('div > img').on('load', function() { alert('Loaded!'); });
because this would call the event after every single image has been loaded
Is there any ready function in jQuery that calls an event on a set of matches? Or do I have to write a custom function for it?
Create your own method
$.fn.onAll = function(ev, callback) {
var xhr = [];
this.each(function() {
var def = new $.Deferred();
var ele = document.createElement(this.tagName.toLowerCase());
ele['on'+ev] = function() {
def.resolve();
}
ele.src = this.src;
xhr.push(def);
});
$.when.apply($, xhr).then(callback);
return this;
}
to be used as
$('div > img').onAll('load', function() { alert('Loaded!'); });
FIDDLE
Try this
var $images = $("div > img")
, imageCount = $images.length
, counter = 0;
// one instead of on, because it need only fire once per image
$images.one("load",function(){
// increment counter everytime an image finishes loading
counter++;
if (counter == imageCount) {
// do stuff when all have loaded
alert('Loaded!');
}
}).each(function () {
if (this.complete) {
// manually trigger load event in
// event of a cache pull
$(this).trigger("load");
}
});
try something like this
$('body').on('load','div > img',function() { alert('Loaded!') });
Happy Coding :)
I'm working on a banner for a website and I need it to loop through the images. My problem is that it plays through the images once and then stops. I've tried everything that I can think of with no luck. I'm sure this is simpler than I'm making it, but some help would be greatly appreciated. The latest version is below.
$(document).ready(function(){
// Variables required by script
var currentimage;
// Load Gallery XML file
$.ajax({
url: 'banner.xml',
type: 'GET',
dataType: 'xml',
error: function(){
alert('Error loading XML document');
},
success: function(xmlData){
// do something with xml
setupImages(xmlData);
}
});
// Display images
function setupImages(xmlData) {
// read xml and use it to populate page
//get first image
currentimage = $(xmlData).find("image:first");
// Fade in image after countdown
var t = setTimeout(function(){showNewImage()}, 1000);
}
// Display the image, caption, rating and label
function showNewImage() {
var image = $(currentimage).find("path").text();
var caption = $(currentimage).find("caption").text();
$("#imagelabel").removeClass("active");
// Fade out current image and fade in new image
$("#bannerimgholder").animate({opacity:0},500,
function(){
$(this).css({"backgroundImage":"url("+image+")"}).animate({opacity:1},1000,
function(){
$("#imagelabel").addClass("active");
});
});
// Add caption
$("#imagelabel").text(caption);
var to = setTimeout(function(){getNextImage()}, 5000);
}
function getNextImage(){
var tmp = $(currentimage).next();
if ($(tmp).find("path").text()=="") {
currentimage = $(xmlData).find("image:first");
} else {
currentimage = tmp;
}
showNewImage();
}
});
Your code is using next(), which will return nothing once you reach the last image.
You need to use a different test to close the loop, for example:
tmp.length==0
Note that tmp is already a jQuery object, so you don't need to wrap it in $().
This page offers an example of nextOrFirst() function that does what you want.
Here is a solution that I came up with.
First I added an element to the end of my xml file with just a 'path' attribute of "last".
Next, I add the following variable to save the path name of the first element:
var imagepathtext;
Then, in the setupImages(xmlData) function I added the following:
imagepathtext = $(currentimage).find("path").text();
Lastly, I changed the getNextImage() function from
function getNextImage(){
var tmp = $(currentimage).next();
if ($(tmp).find("path").text()=="") {
currentimage = $(xmlData).find("image:first");
} else {
currentimage = tmp;
}
showNewImage();
}
to
function getNextImage(){
var tmp = $(currentimage).next();
if ($(tmp).find("path").text()=="last") {
while ($(tmp).find("path").text()!=firstimagepath)
{
var tmp1 = $(tmp).prev();
tmp = tmp1;
}
currentimage = tmp;
} else {
currentimage = tmp;
}
showNewImage();
}
And just like magic it loops correctly now!
I've got own gallery code like:
// Gallery
$(function() {
var images = $('#gallery ul li img');
var next = 0;
var timer;
var delay = 5000;
images.click(function() {
if($(this).hasClass('current')) return false; // Prevent from re-showing
$('#gallery ul li.current').toggleClass('current'); // Change current highlighted photo
$(this).parent().toggleClass('current'); // to $(this)
$('#gallery img#show-window').attr('src', $(this).data('src')); // Change viewed photo
$('#gallery .panel h2').text($(this).attr('title')); // Set title
$('#gallery .panel p').text($(this).attr('alt')); // Set description
next = $.inArray(this, images) + 1;
clearTimeout(timer);
timer = setTimeout(function() {
images[next % images.length].click();
}, delay);
});
images[0].click();
});
And if I run it on Chromium (Arch Linux 15.0.874.121 (Build 0 Linux)) it is't showing image until I click on any of the gallery previews and even then it isn't changing to next picture after 5s. It works on Firefox 8.0 and Opera 11.52.
Have you tried the "doTimeout" function?
$.doTimeout( 'someid', 1000, function( state ){
.alert( state ); // alert true in 1 second
.}, true);
Maybe it's just me, but it seems a little redundant to do this with setTimeout programatically clicking the next image when you can do this with setInterval.
function nextImage()
{
// insert image selection logic here
}
$(function(){
var imgDaemon = setInterval(nextImage(), 5000);
});