i have certain links, on mouse over of those links I am changing <div> background image
jQuery I have used is-
function imgchange()
{
$('.smenu li').mouseover( function(){
var src = $(this).find('a').attr('href');
$('.hbg').css('background-image', 'url(' + src + ')');
$(this).find('hbg').attr('title', 'my tootip info');
});
}
It is working fine but the problem is when I running it on server images takes 3-4 sec to be changed on change, but the second time I do mouse over images are getting changed instantly, I think this is because of browser stored images in cache. So I added one javascript to preload images on page onLoad() ivent -
<script language = "JavaScript">
function preloader()
{
heavyImage = new Image();
heavyImage.src = "images/soluinfo1.jpg";
heavyImage.src = "images/soluinfo2.jpg";
heavyImage.src = "images/soluinfo3.jpg";
heavyImage.src = "images/soluinfo4.jpg";
heavyImage.src = "images/soluinfo5.jpg";
heavyImage.src = "images/soluinfo6.jpg";
heavyImage.src = "images/soluinfo7.jpg";
}
</script>
<body onLoad="javascript:preloader()">
but this script has not solved my problem.what should I do?
#Richard's answer (sprites) is probably the best one for what you are after, but the reason your code is not working is that in most browsers, only the last heavyImage.src="" is given enough time to actually register with the browser as an actual request. You're creating only one Image object setting and resetting the .src attribute faster than the browser can request the files (I think modern JavaScript engines take the added step of removing all the intermediate .src statements specifically because of this).
There are a couple of ways to fix this. The easiest is to create multiple Image objects, one for each image. And the easiest way to do that is through something like this:
<script type="text/javascript">
function preloader()
{
function doPreload(strImagePath)
{
var heavyImage = new Image();
heavyImage.src = strImagePath;
}
var arrImages = ["images/soluinfo1.jpg","images/soluinfo2.jpg","images/soluinfo3.jpg","images/soluinfo4.jpg","images/soluinfo5.jpg","images/soluinfo6.jpg","images/soluinfo7.jpg"];
for (var i = 0; i < arrImages.length; i++) {
doPreload(arrImages[i]);
}
}
</script>
By putting the heavyImage variable inside its own function (remember to use the var keyword), you're ensuring that the Image object exists inside its own dedicated scope.
Another way to do this is to attach a "load" event listener to a single heavyImage. Every time the image finishes loading, go fetch the next image. The disadvantage to this method is that your images will be loaded one at a time (bad for navigation images, but great for, say, and image gallery), whereas the first technique will fetch the images in parallel (typicallly four at a time).
You might find it easier to change your approach and use CSS sprites (and another article). Then you would just have one image referenced, and you use CSS to set which part of that image gets shown in which scenario.
This assumes that the images you're using are under your control and you can use an image editor to combine them into one large image.
Related
I have a lot of <img> tags on one HTML page some of whom share the same animated GIF file. The src URL is set dynamically by JavaScript but with my code the same characters are either played all again or following characters are immediately displayed with the last frame.
The idea: This is for an art project. After some text has been entered the characters are displayed in a special font and some transition is done character per character (one after another) which I can only realize by using animated GIFs. The text is split into single characters and <img> tags are created like this:
<!-- delivered HTML at page load -->
<img src="initial/f.png"> <!-- I used to PNG here to outline -->
<img src="initial/o.png"> <!-- the animation is NOT set a first -->
<img src="initial/o.png">
When the animation starts the first <img>'s URL is set to transition/f.gif. Only after it has finished playing (determined by time) the 2nd image is set etc.
<!-- while 2nd animation is running -->
<img src="transition/f.gif"> <!-- already finished, displays last frame -->
<img src="transition/o.gif"> <!-- being animated right now -->
<img src="transition/o.png"> <!-- will be reset to o.gif in next step -->
The problem I can't solve: After o.gif from the example has been played the animation of the next O doesn't work correctly.
I tried defining a class for every character and assigning the image as background-image. Once any occurrence of a character had played any following occurrences of the same letter displayed the last frame (end state) of that GIF immediately when displayed.
I also tried setting the src attribute directly with JavaScript but when the 2nd letter O is set like this the first letter O's animation restarts synchronously. But it shall stay at the last frame.
As the HTML page should also work on the local filesystem I think arguments like o.gif?random=argument for bypassing cache mechanism won't work or won't have any effect (maybe on some computers, testing on my own won't falsify).
You have to create unique urls for the images, so the browser will always reload letters instead of using the cached ones.
You could achieve this for example with a small php, which is outputting the correct gif for a parameter.
<img src="gif_printer.php?letter=o&t=1234567">
The t parameter should be the timestamp when you create the img tag. This gives enough difference to redownload.
In the php set headers to limit/disable caching and output type to gif, and simply pour the contents of the image to stdout.
The timestamp parameter and the cache-control headers should be enough for the browser to redownload evert letter.
If your test environment is not reacting correct, you could try htaccess solution, but for that you have to use a web server (and this could already be enough for the previous solution to work).
That means rewrite any url to images/[a-z].gif into images/[a-z].gif, so simply remove additional noise except the first letter and the extension.
Consider not using GIFs, but image sequences and Javascript. I've thrown together a rough instantiable Javascript object that does just that:
<html>
<head>
<script>
function Animator(target, frames, delay)
{
var _this = this;
// array of frames (image objects)
var f = [];
// a reference to the object where our frames will appear
var t = document.getElementById(target);
// the interval variable. Used to stop and start
var t_loop;
// create a new image element and remember it
var img_el = document.createElement("img");
// current frame
var c_frame = 0;
t.innerHTML = "";
t.appendChild(img_el);
var i, img;
// preload immediately
for(i = 0; i < frames.length; i++)
{
img = new Image();
img.src = frames[i];
f.push(img);
}
this.play = function()
{
t_loop = window.setInterval(_this.frame, delay);
}
this.stop = function()
{
clearInterval(t_loop);
}
this.gotoFrame = function(frame)
{
c_frame = frame;
_this.frame();
}
this.frame = function()
{
img_el.src = f[c_frame].src;
c_frame++;
if(c_frame >= f.length)
{
c_frame = 0;
}
}
}
function loaded()
{
var quip_frames = [
"http://www.abcteach.com/images/abma_thumb.gif",
"http://www.abcteach.com/images/abcu_thumb.gif",
"http://www.abcteach.com/images/zbma_thumb.gif",
"http://www.abcteach.com/images/zbcu_thumb.gif",
"http://www.abcteach.com/images/dnma_thumb.gif",
"http://www.abcteach.com/images/dncu_thumb.gif"
];
var anim1 = new Animator("target1", quip_frames, 100);
var anim2 = new Animator("target2", quip_frames, 100);
var anim3 = new Animator("target3", quip_frames, 100);
anim1.play();
window.setTimeout(anim2.play, 200);
window.setTimeout(anim3.play, 300);
}
</script>
</head>
<body onload="loaded()">
<div id="target1">
</div>
<div id="target2">
</div>
<div id="target3">
</div>
</body>
</html>
thanks to ABCTeach for the images
The object loads the images in a loop, stores them in an array, then through simple use of setInterval() swaps out frames at a desired rate. When the page loads it makes three of these objects, each pointing to a different DIV, but each with the same frames. It then tells each to play with a different delay (the first one immediately, the second after 200ms, the third after 300ms). In your case you'd make one array for every letter you'd use:
var A = [*array of URLs to images of the letter A*];
var B = [*array of URLs to images of the letter B*];
...
Then create a new Animator object for every div on your page, sending it the appropriate letter array:
var letter_so_and_so = new Animator("div_so_and_so", A, 100);
var letter_this_and_that = new Animator("div_this_and_that", B, 100);
var another_letter = new Animator("another_div", B, 100);
Finally give each one either an offset start, or call their Animator.gotoFrame(f) method to start them on different frames (don't forget to Animator.play()!).
JSFiddle
Try to adopt something like this into your code, I think you'll find it works wonders.
I'm wondering if there is a way to detect load event of multiple images (particularly, a function should execute when the last image in a given set has completed loading).
For instance, an user clicks on a link and lighbox appears with 10 images. When all images have loaded, loading bar should disappear.
jQuery(".lightbox-image").each(function(){
var image = jQuery(this);
jQuery('<img />').attr('src', image.attr('src')).load(function(){
hideLoadingBar();
});
});
This unfortunately triggers hideLoadingBar(); too early (after one image has completed loading).
P.S.
I also need my function to work after images have been cached so: jQuery('#img1, #img2').load(); won't work.
Check out this jQuery imagesLoaded plugin, it should suit your needs I think.
Well, it seems that no one has better idea, so below is my solution/workaround. The other answer to this question is probably what you want to use because it's a library created specifically for that but here's the solution that I'm going to use because it's shorter and simple:
var allImages = jQuery(".lightbox-image").length;
var counter = 0;
jQuery(".lightbox-image").each(function(){
var image = jQuery(this).find('.myimage');
jQuery('<img />').attr('src', image.attr('src')).load(function(){
counter++;
if(counter >= allImages){
hideLoadingBar();
}
});
});
Works for cached images and not cached images.
I want to load only certain images from HTML DOM, based on image width and height.
I dont know how to access the width and height properties of a image using JavaScript.
This must run under any browser.
My app is a bookmarklet, so all the images will be loaded by the time a user will start the bookmarklet. So, i will only scan the DOM, get all the img srv values, and use them. The trick is that i dont want all the images, just the ones that match my wanted sizes.
I have this code so far, and it gets all the images from DOM :
var imgObj = document.getElementsByTagName('img');
for(var i=0;i<imgObj.length;i++)
{
imgsList[i] = imgObj[i].getAttribute('src');
if(consoleLog)console.log(imgsList[i]);
}
return images = imgObj.length;
my problem has been solved here: How to get image size (height & width) using JavaScript?
But i dont know how to adapt my code to img.clientWidth
Is it imgsList[i].clientWidth ?
imgObj[i].clientWidth, imgList contains a list of just the src attributes.
Be careful when using any widths and heights of images as they load asynchronously into the browser. This means that when the DOM loads the width and height will be 0. Only after the images themselves finish loading will the element have a width and height appropriately set.
To get around this you can have load handlers whose callback will be executed once the image finishes loading.
Again though a slightly odd behaviour is that a browser that caches the image will not call this load function again (at least not ones in jQuery) and so you need to make sure for cached versions you do any width checks in a DOM load callback.
You can do this in standard javascript however as an example and since I have a jQuery example in front of me which I was working on earlier I will show you how it can be done in jQuery.
Suppose the image has an id=imageid
function checkWidths() {
//do anything you want here
//jQuery uses the .width and .height functions to get the appropriate attributes of an element, these return a value without the px % etc. To get the actual css use .css('width') instead.
}
$(document).ready(function() {
if($('#imageid').width() > 0)
checkWidths();
});
$('#imageid').load(function() {
checkWidths();
}
To know the dimensions of an image, you need either :
to have the image loaded (then clientWidth is OK if your script is executed in an onload callback)
to have them specified as attributes (<img src=... width=33>). In this case use imgObj[i].getAttribute('width');
Note that if you want to reload an image and avoid all cache problems, the simplest is to change its URL, for example like this :
var srcbase = imgObj.getAttribute('src').split('?')[0];
imgObj.src = srcbase + '?time='+(new Date()).getTime();
(this supposes the image is defined by the path until the '?')
This is it guys, and it works perfect.
populateImgsList : function()
{
var imgObj = document.getElementsByTagName('img');
var j = 0;
for(var i=0;i<imgObj.length;i++)
{
if(consoleLog)console.log('w '+imgObj[i].clientWidth+' h: '+imgObj[i].clientHeight);
if( (imgObj[i].clientWidth>100) && (imgObj[i].clientHeight>100) )
{
imgsList[j] = imgObj[i].getAttribute('src');
if(consoleLog)console.log(imgsList[j]);
j++;
}
}
return images = imgList;
},
I have run into numerous sites that use a delay in loading images one after the other and am wondering how to do the same.
So i have a portfolio page with a number of images 3 rows of 4, what i want to happen is for the page to load,except for the images in img tags. Once the page has loaded i want images 1 of each row to load then say 0.5 seconds later the next image in the row(s) and so no. I'm going to have a loading gif in each image box prior to the actual image being displayed.
I know its doable but cant seem to find the term for doing this. This is purely for looks as it is a design site.
Thanks for the help.
This is very easy to do in jQuery
$('img').each(function(i) {
$(this).delay((i + 1) * 500).fadeIn();
});
Fiddle: http://jsfiddle.net/garreh/Svs7p/3
For fading in rows one after the other in a table it just means changing the selector slightly. Remember to change from div to img -- I just used div for testing
$('tr').each(function(i) {
$('td div', this).delay((i + 1) * 500).fadeIn();
});
Fiddle: http://jsfiddle.net/garreh/2Fg8S/
Here is what you can do, you can load the image tags with out the src and using a custom property:
<img alt='The image' path='image/path.jpg' />
then you can use javascript to load the images when the site is loaded or whenever you please;
// simplified
window.onload = function () {
var images = document.getElementsByTagName('img');
// loop and assign the correct
for (var i =0; i < images.length;i++){
var path = images[i].getAttribute('path');
images[i].src = path;
}
}
I hope you get the concept of how the images are delayed
**please note the path attribute is not a standard one.
The easiest way I can think to do this is to have a table set up that will eventually hold the image tags, but have none on load. Javascript can loop through an array of image urls, and insert those image tags into random locations on the table.
If you want to have the delay, setInterval is the perfect tool. http://www.w3schools.com/jsref/met_win_setinterval.asp
// You can hard-code your image url's here, or better still, write
// a server-side script that will read a directory and return them
// so it is fully dynamic and you can add images without changing code
unpickedImages = array();
// Start loading
loadAllImages = setInterval( insertImage, 600 );
function insertImage() {
if( unpickedImages.length > 0 ) {
var imageUrl = unpickedImages.shift();
// pick empty x, y on your table
// Insert the image tag im that <td></td>
} else {
clearInterval( loadAllImages );
}
}
You really don't need javascript to do this. If you specify the image sizes in the HTML or CSS, the browser will layout and display the page while loading the images, which will likely be loaded in parallel. It will then display them as soon as it can.
That way if users re-visit your site and have the images cached, they all show up immediately. If you have a script to load the images after a delay, you are making visitors wait for content unnecessarily and all their efforts to have a faster browser and pay for a fast internet connection has gone to waste.
I am creating this custom theme www.designislikethis.tumblr.com, which uses the jQuery Masonry and the Slider plugins. In creating this theme I wanted to create my own photoset slideshow instead of messing around with the default Flash-based one.
I started by pulling the images from the JSON of each photoset post by the post's ID using JS and jQuery.
I then rendered these images onto my frontpage in a special div that is linked to a minimal jQuery slideshow plugin, so each image fades in and out.
The code I use to pull/render for each photoset post is as follows:
function photoSet() {
$('.photoset').each(function () {
var postID = $(this).attr('id');
var that = $(this);
$.getJSON("http://designislikethis.tumblr.com/api/read/json?id="+postID+"&callback=?",
function(data) {
var postPhotos = data["posts"][0]["photos"];
var postPermalink = data["posts"][0];
for(var i = 0; i<postPhotos.length; i++)
{
var photo250 = new Image();
photo250.src = postPhotos[i]['photo-url-250'];
postLink = postPermalink["url-with-slug"];
var setClass = ".photoset"+ i;
var imgClass = ".img"+ i;
$(that).find('.slide').append('<a class="'+ setClass +'" href="'+postLink+'"><img class="'+ imgClass +'" src="' +photo250.src+ '"/></a>');
}
});
});
}
Now my problem lies in that all the other elements on my tumblr index page are not rendered with JSON, so they load faster. By the time my photo set renders it's divs are unproportional to everything that has loaded around it, and so the image slider wont kick in and you are left with a mess of rendered images.
What's most annoying about this problem is that some times it works fine, and others it's a mess, depending on how fast the page loads, or if you have the website already cached in your browser.
To see the extent of my Javascript and how I am calling this photoset funciton see here:
http://helloauan.com/apps/DILTtheme/utils.js
I know it's a little messy, for I am new to all of this. :)
Thanks.
I don't know if it will help, but you could try the following:
If the images are the same size and you know that size set the ".slide" div to that;
Try preloading the images and only starting the slide show when they are loaded. e.g using a preload plug-in.
and making use of the "callback" function.