How to save image width and height from onload? - javascript

I have an array of <li> elements that I am trying to make into a carousel, just that I want the images to be resized if bigger than 640x480 as well as centered into the frame.
I have the following code:
HTML:
<ul id="carousel">
<li><img src="pic1.jpg" /><p><b>2012</b> something</p></li>
<li><img src="pic2.jpg" /><p><b>2016</b> something else.</p></li>
</ul>
JQuery:
var imW=[];
var imH=[];
//...
$('li',obj).each(function(index){
itemSources.push( $(this).find('img').attr('src') );
var img = $(this).find('img');
imW.push(img.width());
imH.push(img.height());
});
I then use itemSources[i], imW[i] and imH[i] to resize my image and add any necessary padding to center it in the frame.
Which works fine provided that my internet is fast enough and the images load before the size is computed. (ha!)
I know I want something like:
var img = new Image();
img.onload = function() {
console.log(this.width + 'x' + this.height);
};
img.src = $(this).find('img').attr('src');
But I cannot save the width and height, since just pushing to the arrays gets out of scope, and so does creating an external callback for that. How can I save those sizes that are so easily printed to the console into my imW and imH arrays?

You can basically set an attribute of an image, something like data-loaded="true" once the image is loaded and when the last image is loaded you can then iterate the images and load the array
In your onload method, do the following changes
var img = new Image();
img.onload = function() {
console.log(this.width + 'x' + this.height);
//set this attribute to indicate that this image has been loaded already
$(this).attr( "data-loaded", "true" );
//check if all images have this attribute
if ( $( "img[data-loaded='true']" ).size() == $( "img" ).size() )
{
//now iterate the images to load your array
}
};
img.src = $(this).find('img').attr('src');

Related

How to do a process after completion of another one in JavaScript

