jQuery Image Load Loop - Wrap HTML & Check Size? - javascript

I have a folder with images in it and I'm loading those images using jQuery. This code:
$(function () {
var i=1;
for (i=1;i<=50;i++){
var curImg = "blog/wp-content/uploads/" + i + ".jpg";
var img = new Image();
$(img).load(function () {
$(this).hide();
$('#loader').removeClass('loading')
.append(this);
$(this).fadeIn();
}).error(function () {})
.attr('src', ''+curImg+'');
}
});
works fine for smoothly loading 50 images from this folder. I am trying to do 2 things:
I want to add a link like this: <a href='blog/wp-content/uploads/" + i + ".jpg' class='picLink'> to each individual image. I have tried using .wrap in my .load function here, but that isn't working for me. This just creates a nest of links (e.g. <a><a></a></a>).
Currently this finds the first 50 photo's, starting at number 1, and loads them. But if more photo's are added they won't be found, and the oldest will always be first. I would like it to find all photo's in the folder and print the newest (highest number) first. It can be presumed that there won't be more than, say, 4000 photo's. So would it be possible to do this loop in reverse, start at 4000, check if that photo exists and work down and just load photo's that exist in the folder?
Thanks in advance for any help, I hope the question is clear enough!

For 1. you can do something like this fiddle
$(function () {
var i=1;
for (i=1;i<=50;i++){
var curImg = "blog/wp-content/uploads/" + i + ".jpg";
var img = new Image();
$(img).load(function () {
$(this).hide();
$('#loader').removeClass('loading')
.append($('').append(this));
$(this).fadeIn();
}).error(function () {})
.attr('src', ''+curImg+'');
}
});
Also they may not be in order as some images may take longer to load than others.
For 2. I think you should get the image count server-side and inject it into the for loop something like,
for (i=<?php echo $count; ?>; i > <?php echo ($count>50?$count-50:0); ?>; i--){
assuming you're using php, where $count represents the amount of images in the folder.

Related

Preloaded images are not beeing used

I am trying to preload images for use in a image gallery. The images are taken threw a php script from a folder outside of the htdocs folder. And when they are loaded the images should be used in a masonry layout.
As far as my knowledge goes the javascript that I am using should be working. However when I am using the page on a gallery for several 100 images it does not work. Some images are loaded others are not.
I also have very little knowledge of javascript in general. So any advice would be helpful.
I tried a lot of things. The imagesloaded from desandro. Several iterations of the script I will share on the bottom. I am at a loss.
Javascript code
<script type="text/javascript">
var images = <?php echo json_encode($images); ?>;
var folder = <?php echo json_encode($folderName); ?>;
var imageArray = [];
function preloadImages() {
for (var i = 0; i < images.length; i++) {
var img[i] = new Image();
img[i].src = "img/jpg/" + folder + "/" + images[i].image_name;;
imageArray.push(img);
}
}
</script>
JSON example (for the images)
{"image_id":"8","image_name":"DSC00058.JPG","image_selected":"1","image_locked":"0"},
{"image_id":"9","image_name":"DSC00053.JPG","image_selected":"1","image_locked":"1"},
HTML
<body class="h-100 bg-light" onload="preloadImages();">
The expected result would be that the masonry only starts building and using the images that are preloaded. Is there a way to use the preloaded images or do I need to doe a specific thing in HTML?
Your preload function is loading the images, but it's not preloading them. The trick is to wait for them all to load before initializing the masonry plugin..
Here's an example using promises.
function preloadImages() {
var promises = [];
for (var i = 0; i < images.length; i++) {
promises.push(new Promise(done => {
var img[i] = new Image();
img.onload = ()=>done();
img[i].src = "img/jpg/" + folder + "/" + images[i].image_name;;
imageArray.push(img);
}));
}
Promise.all(promises).then(()=>{
// initialize masonry here...
});
}

Get number of items by class within parent in JS

I have built an image gallery where there is one main image and up to 5 thumbnails under it. and can use left and right buttons to cycle through the thumbnails and replace the main image like so:
$(".gallery-btn-left").unbind("click").bind("click", function(){
var image_id = $(".gallery-main-image img").attr('data-id');
image_id--;
if(image_id == 0){image_id = $('.gallery-thumbnail img').length;}
var image_url = $(".gallery-thumbnail img[data-id=" + image_id + "]").attr('src');
$(".gallery-main-image img").attr('src', image_url);
$(".gallery-main-image img").attr('data-id', image_id);
});
$(".gallery-btn-right").unbind("click").bind("click", function(){
var image_id = $(".gallery-main-image img").attr('data-id');
image_id++;
if(image_id > $('.gallery-thumbnail img').length){image_id = 1;}
var image_url = $(".gallery-thumbnail img[data-id=" + image_id + "]").attr('src');
$(".gallery-main-image img").attr('src', image_url);
$(".gallery-main-image img").attr('data-id', image_id);
});
This all works fine, however, if I want to put two galleries on the same page I get an issue where by my JS is getting 10 instead of 5 or however may thumbnails there are (max 5 per gallery) for $('.gallery-thumbnail img').length which is expected.
What I want to know is if there is a way to get the length of the amount of thumbnails in the parent gallery rather than how many thumbnails there are on the page as a whole.
The most common approach for multiple instances is to look up to the container instance and then use find() within that instance.
Also when you look for the same selector multiple times it is best to store a reference to it rather than search the DOM every time you need to access it. It also makes the code a little easier to read
Something like:
$(".gallery-btn-left").unbind("click").bind("click", function() {
var $gallery = $(this).closest('.MAIN-GALLERY-CLASSNAME'),
$mainImg = $gallery.find(".gallery-main-image img"),
$thumbs = $gallery.find('.gallery-thumbnail img'),
image_id = $mainImg.attr('data-id');
image_id--;
if (image_id == 0) {
image_id = $thumbs.length;
}
var image_url = $thumbs.filter("[data-id=" + image_id + "]").attr('src');
$mainImg.attr({'src': image_url, 'data-id',image_id});
});

Execute js after all image loaded not working

(not duplicate, because not find exactly/easy solution)
I'm trying to execute JS after all images completely loaded. My goal is, when all images finish load completely, then removeClass my-loader and addClass visible to main-slider div.
HTML:
<div class='main-slider my-loader'>
<img src="https://unsplash.it/200/300/">
<img src="https://unsplash.it/200/300/">
<img src="https://unsplash.it/200/300/">
</div>
Execute below js when all images completely loaded
$(".main-slider").removeClass("my-loader").addClass("visible");
Tried this js :
But not works properly on my site, problem is when i clear browser cache, then it works/execute! when i reload page then next time it's not works/execute! It only works when i clear browser cache.
var img = $('.main-slider img')
var count = 0
img.each(function(){
$(this).load(function(){
count = count + 1
if(count === img.length) {
$('.main-slider').removeClass('my-loader').addClass('visible')
}
});
});
Any simple solution? Thanks in advance.
jQuery provides a way to register a callback for the window load event which will fire when the entire page, including images and iframes, are loaded.
Reference: https://learn.jquery.com/using-jquery-core/document-ready/
Your code should look something like:
$( window ).load(function () {
var img = $('.main-slider img')
var count = 0
img.each(function(){
$(this).load(function(){
count = count + 1
if(count === img.length) {
$('.main-slider').removeClass('my-loader').addClass('visible')
}
});
});
});
Here's how to do this, using Deferreds and native handlers, and calling the onload handler if the image is cached in older browsers etc.
var img = $('.main-slider img');
var defs = img.map(function(){
var def = new Deferred();
this.onload = def.resolve;
this.onerror = def.reject;
if (this.complete) this.onload();
return def.promise();
});
$.when.apply($, defs).then(function() {
$('.main-slider').removeClass('my-loader').addClass('visible')
});

Loading A text along with a picture using AJAX

I have made a photo gallery in my website using the following:
/*Begin Photo Gallery Code*/
var images = ['g1.jpg', 'g2.jpg', 'g3.jpg', 'g4.jpg'];
function loadImage(src) {
$('#pic').fadeOut('slow', function() {
$(this).html('<img src="' + src + '" />').fadeIn('slow');
});
}
function goNext() {
var next = $('#gallery>img.current').next();
if(next.length == 0)
next = $('#gallery>img:first');
$('#gallery>img').removeClass('current');
next.addClass('current');
loadImage(next.attr('src'));
}
$(function() {
for(var i = 0; i < images.length; i++) {
$('#gallery').append('<img src="images/gallery/' + images[i] + '" />');
}
$('#gallery>img').click(function() {
$('#gallery>img').removeClass('current');
loadImage($(this).attr('src'));
$(this).addClass('current');
});
loadImage('images/gallery/' + images[0]);
$('#gallery>img:first').addClass('current');
setInterval(goNext, 4000);
});
It loads one picture at a time from a set of four pictures. Also I have four html files, each of them being relevant to one of the pictures. I want to use JavaScript/JQuery/AJAX to load the relevant html file's content along with the shown picture. Does anyone have an idea how I can do this?
Should I put the ajax files (4 html files) into a JavaScript array or something?
var ajaxPages=['ajax1.html','ajax2.html','ajax3.html','ajax4.html'];
Thanks in advance.
Unless the HTML files supposed to change somehow during their displaying, should either output them via your server-side code in hidden divs with the request (would be the correct way of doing it) or use AJAX to save them in a variable or create hidden divs.
First you need two arrays like this:
var ajaxPages=['ajax1.html','ajax2.html','ajax3.html','ajax4.html'];//File Names
var divPages=['div1','div2','div3','div4'];//Div ids in order
For the AJAX part you should use something like:
var getHtml = function(filename,divid){
$.post('html/'+filename, function(data) {
//The first argument is your file location
//Second one is the callback, data is the string retrieved
$('#'+divid).html(data);
});
}
$.each(ajaxPages,function(index,value){
getHtml(value,divPages[index]);
});
That should do it... Do tell me if you require further explanation.
EDIT:
var ajaxPages=['ajax1.html','ajax2.html','ajax3.html','ajax4.html'];
var divId="yourdivid";
var textArray=new Array();
var currentImg=0;
var getHtml = function(filename){
$.post('html/'+filename, function(data) {
textArray.push(data);//Save data inside the array textArray
});
}
$.each(ajaxPages,function(index,value){
getHtml(value,divPages[index]);
});
Then your goNext() method:
function goNext() {
var next = $('#gallery>img.current').next();
if(next.length == 0){
next = $('#gallery>img:first');
currentImg=0;
}else{
currentImg++;
}
$('#gallery>img').removeClass('current');
next.addClass('current');
loadImage(next.attr('src'));
$('#'+divId).html(textArray[currentImg]);//Adds text to div based on current picture
}
That should be working fine!

Preloading Image Bug in IE6-8

Page in question: http://phwsinc.com/our-work/one-rincon-hill.asp
In IE6-8, when you click the left-most thumbnail in the gallery, the image never loads. If you click the thumbnail a second time, then it will load. I'm using jQuery, and here's my code that's powering the gallery:
$(document).ready(function() {
// PROJECT PHOTO GALLERY
var thumbs = $('.thumbs li a');
var photoWrapper = $('div.photoWrapper');
if (thumbs.length) {
thumbs.click( function(){
photoWrapper.addClass('loading');
var img_src = $(this).attr('href');
// The two lines below are what cause the bug in IE. They make the gallery run much faster in other browsers, though.
var new_img = new Image();
new_img.src = img_src;
var photo = $('#photo');
photo.fadeOut('slow', function() {
photo.attr('src', img_src);
photo.load(function() {
photoWrapper.removeClass('loading');
photo.fadeIn('slow');
});
});
return false;
});
}
});
A coworker told me that he's always had problems with the js Image() object, and advised me to just append an <img /> element inside of a div set to display:none;, but that's a little messy for my tastes--I liked using the Image() object, it kept things nice and clean, no unnecessary added HTML markup.
Any help would be appreciated. It still works without the image preloading, so if all else fails I'll just wrap the preloading in an if !($.browser.msie){ } and call it a day.
I see you've fixed this already, but I wanted to see if I could get the pre-loading to work in IE as well.
try changing this
photo.fadeOut('slow', function() {
photo.attr('src', img_src);
photo.load(function() {
photoWrapper.removeClass('loading');
photo.fadeIn('slow');
});
});
to this
photo.fadeOut('slow', function() {
photo.attr('src', img_src);
if (photo[0].complete){
photoWrapper.removeClass('loading');
photo.fadeIn('slow');
} else {
photo.load(function() {
photoWrapper.removeClass('loading');
photo.fadeIn('slow');
});
}
});

Categories