I am trying to get some JavaScript to programmatically adjust a HTML img tag's width to display various sized images correctly.
I have a fixed width img tag at 800px to display an image, this is the max width.
If the image is wider then 800px I want to display it at 800px wide;
If the image is less than 800px wide I want to preserve its width to avoid stretching it.
I use this html/javacript code to get a partial solution:
function resize_image(id) {
var img = document.getElementById(id);
var normal_width = img.width;
img.removeAttribute("width");
var real_width = img.width;
if (real_width < normal_width) {
img.width = real_width;
} else {
img.width = normal_width;
}
}
<img id="myimage" onload="resize_image(self.id);" src="https://via.placeholder.com/350x150" width="800" />
The above code seems to work on all browsers I have tested except Safari (images don't display unless you refresh the page).
I know I can use CSS max-width but that wont work on IE < 7 which is a show stopper.
How can I get this working for all browsers? Many thanks in advance.
I have never seen a safari in work, but you can try changing your onload event to this:
onload="resize_image(self.id);return true"
It could be that without a return value, safari thinks that this object should not be loaded.
Use the IE6 css+javascript hack:
.dynamic_img {
width: expression(document.body.clientWidth <= 800? "auto" : "800px");
max-width: 800px; //For normal browsers
}
Without id:
...
function resize_image( img )
{
//var img = document.getElementById( id );
...
<img onload="resize_image(this);" src="IMAGE.JPG" width="800" />
Have you tried monkey with img.style.width? You could also try having 2 CSS classes for each of the 2 conditions and programmaticly change them.
Related
I have the following code
img = document.getElementById('image'); // which is an <img> element
if (img.width > 0) {
// I get here in Chrome, width is correct
} else {
// I get here in Safari, width is 0
}
Why is the width property 0 in Safari and how can I solve this?
Although it should really matter, try using .clientWidth instead of .width
This answer explains that
In the case of an IMG element, this will get the actual dimensions of the visible image.
HTML
<img id="image" width="0" height="100" src="http://placehold.it/100x100"/>
JavaScript
var img = document.getElementById('image'); // which is an <img> element
if (img.clientWidth > 0) {
// I get here in Chrome, width is correct
console.log('Do something if greater than 0')
}
else {
// I get here in Safari, width is 0
console.log('Do something else if not greater than 0')
}
Here's a quick Codepen link to show it working in both browsers
It is likely that Safari does not have access to the image's dimensions, and therefore is unable to compute its width and height when you probe for it.
You should wait for the image to load, which fires an event handler for which you can fetch the image dimensions from within.
Have you tried to read the "offsetWidth" object.
img = document.getElementById('image');
img.offsetWidth // here you go
Let's say the original height of an image is 200px or lower than 100px. Then I set the 'max-height: 100px' of an image. How would I get its displayed height. I've tried $('img').height(). But is it just returning me a 0 value.
Use window.getComputedStyle ( Firefox, Opera, Safari ) :
example :
<img style="height:100px;max-height:100px;" src="img.gif" id="test">
var img = document.getElementById('test');
var height = window.getComputedStyle(img).height;
console.log(height)
will output 100px
For IE you can use
var height = img.currentStyle.height;
Use simple JavaScript:
var img = document.getElementById('imageid'); // use the id of your image
var height = img.clientHeight;
You need $('img').innerHeight() - Get the current computed height for the first element in the set of matched elements, including padding but not border.
http://api.jquery.com/innerHeight/
$(document).ready(function() {
$("img").load(function() {
alert($(this).height()); // for height
alert($(this).width()); // for width
});
});
Make sure you have jQuery initialized ABOVE this script, as in this case it seems you are trying to use jQuery by the " $ " command.
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
Put the above code in the head of the document.
in the body, but the image
<body>
<img src="img.jpg" id="new-image" />
</body>
Above is the HTML, the image has an ID of "new-image"
IDs can be selected using jQuery by adding a # before the ID
e.g. "#new-image"
$(document).ready(function(){
// Retrieves computed image height and stores to variable "imgHeight"
var imgHeight = $('#new-image').height();
// Shows current computed/displayed height in development console
console.log(imgHeight);
// If you don't know how to access the development console
// You can also use alert (but you should learn to use the console!)
alert(imgHeight);
}
Make sure to wrap the above code in a script tag.
I have function that is supposed to wait till background image is loaded and then add image's ratio to it's container and fade background image container in. It seems to work in Chrome, but fails in Internet explorer 8 and 9, and not always works in 10. In ie8 it doesn't seem to understand jquery on('load') event. In ie 9 and 10 it not always finds width of background image. How can I make it work in ie8+ and other major browsers?
js:
$('.item').each(function(index) {
var thisItem = $(this);
var image_url = thisItem.find('.img').css('background-image');
var img = new Image();
img.src = image_url.replace(/(^url\()|(\)$|[\"\'])/ig, '');
if (image_url){
//initialize only when background img is loaded
var $img = $('<img>').attr('src', img.src).on('load', function(){
//don't allow img to be larger than it is
if(img.width < thisItem.width()){thisItem.css({'max-width':img.width+'px'});}
var ratio = img.height/img.width;
thisItem.find('.item_ratio').css({'padding-bottom':ratio*100+'%'});
thisItem.find('.img').fadeIn(800);
});
}
});
html:
<div class="item">
<div class="img" style="background-image:url('some_url'); width: 100%; background-size: cover;"></div>
<div class="item_ratio"></div>
<!-- Some other not important html ->
</div>
The load event on images has been shown to be unreliable/absent, which is why there's a well-known jQuery plugin to help smoothen things out cross-browser. I'd recommend having a look at that instead rather than trying to figure out the browser issues and edge cases like missing load events when browsers fetch images from cache etc.
Edit: code sample to make it work with a dangling <img/> (untested)
//initialize only when background img is loaded
var $img = $('<img>').attr('src', img.src).prependTo(thisItem).hide().imagesLoaded(function() {
//don't allow img to be larger than it is
//... [your code]
});
I used this approach here. (The thumbs on the left are a single background image sprite, I animate those in once the image has loaded).
As an aside, you may also be able to use background-size: contain in CSS. Doing that might be more performant in newer browsers (if images are large) and much simpler since you don't need any code. It's unsupported in IE8 though, which you can test if you're using Modernizr. That would probably be my preferred approach, but I normally include Modernizr anyway. YMMV.
I'm working on a simple script that acts as a slideshow.
It's based on this script.
Background:
Most of these types of scripts (including the more advanced ones) have the issue that they work great with landscape-style images but really mess portrait-style images up. So I'm trying to build something more or less from scratch.
Problem
I want my images centered on the page. So I use position:absolute; and left:50%; and top:50%; which puts left-most and top-most edge of the image in the proper position. But to center it you would need to do left:50% - imageWidth/2 (which obviously doesn't exist in CSS)
So I need to use javascript to get the image height/width and change it's left and top positioning as needed.
Here is my HTML:
<div class="fadewrapper">
<div class="fadein">
<img src="../Content/images/samples/1.jpg">
<img src="../Content/images/samples/2.jpg">
<img src="../Content/images/samples/3.jpg">
</div>
</div>
Here is my CSS:
.fadewrapper {width:100%; height:100%;}
.fadein { display:inline-block;}
.fadein img {position:absolute; top:50%;}
My knowledge in javascript is limited, but I've found this script (on SO):
var img = new Image();
img.onload = function () {
alert(this.width + 'x' + this.height);
}
img.src = 'http://www.google.com/intl/en_ALL/images/logo.gif';
This script works, but I don't know how to use the images on my page and how to then adjust its positioning. Any and all help is very much appreciated.
Here you go. This will set the image in the exact center of the wrapper.
win_width = $('#fadewrapper').width();
win_height = $('#fadewrapper').height();
border = $('#framewrapper').css('borderWidth');
$('.fadein img').each(function(){
$(this).css({
'left' : (win_width - $(this).width() - border ) / 2,
'top': (win_height - $(this).height() - border ) / 2
});
})
Here's a jsFiddle working example. It reacts based on the window size. Resize the output window to see it react
This might be worth of trying:
<DIV style="position:relative;top:100px;height:300px;text-align:center;white-space:nowrap">
<IMG id="your_img_id_1" src="your_img_source" height="100%">
<IMG id="your_img_id_2" src="your_img_source" height="100%">
<IMG id="your_img_id_3" src="your_img_source" height="100%">
</DIV>
Add these positioning rules to your fadewrapper-class, and remove all others. Then make changes needed to top and height values, but don't change the height-attribute values in IMG-elements. IDs can be omitted, if you don't need them.
EDIT:
I'm sorry, I didn't notice to check window resize. Code corrected. Width's shoul'd be OK with smaller window sizes now.
I've tested this in IE, FF, Opera and Chrome. In all those browsers images appear just like I want to. But if I've missunderstood what you'd like to have?
I'm currently building a site and using the Shadowbox JS plugin to display images.
Because we serve up images via a JSP (rather than linking directly to image files), Shadowbox seems unable to dynamically determine their width and height and so just opens the images in an overlay of ~the screen size.
It's possible to manually pass in widths and heights to the shadowbox plugin using 'rel', so I've got around the problem for FF/Chrome/Safari using the following code:
$('#pic1img').attr("src")).load(function() {
picWidth = this.width;
picHeight = this.height;
});
$(window).load(
function() {
var w = $("#pic1img").width();
var h = $("#pic1img").height();
if( picWidth < w ){ picWidth = w; }
if( picHeight < h ){ picHeight = h; }
$('#pic1').attr('rel', 'shadowbox[pics];height=' + picHeight + ';width=' + picWidth);
}
);
But I can't find any way to do the same in IE.
The code actually worked once I began loading the thumbnails at full size and then setting their width and height after load.
The issue was that I was setting a surrounding div to
display: none
until the images were loaded and IE can't work out the sizes of hidden images.
Resolved this by setting
visibility: hidden
instead.