I want to add an image by Javascript, then calculating the html element width as
window.onload=function(){
document.getElementById('x').addEventListener('click', function(e){
var el = document.getElementById('xx');
el.innerHTML = '<img src="img.jpg" />';
var width = el.offsetWidth;
.....
}, false);
}
but since JavaScript conduct all processes simultaneously, I will get the width of the element before loading the image. How can I make sure that the image has been loaded into the content; then calculating the element width?
UPDATE: Thanks for the answers, but I think there is a misunderstanding. img src="img.jpg" /> does not exist in the DOM document. It will be added later by Javascript. Then, when trying to catch the element by Id, it is not there probably.
You can give the img an ID and do the following :-
var heavyImage = document.getElementById("my-img");//assuming your img ID is my-img
heavyImage.onload = function(){
//your code after image is fully loaded
}
window.onload=function(){
document.getElementById('x').addEventListener('click', function(e){
var el = document.getElementById('xx');
var img = new Image();//dynamically create image
img.src = "img.jpg";//set the src
img.alt = "alt";
el.appendChild(img);//append the image to the el
img.onload = function(){
var width = el.offsetWidth;
}
}, false);
}
This is untested, but if you add the image to the DOM, set an onload/load event-handler and then assign the src of the image, the event-handling should fire (once it's loaded) and allow you to find the width.
This is imperfect, though, since if the image is loaded from the browser's cache the onload/load event may not fire at all (particularly in Chromium/Chrome, I believe, though this is from memory of a bug that may, or may not, have since been fixed).
For the chrome bug you can use the following:-
var BLANK = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';//create a blank source
var tImg = document.getElementById("my-img");//get the image
var origSrc = tImg.src;//get the original src
tImg.src = BLANK;//change the img src to blank.
tImg.src = origSrc;//Change it back to original src. This will lead the chrome to load the image again.
tImg.onload= function(){
//your code after the image load
}
You can use a library called PreloadJS or you can try something like this:
//Somewhere in your document loading:
loadImage(yourImage, callbackOnComplete);
function loadImage(image, callbackOnComplete){
var self = this;
if(!image.complete)
window.content.setTimeout(
function() { self.loadImage(image, callbackOnComplete)}
,1000);
else callbackOnComplete();
}
I did this when I worked with images base64 which delay on loading.

how to know size of the image by it url

I have an input text field where the user provides the source url of the image ,
for example http://mysite/images/STARTPAGE_LOGO.gif is a valid value.
I dont have any img tag or something else in my html document. How can i determine the dimensions of the image which is present at the URL the user has entered .
There is no method to find out the width and height of the image without loading it so you will have to dynamically load it , and to do so you can use
function getDimensions(_src,_callback){
/* create a new image , not linked anywhere in document */
var img = document.createElement('img');
/* set the source of the image to what u want */
img.src=_src;
/* Wait the image to load and when its so call the callback function */
/* If you want the actual natural dimensions of the image use naturalWidth and natural height instead */
img.onload = function () { _callback(img.width,img.height) };
}
After declaring the above function in pure javascript spirit you can do something like
getDimensions('http://mysite/images/STARTPAGE_LOGO.gif',function(w,h){
console.log( "Height : ",h,"Width:",w);
});
HTML:
<input id="src" type="text" value="https://www.google.pl/images/srpr/logo3w.png"/>
JAVASCRIPT:
var img = new Image; // create tmp image element
// is equal to document.createElement('img');
Bind function on onload event, it will be called automatically when image is loaded.
img.onload = function(){
alert( this.width +" : " + this.height );
};
Set the source of image;
img.src = document.getElementById('src').value // get the value of input element;
for curiosity in jQuery:
$('<img/>').attr('src',$('#src').val()).bind('load',function(){
alert( this.width +' x ' + this.height );
});

JavaScript/jQuery: Running DOM commands *after* img.onload commands

I need to get the width & height of a CSS background image and inject it into document.ready javascript. Something like:
$(document).ready(function(){
img = new Image();
img.src = "images/tester.jpg";
$('body').css('background', 'url(' + img.src + ')');
$('body').css('background-size', img.width + 'px' + img.height + 'px');
});
The problem is, the image width and height aren't loaded in at the time of document.ready, so the values are blank. (They're accessible from console, but not before).
img.onload = function() { ... } retrieves the width and height, but DOM $(element) calls aren't accessible from within img.onload.
In short, I'm a little rusty on my javascript, and can't figure out how to sync image params into the DOM. Any help appreciated
EDIT: jQuery version is 1.4.4, cannot be updated.
You could use $.holdReady() to prevent jQuery's ready method from firing until all of your images have loaded. At that point, their width's and height's would be immediately available.
Star by calling $.holdReady(true). Within the onload method of each image, check to see how many images have been loaded all together, and if that matches the number of expected images, you can $.holdReady(false) to fire the ready event.
If you don't have access to $.holdReady(), you could simply wait to spit out your HTML until all of the images have loaded by still calling a function:
var images = { 'loaded': 0,
'images': [
"http://placekitten.com/500/500",
"http://placekitten.com/450/450",
"http://placekitten.com/400/400",
"http://placekitten.com/350/340",
"http://placekitten.com/300/300",
"http://placekitten.com/250/250",
"http://placekitten.com/200/200",
"http://placekitten.com/150/150",
"http://placekitten.com/100/100"
]};
function outputMarkup() {
if ( ++images.loaded === images.images.length ) {
/* Draw HTML with Image Widths */
}
}
for ( var i = 0; i < images.images.length; i++ ) {
var img = new Image();
img.onload = function(){
outputMarkup();
};
img.src = images.images[i];
}

How to get new image size after changing src in IE

