Hi, i have working with an aplication ... this:

www.plantasic.es

and like you can see, by clicking in a line at the right, each one displays a different image. When the image is loaded, there's a javascript code for re-measurement, for adjusting to the available screen area. The easy implementation for the resizing would be:

<img onload="initHeightImag()" ...>

but 'onload' is deprecated for img tag, and W3C Markup validator doesn't validate it.

So, i have done something like this:

objImage = new Image();
	
	if (window.XMLHttpRequest)
	  {// code for IE7+, Firefox, Chrome, Opera, Safari
	  xmlhttp3=new XMLHttpRequest();
	  }
	else
	  {// code for IE6, IE5
	  xmlhttp3=new ActiveXObject("Microsoft.XMLHTTP");
	  }
	xmlhttp3.onreadystatechange=function()
	  {
	  if (xmlhttp3.readyState==4 && xmlhttp3.status==200)
	    {
		  objImage.src=""+xmlhttp3.responseText;
		  alert(xmlhttp3.responseText);
	    }
	  }
	xmlhttp3.open("GET","ajax/getsrc.php?id="+img,true);
	xmlhttp3.send();

	objImage.onLoad=initHeightImag();

but unfortunately the result is the image is loaded at its original size. The objImage.src is well retrieved from AJAX, like i can test with the alert: the getsrc.php?id="+img opens a MYSQL query on the database and returns the matching path to the img id, which is set before.

Can anybody give any alternative suggestion? Any help would be really appreciated.

Recommended Answers

All 12 Replies

Miganper,

Using AJAX to revieve an image src is OTT. Unless there is very good reason to involve the server, then it's an unnecessary level of complexity.

Also, it is generally recommended (and ultimately easier) to attach all event handlers in javascript rather than HTML. For this reason, onLoad="..." should be no more deprecated than onClick="...", which is also used on the same page - some validators are fussier than others.

In addition, it is generally unnecessary to use javascript to maintain an image at a fixed size. It can be fixed in height, width or both in HTML or CSS.

Try this :

onload = function() {
	imageSrcs = [
		'http://www.plantasic.es/imags/forestales/abialb5.jpg',
		'http://www.plantasic.es/imags/forestales/abialb9.jpg',
		'http://www.plantasic.es/imags/forestales/abialb1.jpg',
		'http://www.plantasic.es/imags/forestales/abialb2.jpg',
		'http://www.plantasic.es/imags/forestales/abialb4.jpg',
		'http://www.plantasic.es/imags/forestales/abialb3.jpg',
		'http://www.plantasic.es/imags/forestales/abialb6.jpg',
		'http://www.plantasic.es/imags/forestales/abialb7.jpg',
		'http://www.plantasic.es/imags/forestales/abialb8.jpg'
	];//you can reduce these to relative URLs
	var myImg = document.getElementById('myImage');
	function uimg_closure(i) {
		return function() {
			if(myImg) { myImg.src = imageSrcs[i]; }
			return false;
		};
	}
	var links = document.getElementsByTagName('a');
	var count = 0;
	for(var i=0; i<links.length; i++) {
		if(links[i].className === 'imageLink') {
			links[i].onclick = uimg_closure(count);
			count++;
		}
	}
};
<img id="myImage" src="" height="300px" border="0"><!-- Fixed height. Adjust as required. Width will auto adjust to maintain aspect ratio.  -->
<br>
<a href='#' class="imageLink">  1. Hábitat</a><br>
<a href='#' class="imageLink">  2. Árbol 1 (lámina)</a><br>
<a href='#' class="imageLink">  3. Árbol, corteza y conos femeninos</a><br>
<a href='#' class="imageLink">  4. Árbol 3</a><br>
<a href='#' class="imageLink">  5. Árbol 4</a><br>
<a href='#' class="imageLink">  6. Hojas y conos masculinos y femeninos</a><br>
<a href='#' class="imageLink">  7. Hoja 1</a><br>
<a href='#' class="imageLink">  8. Hoja 2</a><br>
<a href='#' class="imageLink">  9. Yemas</a><br>
<!-- links removed from table for this demo -->

Airshow

Thank you for your post, Airshow.

The problem is that i would have to retrieve these URLs with php, and then pass them to javascript. Would that code work with the next modification?:

(i suppose onLoad is on body tag, perhaps i am too newbie for being sure)

