I tried this code for a line preloader but it didn't work and i don't know where is the problem.
var $preload = $("<div class='preloader'><div class='percent'></div><div class='line-parent'><div class='line'></div></div></div>");
$("body").prepend($preload);
var $imgs = $("img");
var imgsLoaded = 0;
var ratio = 0;
$imgs.each(function(){
$this = $(this);
$this.load(function(){
imgsLoaded++;
ratio = imgsLoaded / $imgs.length;
$(".percent").html(ratio / 0.01 + "%");
$(".line").animate({
width : ratio / 0.01 + "%"
});
}, function(){
if(ratio === 1){
$(".preloader").fadeOut();
}
});
});
I belive you want to show 100% wenn all images are loaded and do some action. First load event will not work if is atteched after image is already loaded.
I sugest to check for each img comlete and naturalWidth property every 100ms (with setInterval).
Loader = (function() {
var list, img_length, loaded, interval;
function _check_one(i) { o = list[i]; if (o.complete == true && o.naturalWidth > 0) { loaded++; delete list[i]; } };
function _procent(l, a) { console.log((100*loaded/img_length) + '%'); }
function _check_list() { for(var i in list) {_check_one(i)};_procent();_kill(); };
function _kill() { if(img_length <= loaded) clearInterval(interval); }
function _start() { loaded = 0; list = $('img'); img_length = list.length;
if(img_length != loaded) interval = setInterval(_check_list, 100); }
return { start: _start }
})();
Now at end of the body or in $(document).ready(..) you need to call Loader.start();
Or put all images source (src) in data-src attribite, attach load events and copy data-scr to src attribite. In body all relevant images looks like this:
<img data-src="some url">...
In Script Tag:
$('img').on('load', function() {
// Your action.
}).each(function() { var img = $(this); img.attr('src', img.attr('data-src')); });
Related
I am trying to make a responsive image gallery in vanilla JS, I have a function and I am passing the image source as its parameter, and every time I am only changing the source on the click of next or previous button. Here is the function:
this.open = function (src) {
if (!src) {
return false;
}
for (count = 0; count <= imgSrc.length; count++) {
if (imgSrc[count] == src)
break;
var tempSrc = imgSrc[count];
}
imgRatio = false; // clear old image ratio for proper resize-values
var img = document.createElement('img');
img.setAttribute('src', src);
// hide overflow by default / if set
if (!this.opt || !isset(this.opt.hideOverflow) || this.opt.hideOverflow) {
body.setAttribute('style', 'overflow: hidden');
}
this.box.setAttribute('style', 'padding-top: 0');
this.wrapper.innerHTML = '';
this.wrapper.appendChild(img);
// console.log(this.wrapper.innerHTML);
addClass(this.box, 'jslghtbx-active');
// already show wrapper due to bug where dimensions are not
// correct in IE8
if (isIE8) {
addClass(that.wrapper, 'jslghtbx-active');
}
imgText.innerHTML = Details.static_data.gallery[count][3];
var checkClassInt = setInterval(function () {
if (hasClass(that.box, 'jslghtbx-active') && img.complete) {
// wait few ms to get correct image-dimensions
setTimeout(function () {
that.resize();
// add active-class for all other browsers
setTimeout(function () {
addClass(that.wrapper, 'jslghtbx-active');
}, 10);
clearInterval(checkClassInt);
}, 40);
}
}, 10); };
Is there any way so that I can attach animate kind of attribute to the image to have a sliding kind of animation. Please suggest your valuable feedback. [ NOTE: I am using this script https://github.com/felixhagspiel/jsOnlyLightbox ]
Hey there i got this fiddle :
http://jsfiddle.net/5H5Xq/42/
containing this jquery:
function anim(selector) {
$(".images img", selector).first().appendTo($('.images', selector)).fadeOut(2000);
$(".images img", selector).first().fadeIn(2000);
}
// Untuk delay gambarnya
var i = 0, max = 3;
myFunction = function(event){
$(".subbox1").each(function() {anim(this)});
i += 1;
if(i >= max) { i = 0; }
}
var interval = setInterval(myFunction, 5000);
$(".slider").hover(function() {
clearInterval(interval);
var img = $('<img>');
img.attr('src', $(this).attr('data-url'));
$('#newImage').html(img);
$('.images').hide();
return false;
i += 1;
$(".subbox1").each(function() {anim(this)});
});
$(".slider").mouseout(
function (){
$('.images').show();
// $('#newImage').hide();
interval = setInterval(myFunction, 5000);
}
);
It just means:
Every 5 seconds => automatic image-change.
When i hover throw a link => image-change + automatic image change disabled.
What i wanted to add to the automatic image-change:
Depending on the current picture, the -item gets a new background-color..is this possible?
greetings
Sure you can. Just change the background-color css attribute of the element depending on your criteria.
if (*your criteria here*) {
element.css("background-color", "#ff0000");
}
I have a set of images that are frames in an animation like: frame-1.jpg, frame-2.jpg and I have about 400 images.
What I want to do is preload these 400 images before the animation starts.
Usually when preloading images I use the following:
var images = [
'img/nav-one-selected.png',
'img/nav-two-selected.png',
'img/nav-three-selected.png',
'img/nav-four-selected.png'
];
$(images).each(function() {
var image = $('<img />').attr('src', this);
});
But in this instance, listing the images in the var isn't feasible, and I also wish to fire off the start animation once the images have all been loaded.
So far I have the following:
$spinner_currentFrame = 1;
$numFrames = 400;
function preloadImages() {
$($images).each(function() {
var image = $('<img />').attr('src', this);
});
startAnimation();
}
function startAnimation() {
$spinner_loadingAnim = setInterval(function () {
UpdateSpinner();
}, 140);
}
function UpdateSpinner() {
$spinner_currentFrame = $spinner_currentFrame + 1;
if($spinner_currentFrame > $numFrames) {
$spinner_currentFrame = 1;
}
console.log($spinner_currentFrame);
$('#spinner').css("background-image", "url(frame-" + $spinner_currentFrame + ".jpg)");
}
$(document).ready(function() {
preloadImages();
});
So the plan is that I preload images that are from 1 to 400 and then once that's completed then start the animation. How would I build the $images var though?
I've thought about something like:
$images = [];
$frame = 1;
$numFrames = 400;
$($frame).each(function() {
$frame = $frame + 1;
if($frame <= $numFrames) {
$images =+ 'frame-' + $frame + '.jpg';
}
});
But I'm not sure how a) efficient this is and b) how to do the callback once all images have loaded successfully.
You should use a standard javascript for loop instead of the jQuery's foreach. Foreach is wonderful for looping over an array or set of objects, but not in this case. Here is an example, please note that you have to bind the onload event handler before you set the Image object's src property.
UPDATE: added more functions to complete the entire example.
var loaded_images = 0;
var frames = 400;
var images = [];
function preloadImages() {
for (i=0; i < frames; i++) {
images[i] = new Image();
images[i].onload = function() {
loaded_images += 1;
checkLoadingFinished();
}
images[i].src = 'frame-' + i + '.jpg';
}
}
function checkLoadingFinished() {
if (loaded_images >= frames) {
startAnimation();
}
}
function startAnimation() {
var frameNumber = 0;
var timer = setInterval(function() {
$('#img-dom-element').attr('src', images[frameNumber]);
if (frameNumber > frames) {
frameNumber = 0;
else
frameNumber++;
}, (1000/30)); // (1000/30) = 30 frames per second
}
$(document).ready(function() {
preloadImages();
});
I dont know if it fits to your special case but I use
http://thinkpixellab.com/pxloader/
to preload images. You can add the paths and get one callback if all images are loaded. Afterwards you can start animation.
I have built a site for a client and when the user clicks on a navigation link, the content of the linked page is dynamically loaded and transitioned in with JQuery, instead of loading the new page.
The problem I am having is that because it is not loading a new page, $(document).ready doesn't fire again and any JS on the individual pages gets broken. For example, if you visit http://www.woodlandexotica.com/species.php the page works correctly, but if you try to navigate to the page from http://www.woodlandexotica.com/index_dev.php, the JS won't work.
I'm not an expert in JS and I really appreciate any and all help!
The problem is that when you call ".load()", you're using a URL string and a selector suffix to extract from the loaded content. When you use ".load()" that way, jQuery strips out all the scripts and does not run them. There's nothing you can do about that other than to implement your own version of ".load()" yourself, or (better) have the other pages you load not be complete HTML pages. If you use ".load()" without the selector suffix on the URL string, then jQuery does run the scripts.
See jQuery bug 6307 for more. The bug will not be fixed but hopefully the documentation will be improved.
The way you organized this code is wrong
Keep only binding's inside document.ready and move the logic outside to a functions..which can be accessed by any page.
$(document).ready(function() {
//////////////////////////////////////////////////
//////////////////////////////////////////////////
// CONTENT BG SLIDESHOW
//////////////////////////////////////////////////
var photos = ["images/bg01.jpg", "images/bg02.jpg", "images/bg03.jpg"];
var slideshowSpeed = 8000;
var interval;
var activeContainer = 1;
var currentImg = 0;
var navigate = function(direction) {
currentImg++;
if(currentImg == photos.length + 1) {
currentImg = 1;
}
// Check which container we need to use
var currentContainer = activeContainer;
if(activeContainer == 1) {
activeContainer = 2;
} else {
activeContainer = 1;
}
showImage(photos[currentImg - 1], currentContainer, activeContainer);
};
var currentZindex = 1;
var showImage = function(photoObject, currentContainer, activeContainer) {
// Make sure the new container is always on the background
currentZindex--;
// Set the background image of the new active container
$("#bgimg" + activeContainer).css({
"background-image" : "url(" + photoObject + ")",
"display" : "block",
"z-index" : currentZindex
});
// Fade out the current container
// and display the header text when animation is complete
$("#bgimg" + currentContainer).fadeOut(function() {
setTimeout(function() {
animating = false;
}, 500);
});
$("#bgimg" + currentContainer).css({
"z-index" : "1"
});
currentZindex = 1;
};
function photoLoaded() {
if(!--numPhotosLeft) {
navigate("next");
interval = setInterval(function() {
navigate("next");
}, slideshowSpeed);
$('#bg_load').fadeOut('fast');
$('#page_bg').animate({opacity: 1, marginLeft: '-=860'}, 500);
}
}
var photos = ["images/bg01.jpg", "images/bg02.jpg", "images/bg03.jpg"];
var numPhotosLeft = photos.length;
for(var i = 0; i < photos.length; ++i) {
var img = new Image();
img.onload = photoLoaded;
img.src = photos[i];
}
//////////////////////////////////////////////////
//////////////////////////////////////////////////
//////////////////////////////////////////////////
//////////////////////////////////////////////////
// PAGE TRANSITION
//////////////////////////////////////////////////
// ADJUST FOR DEEPLINKING
var hash = window.location.hash.substr(1);
var href = $('a.link').each(function(){
var href = $(this).attr('href');
if(hash==href.substr(0,href.length-4)){
var toLoad = hash+'.php #page_bg';
$('#page_bg').load(toLoad)
}
});
$('a.link').click(function() {
var toLoad = $(this).attr('href')+' #page_bg';
$('#page_bg').animate({opacity: 0.25, marginLeft: '-=875'}, 500, loadContent);
window.location.hash = $(this).attr('href').substr(0,$(this).attr('href').length-4); //MODIFY FOR DEEP LINKING
function loadContent() {
$('#page_wrap').prepend('<span id="load">LOADING...</span>');
$('#load').fadeIn('fast');
$('#page_bg').css('marginLeft', 860);
$('#page_bg').css('backgroundImage', 'none');
$('#page_bg').load(toLoad,'',hideLoader);
}
function hideLoader() {
$('#load').fadeOut('fast', showNewContent);
}
function showNewContent() {
$('#page_bg').animate({opacity: 1, marginLeft: '-=860'}, 500);
}
return false;
});
//set initial position and opacity
$('#page_bg').css('marginLeft', 860);
$('#page_bg').css('opacity', 0.25);
$('#page_wrap').prepend('<span id="bg_load">LOADING...</span>');
$('#bg_load').fadeIn('fast');
//////////////////////////////////////////////////
//////////////////////////////////////////////////
});
I have images on my page.
I want to show a loading bar on my page, showing the progress of the downloaded images.
How can I do this?
I have written a jQuery plugin to register callbacks for images loading.
You would use it like so...
var loading = $('<div id="loading" />').appendTo('body');
$('body').waitForImages(function() {
loading.remove();
}, function(loaded, all) {
loading.html(((loaded / all) * 100) + '% loaded');
});
jsFiddle.
var preload = function (images, callback) {
var count = 0;
for (var i = 0, len = images.length; i < len; i++) {
var img = new Image();
img.src = images[i];
img.onload = function () {
var perc = ++count * (100 / len) | 0;
if (callback) callback.call(this, perc, perc === 100);
};
}
};
The usage is pretty simple:
preload(['http://lorempixel.com/800/600'], function(perc, done) {
console.log( perc);
if(done) console.log( 'Done!' );
// `this` refers to each loaded image.
});