I have the following code which loads a JSON feed and creates all the HTML needed for the jCarousel to work. However, I'm not sure how to preload the images. Anyone have any idea's how to do this?
$(".banner ul").jcarousel({
itemLoadCallback:loadTopBanner,
auto: 6,
wrap: 'circular',
scroll: 1,
animation:1000,
itemFallbackDimension:10
});
function loadTopBanner(carousel, state){
$.getJSON("get_top_banner.php", function(data){
carousel.size( data.length );
$.each(data, function(i){
carousel.add(i, makeTag(this.imageURL, this.URL));
});
});
}
function makeTag(img, url){
return "<a href='" + url + "'><img src='" + img + "'></a>";
}
This should do the trick, however, it is untested, and can be further optimised:
function loadTopBanner(carousel, state) {
$.getJSON("get_top_banner.php", function(data) {
carousel.size(data.length);
// make array of elements to which load events can be attached
var imgs = [];
$.each(data, function(i) {
var img = $("<img/>").attr("src", this.imageURL);
imgs.push(img);
});
// init a load counter
var loadCounter = 0;
$.each(imgs, function() {
$(this).one("load", function() {
loadCounter++
// when all have loaded, add to carousel
if (loadCounter == data.length) {
$.each(data, function(i) {
carousel.add(i, makeTag(this.imageURL, this.URL));
});
}
});
if(this.complete) $(this).trigger("load");
});
});
}
May not be a good solution but you can try to load the images somewhere on the page in a hidden div so that they will get cached before you make a ajax call and use them in loadTopBanner method. This way the carousel will not show any delay in loading the images.
If you really want to preload images, you don't need to put them in a hidden div -- you can use the Image object:
var image = new Image();
image.src = "images/foo.jpg";
Related
How can I preload image only when event starts, i.e. .scroll or .click ?
What happens now is, image loads along with website, and I want to prevent this from happening.
Thanks.
Use .one() , .appendTo()
$(element).one("click", function() {
$("<img src=/path/to/img/>").appendTo(/* target element */)
})
$(window).one("scroll", function() {
$("<img src=/path/to/img/>").appendTo(/* target element */)
})
Maybe something like this:
$(function() {
$('img').each(function() {
var self = $(this);
self.attr('data-src', self.attr('src'));
self.removeAttr('src');
});
var loaded = false;
function loadImages() {
if (!loaded) {
$('img').each(function() {
var self = $(this);
self.attr('src', self.data('src'));
});
loaded = true;
}
}
$('button').click(loadImages);
$(window).scroll(function() {
loadImages();
$(this).unbind('scroll');
});
});
if the javascript is executed after images are loaded you can try to change img src to data-src in html file.
You could create an image tag with the source in an data attribute:
<img data-src="your_image.jpg">
And then load it on an event:
$('body').on('click', function(){
$('img[data-src]').each(function(i, img){
$img = $(img);
$img.attr('src', $img.data('src'));
$img.removeAttr('data-src');
});
});
This should work
$(function(){
$(document).one("scroll, click", function(){
loadImages();
})
})
Here loadImage is a function which will load your images on click/scroll event. "one" method will make sure that it only happens only once else you will end up loading images every time someone click or scroll.
var src = 'location/file.jpg';
$(document).on('click', function(){
$('target').append('<img src="' +src+ '" />');
});
If you go to an album (eg. Nature because still working on the others) and click one of the images they all fade out and then the one you clicked appears to just show up on the screen. What is happening is that it is still fading in as the thumbnails are fading out. I tried adding the rest of the code inside a .complete(), but that seems to break it.
$(document).ready(function(){
$('.photos').on('click', function() {
var src = $(this).attr('src').replace('thumb-','');
$('.photos').stop().fadeOut(500);
$('.enlarged').remove();
$('#album').append('<img class="enlarged" src="' + src + '">');
$('.enlarged').hide();
$('.enlarged').stop().fadeIn(500).done(
$('.enlarged').on('click', function () {
$(this).stop().fadeOut({
duration: 500,
done: this.remove()
});
$('.photos').stop().fadeIn(500);
})
);
});
});
You can use promise to catch complete all fade out animation:
$(document).ready(function(){
$('.photos').on('click', function() {
var src = $(this).attr('src').replace('thumb-','');
var photos = $('.photos');
photos.stop().fadeOut(500);
photos.promise().done( function() {
$('.enlarged').remove();
$('#album').append('<img class="enlarged" src="' + src + '">');
$('.enlarged').hide();
$('.enlarged').stop().fadeIn(500).done(
$('.enlarged').on('click', function () {
$(this).stop().fadeOut({
duration: 500,
done: this.remove()
});
$('.photos').stop().fadeIn(500);
})
);
});
});
});
I read many different posts about this matter but I can't solve my problem.
I am trying to create a simple lightbox on dynamically generated content.
$(document).ready(function() {
$("body").on("click", "button", function() {
$("button").removeClass("selected");
$(this).addClass("selected");
var flickrAPI = "http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
var animal = $(this).text();
var flickrOptions = {
tags : animal,
format: "json"
};
var displayPhotos = function(data) {
var photoHTML = "<ul>";
$.each(data.items, function(i, photo) {
photoHTML += '<li class="grid-25 tablet-grid-50">';
photoHTML += '<a href="' + photo.link + '" class="image">';
photoHTML += '<img src="' + photo.media.m + '" ></a></li>';
});
photoHTML += '</ul>';
$('#photos').html(photoHTML);
}
$.getJSON(flickrAPI, flickrOptions, displayPhotos);
var $overlay = $('<div id="overlay"></div>');
var $image = $("<img>");
var $caption = $("<p></p>");
//An image to overlay
$overlay.append($image);
//A caption to overlay
$overlay.append($caption);
//Add overlay
$("body").append($overlay);
//Capture the click event on a link to an image
$("#photos a").click(function(event){
event.preventDefault();
var imageLocation = $(this).attr("href");
//Update overlay with the image linked in the link
$image.attr("src", imageLocation);
//Show the overlay.
$overlay.show();
//Get child's alt attribute and set caption
var captionText = $(this).children("img").attr("alt");
$caption.text(captionText);
});
//When overlay is clicked
$overlay.click(function(){
//Hide the overlay
$overlay.hide();
});
});
});
Here is my complete code on jsfiddle
The click event after the AJAX call doesn't fire up.
How can I solve this?
what it's happening its that you are adding the event before the DOM exists, what you should do its wait for the response to actually render all the event and the interface or replace this:
$("#photos a").click(function(event){
});
for
$(document).on("click","#photos a",function(){
});
that way the event its gonna exist always... Its my guess... I'm not sure if $("#photos a") actually get the element you want to attach the event, but you got the idea of how you can add event to DOM elements that still dont exist on the DOM.
How can I make the my infoWindows have tabbed content? I tried things like:
google.maps.event.addListener(this, "domready", function(){ $("#info").tabs() });
*also tried to use infoWidnwow, infowindow, and iw instead of this keyword
and
.ready(function(){ $("#info").tabs();});
and
.bind('domready', function(){ $("#info").tabs(); });
None of these worked.
Code for creating markers and infowindows:
$('#map').gmap(mapOptions).bind('init', function(){
$.post('getmarkers.php', function(json){
var theMarkers = json;
$.each(theMarkers, function(i, element) {
$.each(element, function(object, attributes){
$('#map').gmap('addMarker', {
'position': new google.maps.LatLng(parseFloat(attributes.Lat), parseFloat(attributes.Lng)),
'bounds':true } ).click(function(){
$('#map').gmap('openInfoWindow', { 'content':'<div id="info"><ul><li><a href="#tab1">Tab1</li><li><a href="#tab2">Tab2</li></ul><div id="tab1"><h1>'+attributes.productName+'</h1></div><div id="tab2"><h2 style="color: grey"><h1>'+attributes.productPrice+'</h1></div></div>' }, this);
});
});
});
});
});
Somehow I need to tell this part:
$('#map').gmap('openInfoWindow', { 'content':'<div id="info"><ul><li><a href="#tab1">Tab1</li><li><a href="#tab2">Tab2</li></ul><div id="tab1"><h1>'+attributes.productName+'</h1></div><div id="tab2"><h2 style="color: grey"><h1>'+attributes.productPrice+'</h1></div></div>' }, this);
To tab the content that I pass to openInfoWindow.
There is a free jquery plugin that takes care of multiple tabs, positioning of each and styling i just found that has an intuitive interface for customization. Here is a demo
https://github.com/googlemaps/js-info-bubble/blob/gh-pages/examples/example.html
Remove the first three snippets you posted and use this:
$('#map').gmap(mapOptions).bind('init', function() {
$.post('getmarkers.php', function(json) {
var theMarkers = json;
$.each(theMarkers, function(i, element) {
$.each(element, function(object, attributes) {
$('#map').gmap('addMarker', {
'position': new google.maps.LatLng(parseFloat(attributes.Lat), parseFloat(attributes.Lng)),
'bounds': true
}).click(function() {
var ts = $.now();
$('#map').gmap('openInfoWindow', {
"<div id='" + ts + "info'>... your tab content ..."
}, this);
$('#' + ts + 'info').tabs();
});
});
});
});
});
I created a unique string and used it to give the div a unique id, then used that to make the tabs.
Is there any way to combine all of this to reduce the amount of javascript?
$(document).ready(function() {
$(".individualImagebox img").bind("click", function()
{
var src = $(this).attr("src");
if (src.search(/Red\.jpg$/) >= 0) return;
// Removes the red overlay from the images folder
$('.individualImagebox img').attr( "src", function () {
var thisSRC = $(this).attr( "src");
return thisSRC.replace(/Red\.jpg$/, ".jpg");
});
// Adds the red overlay from the images folder
$(this).attr( "src", src.replace(/\.jpg$/, "Red.jpg") );
});
});
function ShowHide(index) {
var itemSelector = ".name:eq(" + index + ")";
$(".name .bio").fadeOut();
$(".name").not(itemSelector).fadeOut();
$(itemSelector).animate({"height": "show"}, { duration: 500 });
$(itemSelector + " .bio").animate({"height": "show"}, { duration: 500 });
}
$(function() { // $(function(){}) is a shortcut of $(document).ready(function(){})
var $activeImg; // Maintain a reference to the last activated img
$(".individualImagebox img").click(function(){
if (!!$activeImg) {
$activeImg.attr("src", function(i, src){
return src.replace(/(.+)Red\.jpg$/, "$1.jpg");
});
}
$activeImg = $(this).attr("src", function(i, src){ // replace attribute and updates active img reference
return src.replace(/(.+)\.jpg$/, "$1Red.jpg");
});
});
});
I don’t know exactly what you are trying to do but if possible, you should toggling a class instead of modifying the src attribute.
Combining methods won't save you space. Take a look at
http://developer.yahoo.com/yui/compressor/