<?php 
...//retrieving the URLs for the current record
echo ("<script language='JavaScript'>
function(){
....
}
</script>");
?>
<body onLoad="function()">

And i have to set the image size with javascript because it must be a variable one in each case of browser toolbars and screen resolution. The container div is relatively positioned, however if i set ist height to 100% the unwanted vertical scroll of the browser window appears because the div height value is then the same than the screen height.

You should still be be able to do all that without AJAX providing all the data is known when each page is built.

Write the required height into the img tag like this:

<img id="myImage" src="" height="<?php =$height ?>" border="0"><br>

Then, retreive the image urls, and write them into the document as it is built. It's probably easier to understand if they are written into the HTML (rather than the Javascript) so this is a bit different from what I gave you before:

<ol>
<?php
while( ...... ) {//Loop. I can't help much here because I don't know how you store/retreive the image URLS and titles.
?>
<li><a href="<?php echo $row['imageURL'] ?>" class="imageLink"><?php echo $row['imageTitle'] ?></a></li>
<?php
}
?>
<ol>

The corresponding javascript is simpler that the version I gave you before :

onload = function() {
	var myImg = document.getElementById('myImage');
	function uimg(evt) {
		evt = evt || window.event;
		var target = evt.target || evt.srcElement;
		if(myImg) { myImg.src = target.href; }
		return false;
	}
	var links = document.getElementsByTagName('a');
	for(var i=0; i<links.length; i++) {
		if(links[i].className === 'imageLink') {
			links[i].onclick = uimg;
		}
	}
};

onload = function() { ... in javascript, is an alternative to <body onload="...."> in HTML.

Airshow

Thank you very much for your help, Airshow.

I didn't say that by clicking on the image, there's a zoom in, and a zoom out by Ctrl+click. So, this zooming is done with measures in % and thus the initial image dimensions are set in %. For that, i do all this in javascript: read the height of the container div, the original height of the image, and set the corresponding % for giving the height to the image, also with javascript:

document.getElementById('image').style.height=imageHeight+'%';

Also, if the image width is so big that by fixing the image height to fit to the screen the width would be greater than the container div width, i must set the image width instead of its height. All this is implemented in javascript. Then, it's unknown for my how to transfer an image width or height (depending of the case) to php and displaying the image with its size in html.

So, i don't find another way of doing it: all this javascript code is run with the img event onLoad.

About retrieving the img sources with AJAX, i think the mentioned in the paragraphs above doesn't change the problem, so i can follow your suggestion for the img sources.

Thanks again.

Miganper, I think I would need to see the page in question to fully understand the issues, but you seem to be in control.

Airshow

Of course, Airshow, it's: www.plantasic.es

Just now it's like originally.

The question also would be if really attribute 'onLoad' in img tag is deprecated and would have to be changed in my code, only because the W3C Markup validator doesn't validate it.

Thank you.

Oh yes. It's been a while.

To avoid using image.onload but still retaining the functionality you seek ....

In php use getimagesize and build the javascript as before but with height and width data for each image (as you will determine by writing the rules into your php):

onload = function() {
	imageSrcs = [
		{src:'http://www.plantasic.es/imags/forestales/abialb5.jpg', width:'xxpx', height:'yypx'},
		{src:'http://www.plantasic.es/imags/forestales/abialb9.jpg', width:'xxpx', height:'yypx'},
		{src:'http://www.plantasic.es/imags/forestales/abialb1.jpg', width:'xxpx', height:'yypx'},
		{src:'http://www.plantasic.es/imags/forestales/abialb2.jpg', width:'xxpx', height:'yypx'},
		{src:'http://www.plantasic.es/imags/forestales/abialb4.jpg', width:'xxpx', height:'yypx'},
		{src:'http://www.plantasic.es/imags/forestales/abialb3.jpg', width:'xxpx', height:'yypx'},
		{src:'http://www.plantasic.es/imags/forestales/abialb6.jpg', width:'xxpx', height:'yypx'},
		{src:'http://www.plantasic.es/imags/forestales/abialb7.jpg', width:'xxpx', height:'yypx'},
		{src:'http://www.plantasic.es/imags/forestales/abialb8.jpg', width:'xxpx', height:'yypx'}
	];//xx and yy in each case is determined server-side and written dynamically into the page.
	var myImg = document.getElementById('myImage');
	function uimg_closure(i) {
		return function() {
			if(myImg) {
				myImg.src = imageSrcs[i].src;
				myImg.style.width = imageSrcs[i].width;
				myImg.height = imageSrcs[i].height;
			}
			return false;
		};
	}
	var links = document.getElementsByTagName('a');
	var count = 0;
	for(var i=0; i<links.length; i++) {
		if(links[i].className === 'imageLink') {
			links[i].onclick = uimg_closure(count);
			count++;
		}
	}
};

(See comment in code)

This way all the "intelligence" is exercised server-side and the browser does what it's told.

Airshow

Thank you very much Airshow.

I think i still don't get it. Several questions:

1.- width:'xxpx' height:'yypx' in imageSrcs array would be the image size i want to give initially to each image? i mean, without using zoom in nor zoom out? Then, these data would have been retrieved with php like you suggest, but i wouldn't know how to pass it to the javascript array from the php code.

2.- The zooming would be implemented in the solution you suggest?

I think they aren't all the questions, but i would need to know these responses before anything.

Sorry for the delay in my post, i have been going in and out of this project too many times.

Thank you again.

Yes, width:'xxpx' height:'yypx' are the initial dimensions.

Passing parameters from php to javascript is exactly the same in principle as writing HTML with php. This is because javascript is delivered as uncompiled source, ie text.

For example, consider one line of the imageSrcs array:

//You can research the dimensions you want to use and hard-code them ...{src:'http://www.plantasic.es/imags/forestales/abialb5.jpg', width:'180px', height:'100px'},
//or use php's getimagesize() to discover the images dimensions, then implement a rule, such as 50% ...
<?php $imgSize = getimagesize('imags/forestales/abialb5.jpg'); ?>
{src:'http://www.plantasic.es/imags/forestales/abialb5.jpg', width:'<?php echo $imgSize[0]/2 ?>px', height:'<?php echo $imgSize[0]/2 ?>px'},

I'm not sure exactly what you have in mind for zoom. Changing a img's outer dimensions is easy but zoom/pan within a fixed frame is harder.

Airshow

Yes, i mean zooming within a fixed frame. You can see it in www.plantasic.es, by clicking over the image (zoom in) or Ctrl+clic (zoom out).

Really the functionality has complexity: for doing that zooming, for each specie (that is, each plant which has about 10 images; you can browse through the different species with browse buttons in right top corner), when page is loaded, two frames (divs with overflow hidden) are calculated:

1.- div_imagen: the frame where the image will display
2.- divImagenLinks: the frame where the links list will display

Both calculations are height, since width is given in % with CSS. And these calculations are done for adjusting the two frames to all the available height of the screen, variable depending of the screen resolution and the browser mainly.

These calculations are:

function initDimPosDivs(){

    			if( typeof( window.innerWidth ) == 'number' ) {
    				//Non-IE
	    			var divHeight1 = window.innerHeight-document.getElementById('div_imagen').offsetTop;
	    			var divHeight2 = window.innerHeight-document.getElementById('divImagenLinks').offsetTop;
	    		} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
	    		        //IE 6+ in 'standards compliant mode'
    			        divHeight1 = document.documentElement.clientHeight-document.getElementById('div_imagen').offsetTop;
    			        divHeight2 = document.documentElement.clientHeight-document.getElementById('divImagenLinks').offsetTop;
	       		} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    			        //IE 4 compatible
	    		        divHeight1 = document.body.clientHeight-document.getElementById('div_imagen').offsetTop;
    			        divHeight2 = document.body.clientHeight-document.getElementById('divImagenLinks').offsetTop;
	       		}
	document.getElementById('div_imagen').style.height = divHeight1+'px';
	document.getElementById('divImagenLinks').style.height = divHeight2+'px';	

	initHeightImag()
}

