Getting an image's 'real' width and height in IE - javascript

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.

Related

Javascript fails to execute properly for some images

I'm building my personal e-commerce website with vertical rhythm in mind. It's just a challenge for myself. But images are so problematic for me. I need to set their height using javascript (script below?), for some images it's executed properly but not some others. The not executed properly images will have 0 height.
I've tried using window.onload but still don't work. I also looking for proper vanilla JS plugin but none of them available to use.
function adjustImg(element) {
var images = document.getElementsByTagName(element),
lineHeight = parseInt(window.getComputedStyle(document.body).getPropertyValue('line-height')),
newLineHeight = lineHeight / 2;
for(i = 0; i < images.length; i++) {
var aspectRatio = images[i].offsetWidth / images[i].offsetHeight,
originalHeight = images[i].offsetWidth / aspectRatio,
div = Math.round(originalHeight / newLineHeight),
newHeight = newLineHeight * div;
images[i].style.height = newHeight + 'px';
}
}
I expected all images to have corrected height properly. But like I said some of them don't show up because of the 0 height. My hypothesis is because the image is not completely loaded, but the javascript has been executed. Therefore the javascript could not obtain the offsetWidth and offsetHeight
I've no idea how to fix this issue, any helps are much appreciated. Sorry for my english.
Perhaps try img.onload. This event fires when an image is loaded.

Adjust Iframe height dynamically and set scroll if content height change on client side event (Text Expand/Collapse using +/- buttons)

I have been searching around for a solution to set scroll of iframe sourcing same domain page using javascript. I just want to have scroll on the iframe only if the content's height is greater that the window height. Came across solutions using setInterval. In IE i dont get a proper scrollheight for a page that has some content hidden. The works fine in chrome and mozila although. Also it looks like i have to set anyways max-hright of the iframe to get this code working on chrome and IE when the use click on +/- in the iframe page. I dont have controll over the source page for iframe. Also there are events where in the content height of the iframe changes at client side like expand/collapse thing. Any suggestions as to why it is happening or any other options to implement.
Iframe container (div)
border: groove;border-width: thin;display:none;position:fixed;z-index:998;width:800px;background-color: white;right: 83px;top:22px;
Iframe style
top: 20px;margin:0;padding:0
Javascript function that gets called based on interval to set iframe height to that content height
function AdjustIframeHeightOnLoad() {
var screenHeight = $(window).height();
var iframeContentHeight;
var iframeContentwidth;
iframeContentHeight = document.getElementById("iframe_ObjectLink").contentWindow.document.body.scrollHeight;
iframeContentwidth = document.getElementById("iframe_ObjectLink").contentWindow.document.body.scrollWidth;
if (iframeContentHeight > (screenHeight - 47)) {
document.getElementById("objectionMenuContentContainer_div").style.height = (screenHeight - 27) + "px";
document.getElementById("iframe_ObjectLink").height = (screenHeight - 47);
document.getElementById("iframe_ObjectLink").contentWindow.document.documentElement.style.overflowY = "scroll";
}
else {
document.getElementById("objectionMenuContentContainer_div").style.height = iframeContentHeight + "px";
document.getElementById("iframe_ObjectLink").height = (iframeContentHeight - 25);
document.getElementById("iframe_ObjectLink").contentWindow.document.documentElement.style.overflowY = "hidden";
}
if (iframeContentwidth > 883)
document.getElementById("iframe_ObjectLink").contentWindow.document.documentElement.style.overflowX = "scroll";
else
document.getElementById("iframe_ObjectLink").contentWindow.document.documentElement.style.overflowX = "hidden";
}

jQuery script not executing on initial page load

I have created a custom jQuery plugin that does some simple image resizing for my website. Here is the site: http://www.daemondeveloper.com/photography/gallery.php
As you can see, for debugging purposes I have made portrait images have an opacity of 0.5 and landscape images an opacity of 1. I classify images as portrait or landscape using this custom plugin:
(function($) {
$.fn.superFit = function(options) {
var $this = $(this);
var parent = $this.parent();
var parentW = parent.width();
var parentH = parent.height();
var imgW = $this.width();
var imgH = $this.height();
var imgRatio = imgH / imgW;
var parentRatio = parentH / parentW;
if(imgRatio < parentRatio) //We have a landscape image
{
//First set the height of image to be 100%;
$this.css('height', '100%');
imgW = $this.width();
parentW = parent.width();
//Now center the image
$this.css('margin-left', -(imgW/2)+(parentW/2));
}else{ //We have a portrait image
$this.css('width', '100%');
$this.css('opacity', '0.5');
}
}
})(jQuery);
I want portrait images to fill up the width of its parent but overflow off the bottom of the parent. This seems to be working fine. However, the panoramic images (there are 2) that should have a landscape classification are being looked at by the jQuery as a portrait. That is, until you refresh the page. If you click on the Gallery menu item or hit refresh, all of a sudden the plugin works and you can see the landscape images become opacity 1 and fill up the parent as they should.
So what is causing the jQuery to fire only after refreshing the page again?? I am guessing it must have something to do with the way the pictures are loaded or something.
Finally, here is the code that runs the plugin function:
$('#gallery ul li').each(function() {
var $frame = $(this).children('div');
var fw = $frame.width();
var fh = $frame.height();
$frame.children('img').superFit();
});
This is being ran on document.ready
UPDATE: Actually using refresh or F5 does NOT fix the issue. For some reason only when you click the Gallery menu item or get focus on the address bar and hit Enter does it work...
I am guessing it must have something to do with the way the pictures are loaded or something.
Yes, you won't be able to get the dimensions of an image before it is loaded. On refresh the images will load from cache before DOMready.
Instead, hook on the .load() event.