I have an image element with a spinner gif. I later dynamically change the src of that image with jQuery, and I want to get the actual width and height of the new image. Here is my code:
function loadImage() {
$('#uploaded-image').load(function() {
var img = document.getElementById('uploaded-image');
// These statements return the correct values in FF and Chrome but not IE
imgWidth = img.clientWidth;
imgHeight = img.clientHeight;
});
$('#uploaded-image').removeAttr('width').removeAttr('height').attr('src', imgUrl);
}
This works perfectly in Chrome and Firefox, but IE always returns the size of the original spinner gif instead of the new image.
How can I get the width and height of the new image in IE?
Notes:
I've tried the jQuery .width() and .height() methods in addition to the pure Javascript approach, with the same results.
The .load event is being fired as expected in all browsers.
Use offsetHeight and offsetWidth in IE.
Check this out in your IE: http://jsbin.com/abopih/5
var imgUrl = "http://www.google.com/intl/en_com/images/srpr/logo3w.png";
var img = document.getElementById('uploaded-image');
$('#uploaded-image').click(function() {
imgWidth = img.clientWidth;
imgHeight = img.clientHeight;
$('#uploaded-image').removeAttr('width').removeAttr('height').attr('src', imgUrl);
console.info('clientWidth: ', img.clientWidth);
console.info('clientHeight: ', img.clientHeight);
console.info('offsetWidth: ', img.offsetWidth);
console.info('offsetWidth: ', img.offsetWidth);
});
You could create a hidden div and place the image in there in order to get the size. Just make sure the hidden div isn't done with display:none, because then it will have no dimensions. Use visibility:hidden, grab the dimensions, and then remove it.
Make sure you remove css height and width as well:
$('#uploaded-image').css({ height: "auto", width: "auto" });
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="file" id="file" />
<script type="text/javascript" charset="utf-8">
$("#file").change(function(e) {
var file, img;
file = document.getElementById("file");
if (file!=null) {
img = new Image();
img.src = file.value;
img.onload = function() {
alert(img.width + " " + img.height);
};
img.onerror = function() {
alert( "not a valid file: " + file.type);
};
}
});
</script>
It seems to be a cache problem.
Add this to your image source url:
imgUrl += new Date().getTime();

Changing source of image with an image of different size, won't resize in IE

I'm trying to create a very simple gallery using javascript. There are thumbnails, and when they're clicked the big image's source gets updated. Everything works fine, except when I try it in IE the images' size stays the same as the inital image's size was. Let's say initial image is 200x200 and I click on a thumbnail of a 100x100 image, the image is displayed but it is streched to 200x200. I don't set any width or height values, so I guess the browser should use image's normal size, and so does for example FF.
here's some code:
function showBigImage(link)
{
var source = link.getAttribute("href");
var bigImage = document.getElementById("bigImage");
bigImage.setAttribute("src", source);
return false; /* prevent normal behaviour of <a> element when clicked */
}
and html looks like this:
<ul id="gallery">
<li>
<a href="images/gallery/1.jpg">
<img src="images/gallery/1thumb.jpg">
</a>
</li>
(more <li> elements ...)
</ul>
the big image is created dynamically:
function createBigImage()
{
var bigImage = document.createElement("img");
bigImage.setAttribute("id", "bigImage");
bigImage.setAttribute("src", "images/gallery/1.jpg");
var gal = document.getElementById("gallery");
var gal_parent = gal.parentNode;
gal_parent.insertBefore(bigImage, gal);
}
There's also some code setting the onclick events on the links, but I don't think it's relevant in this situaltion. As I said the problem is only with IE. Thanks in advance!
Sounds like IE is computing the width and height attributes for #bigImage when it is created and then not updating them when the src is changed. The other browsers are probably noting that they had to compute the image dimensions themselves so they recompute them when the src is changed. Both approaches are reasonable enough.
Do you know the proper size of the image inside showBigImage()? If you do, then set the width and height attributes explicitly when you change the src:
function showBigImage(link) {
var source = link.getAttribute("href");
var bigImage = document.getElementById("bigImage");
bigImage.setAttribute("src", source);
bigImage.setAttribute("width", the_proper_width);
bigImage.setAttribute("height", the_proper_height);
return false;
}
If you don't know the new dimensions then change showBigImage() to delete #bigImage and create a new one:
function createBigImage(src) {
var bigImage = document.createElement("img");
bigImage.setAttribute("id", "bigImage");
bigImage.setAttribute("src", src || "images/gallery/1.jpg");
var gal = document.getElementById("gallery");
gal.parentNode.insertBefore(bigImage, gal);
}
function showBigImage(link) {
var bigImage = document.getElementById("bigImage");
if(bigImage)
bigImage.parentNode.removeChild(bigImage);
createBigImage(link.getAttribute("href"););
return false;
}

Categories

Resources