And the called function initHeightImag() sets three global variables and also give height and width to each image, in different way depending of the dimension to adjust to the frame is width or height (for example, if you go to record 407 of 639, by writing '407' in the textfield that shows the actual record -1- in the right top corner of the screen, you will see the specie 'Arroz' -'Rice' in english-, which has 24 images: for the image 1, the adjusted dimension is height, but for the image 7, the adjusted dimension is width (it's much longer than height).

The initHeightImag() function is (it's also called from img onLoad event):

var width=100
var height=100
var whichDim="";

function initHeightImag(){
	if( typeof( window.innerWidth ) == 'number' ) {
		//Non-IE
		var divHeight1 = window.innerHeight-document.getElementById('div_imagen').offsetTop;
		var availWidth=document.getElementById('div_imagen').offsetWidth;
		if (((availWidth/divHeight1)/(document.getElementById('image').offsetWidth/document.getElementById('image').offsetHeight))>1){
			var imageHeight=(((window.innerHeight-document.getElementById('image').offsetTop)/window.innerHeight)*100)-1.2;
			whichDim="height";
		}else{
			imageWidth = availWidth;						
			whichDim="width";												
		}
	} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
	        //IE 6+ in 'standards compliant mode'
	    	divHeight1 = document.documentElement.clientHeight-document.getElementById('div_imagen').offsetTop;
		availWidth=document.getElementById('div_imagen').offsetWidth;
		if (((availWidth/divHeight1)/(document.getElementById('image').offsetWidth/document.getElementById('image').offsetHeight))>1){
			imageHeight=(((document.documentElement.clientHeight-document.getElementById('image').offsetTop)/document.documentElement.clientHeight)*100)-1.2;
			whichDim="height";
		}else{
			imageWidth = availWidth;
			whichDim="width";												
		}
		
	} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
	        //IE 4 compatible
        	divHeight1 = document.body.clientHeight-document.getElementById('div_imagen').offsetTop;
		availWidth=document.getElementById('div_imagen').offsetWidth;
		if (((availWidth/divHeight1)/(document.getElementById('image').offsetWidth/document.getElementById('image').offsetHeight))>1){
			imageHeight = (((document.body.clientHeight-document.getElementById('image').offsetTop)/document.body.clientHeight)*100)-1.2;
			whichDim="height";
		}else{
			imageWidth=availWidth;
			whichDim="width";	
		}

	}

if (whichDim=="height") {
	height=imageHeight;//esto es un % del alto de capa total disponible en la que está la imagen
	width=((divHeight1*(imageHeight/100)*document.getElementById('image').offsetWidth)/(availWidth*document.getElementById('image').offsetHeight))*100;
	document.getElementById('image').style.height=imageHeight+'%';
}else{
	width=100;
	height=((availWidth*(width/100)*document.getElementById('image').offsetHeight)/(divHeight1*document.getElementById('image').offsetWidth))*100;
	document.getElementById('image').style.width=imageWidth+'px';
} 
}

By setting there the GLOBALS whichDim, width and height, the function is preparing them for the use into the 'zooming' function:

function handle_Click(ev){
if (ev.ctrlKey) {
	// smooth zoom out 
	width=width*.95
	height=height*.95
	if(width<1)width=1
	if(height<1)height=1
}else{
	// indicate that the key has NOT been handled
	// smooth zoom in
	width=width*1.05
	height=height*1.05
	if(width>400)width=400
	if(height>400)height=400
}	


widthnice=width.toFixed(1)
if(widthnice==parseInt(widthnice))widthnice=parseInt(width)
else widthnice=width.toFixed(1)
if (widthnice>200) widthnice=parseInt(width) // round to integer because Opera has a problem with floats of 327.7 and above
if (whichDim=="height") {
	document.getElementById('image').style.width=widthnice+'%'
}else{
	if( typeof( window.innerWidth ) == 'number' ) {
		//Non-IE
	    screenWidth =window.innerWidth;
	} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
	    //IE 6+ in 'standards compliant mode'
		screenWidth = document.documentElement.clientWidth;
	} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
	    //IE 4 compatible
		screenWidth = document.body.clientWidth;
	}
	document.getElementById('image').style.width=widthnice+'%'
}
heightnice=height.toFixed(1)
if(heightnice==parseInt(heightnice))heightnice=parseInt(height)
else heightnice=height.toFixed(1)
if (heightnice>200) heightnice=parseInt(height) // round to integer because Opera has a problem with floats of 327.7 and above
if (whichDim=="height") {
	document.getElementById('image').style.height=heightnice+'%'
}
//Return 'false' to indicate that the key HAS been handled. This stops Opera's built in zoom.
return(false)
}

That's all. Besides passing width and height from php to javascript, i would need to pass the img sources for each specie (about 10 different images for each specie of 639).

Considering all that, i don't know if it would be better to forgive strict W3C Markup validator (onLoad is deprecated for img tag according to this validator) because the most optimized way of implementing these functionalities is leaving like it's now.

Thank you very much again.

Miganper,

OK, I understand much more now. Unfortunately, with Christmas fast approaching I have l little time to get deeply into the code.

Do I understand correctly that you now need to get image dimension data into Javascript in order to get the Zoom function working?

If so, then my development strategy would be to manually hard-code the dimensions for about 5-10 images and get zoom working for just those images. Then you will have a "template" for automating the dimensions for all the other images.

If you have any specific (small) questions, then I will do my best.

Airshow

Ok, thank you very much for all your help Airshow.

Regards,
miganper

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.