How to alter the original HTML while it's still loading

I need to use some data, calculated by JS (for example: window size) as css property of some HTML element. To avoid flickering of the window because of layout changes, I can't afford to use document.onready. I actually need to trigger JS function at the time the DOM element is added to the DOM tree.
I've tried with DOMNodeInserted event, but it seems that it triggered only for elements that are added post-loading the HTML code, with JavaScript.
What I need is to change tag that is presented in the original HTML source of the page. So for now I just inline JavaScript just after the HTML code of the tag that has to be changed, but is there a way to do this without inlining JS after every such tag. Something like DOMNodeInserted, but triggered while the original HTML is being rendered. Or how else I can accomplish this - having a JS dependent layout that does not move after it's loaded (it's properly generated before showing it to the user) and still have HTML code in the page (e.g. do not generate the page entirely from JavaScript)?
UPDATE
here is the javascript that is used to resize image. It respects both width and height, while widht:100% or height:100% works unless the window width/height is not smaller then image itself.
function resizeImg() {
var imgwidth = bgImg.width();
var imgheight = bgImg.height();
var winwidth = $(window).width();
var winheight = $(window).height();
var imgratio = imgwidth / imgheight;
imgwidth = winwidth;
imgheight = winwidth / imgratio;
if (imgheight < winheight) {
imgheight = winheight;
imgwidth = imgheight * imgratio;
}
$('.cover-image').css({
width: winwidth+'px',
height: winheight+'px'
});
}
You can use a script to compose a stylesheet and add it to a new style element on the head before the body renders.
Or you can use media queries in a style sheet and apply the styles you prefer for different window or device dimensions.

How can I resize an image, added via ajax, to fit within specific dimensions while maintaining aspect ratio using JQuery/CSS?

I've got a web application that loads some content from an external source to the dom via an ajax call, one of the things that comes back is a set of images (different sizes and aspect ratios) to be displayed in an profile photo section. I'd like for each of the images to be resized to fit within a 64px x 64px area and I'd like to maintain aspect ratio. I was able to do this in firefox, chrome, and safari, but I've no luck getting this to work in IE 7 or 8. The problem I've had is finding a jquery event that reliably gets triggered after the image loads since the image was added after the page load. Here's what works in the listed browsers:
$(window).load(function () {
$('.profileThumbnail').each(function (i) {
var divHeight = $(this).height();
var divWidth = $(this).width();
if (divHeight > divWidth) {
$(this).css('height', '64px');
$(this).css('width', 'auto');
}
else {
$(this).css('height', 'auto');
$(this).css('width', '64px');
}
divHeight = $(this).height();
var divParentHeight = $(this).parent().parent().height();
var divNewHeight = (divParentHeight - divHeight) / 2;
$(this).parent().css('top', divNewHeight);
divWidth = $(this).width();
var divParentWidth = $(this).parent().parent().width();
var divNewWidth = (divParentWidth - divWidth) / 2;
$(this).parent().css('left', divNewWidth);
});
});
I'm also trying to center (horizontally and vertically) them which is what the rest of that code does, but I think I've got all of that working if I can find a way to trigger this code after the image loads in IE.
keep in mind this needs to work both on the first visit (not cached) and subsequent visits (cached). I'm looking for a jquery, javascript, or css solution as I want to avoid the roundtrip/bandwidth for each image.
Have you tired to add a load event to the images yourself which triggers when the image is loaded? This is how image preloaders work.
var img = document.createElement("img");
img.onload = function(){ alert('loaded'); }
img.onerror = function(){ alert('error'); }
img.src = "foo.png";
You can add the onload to the image elements themselves if you are not doing the preload approach.
The problem I've had is finding a jquery event that reliably gets triggered after the image loads since the image was added after the page load.
Instead of setting an onload listener for the window, set an onload listener for the images you are loading remotely. Set the listener after you create the image object and before you insert it into the body. The listener can basically be all the stuff insife of the .each() in the code you posted,

Categories

Resources