Dynamic Images: Zooming Images in Window | WebReference

Dynamic Images: Zooming Images in Window

Logo

Keeping the Zoomed Images Within the Display
avoid scrolling to view zoom

If you've been following along, and who hasn't, there was probably a time when you zoomed an image that was close to the bottom of the window and you had to scroll to see it.

We can add to our code to make sure that the zoomed image stays within the viewed part of the page to avoid scrolling.

Try it on our images, by moving them almost off the screen, then zooming:

<A NAME="imBigGuy">
<IMG NAME="imZJup" SRC="jupiter.jpeg" WIDTH=80 HEIGHT=60 HSPACE=20 ALIGN=LEFT></A>

<A HREF="/3d/lesson17/">
<IMG NAME="imZFruit" SRC="3d.jpg" WIDTH=80 HEIGHT=60 HSPACE=20 ALIGN=LEFT BORDER=0></A>

<A HREF="/outlook/column5/">
<IMG NAME="imRich" SRC="richWig.gif" WIDTH=80 HEIGHT=60 HSPACE=20 BORDER=0></A>

JavaScript 1.2 and JScript3.0 give us several new properties that we can use:

Value  JavaScript 1.2 (NS) JScript 3.0 (IE JavaScript)
inner width of client window window.innerWidth document.body.clientWidth
inner height of client window window.innerHeight document.body.clientHeight
distance window left is from page left window.pageXOffset document.body.scrollLeft
distance window top is from page top window.pageYOffset document.body.scrollTop

The best way to achieve this effect is to drop the in-line expansion for Explorer, and place the zoomed image in our popup element. Although the Explorer feature is nifty, too often what has happened, and you have been witnesses in the previous pages, is that the original layout, the author's intended layout, suffered. Since the code we have been developing is appendable to existing pages, we can not always be sure that an in-line zoom will look acceptable. An overlay, however, will always be fine, and we can reposition it to remain within the display area easily.

First, our variable. Note that this feature exists in addition to any of the other features we have discussed. This is a method of displaying, not a selection of what to display. For our example, we will keep the display-by-name routine from last page.

    inWind = true

We have to modify the script that creates the CSS element to accomodate Explorer. Remember, at the end of our page? We assign the Netscape identifier for the element to Explorer as well so we can use the same syntax when calling properties or methods associated with its style

    if (ver4) { document.write("<DIV ID='elZoom'></DIV>"); if (IE4) { document.elZoom = document.all.elZoom.style } }

In findIt, place a conditional:

    function findIt(e) { if (zoomed) { zoomIn(); return false; } if (IE4) { isImage = (event.srcElement.tagName == "IMG") ? 1 : 0; isName = (event.srcElement.name && event.srcElement.name.indexOf(useName) != -1) ? 1 : 0; isOK = (isImage && isName) if (isOK) { whichIm = event.srcElement; if (inWind) { zoomOutInEl() } else { zoomOutInPage() } return false; } }...remainder of function

We must modify zoomOutInEl to accomodate Explorer, as well. First we need to write to the CSS element. Explorer 4 has a new method .innerHTML that replaces the HTML contained in any HTML element. This is not a property of elementName.style because it is not associated with CSS. It is associated directly with named HTML elements. The syntax for calling this method, therefore, is different. All elements with an ID= attribute can have the HTML changed on the fly and the page rearranged. This applies to all tags, including <B> or <H3> believe it or not. The method is called in one of two ways:

document.all.elementName.innerHTML or elementName.innerHTML

The name elZoom that we have given our element is identified by Explorer in two ways. As a CSS declared element with the elZoom identifier or as a DIV tag with the elZoom identifier. It has of course, methods and properties that apply to each of these identifications.

Let's look at the whole new zoomOutInEl function and then discuss the positioning additions:

    function zoomOutInEl(whichIm){ newWidth = whichIm.width * scale; newHeight = whichIm.height * scale; bigImStr = "<IMG NAME='imBig' SRC=\"" + whichIm.src + "\" WIDTH=" + newWidth + " HEIGHT=" + newHeight + " BORDER=0>"; if (NS4) { // is it NS? with (document.elZoom.document) { open(); write(bigImStr); close(); } } // or is it IE? else { elZoom.innerHTML = bigImStr }; // Explorer element write if (NS4) { // find NS position document.elZoom.moveTo(whichIm.x,whichIm.y) // first position element, as before winPosL = document.elZoom.left - pageXOffset; // find its horizontal position in the window winPosT = document.elZoom.top - pageYOffset; // find its vertical position in the window } else { // find IE position document.elZoom.left = whichIm.offsetLeft + whichIm.hspace; // position element left document.elZoom.top = whichIm.offsetTop; // then element top winPosL = elZoom.offsetLeft - document.body.scrollLeft; // find horizontal position in window winPosT = elZoom.offsetTop - document.body.scrollTop; // find vertical position in window } winWidth = (NS4) ? window.innerWidth : document.body.clientWidth; // what are the... winHeight = (NS4) ? window.innerHeight : document.body.clientHeight; // window dimensions? if (winPosL + newWidth > winWidth) { // if element is off the right of window... newPosL = (winWidth - (winPosL + newWidth) - 30); document.elZoom.left = parseInt(document.elZoom.left) + newPosL; // move left accordingly } if (winPosT + newHeight > winHeight) { // if element is off the bottom of window... newPosT = (winHeight - (winPosT + newHeight) - 10); document.elZoom.top = parseInt(document.elZoom.top) + newPosT; // move up accordingly } document.elZoom.visibility = "visible"; // now applies to both NS and IE zoomed = true; }

After we write our expanded image HTML to the element, we reposition it as before. Explorer has a bug or feature, that is, it may or may not be intentional, that retrieves the image coordinates not from the displayed image but from the displayed image plus any HSPACE or VSPACE that it has. Netscape gives us the displayed image. We make allowances for the Explorer way by adding the hspace and vspace to the element. This way, it positions on the top left corner of the original image.

Once positioned, we find its position in the window, as opposed to the page, using the properties in the table above.

Last column, we repositioned elements in both browsers by changing the left and top properties, common to both. They are not internally the same, however. Netscape's left and top are integers representing the pixel position of the element in the page. An element positioned at 200 from the left and 150 from the top would have a left value of 200 and a top value of 150. In Explorer the left value would be "200px" and the top "150px", i.e., strings.

We can assign an integer value to them to move an element, but Explorer will internally change it to a string and append the px. We, therefore cannot perform any simple arithmetic with it, unless we change it to an integer first. Using parseInt(document.elZoom.left) for example, extracts the number from the string and can use it for calculations. This is redundant in Netscape, but it is a method we can use for compatibility.

We append parseInt() when we want the same line of code for both browsers and we use other Explorer properties, offsetLeft and offsetTop, that belong to the HTML tag if we have an Explorer-specific calculation. We've used both of these methods above.

The 30 subtracted from the left position is to account for the vertical scrollbar, and the 10 we subtract from the top gives the element some additional space at the bottom. Otherwise it would end right at the bottom and the user wouldn't immediately know if they got the complete image.

Quickly modify, the zoomIn function for Explorer, and you're done.
    function zoomIn() { if (IE4 && !inWind) { // only for IE if in-page whichIm.width = whichIm.width/scale; whichIm.height = whichIm.height/scale; } else { document.elZoom.visibility="hidden" } // now for both zoomed = false; }

We highly recommend that this method is used in conjunction with the name prefix variable.

What do we do now? The same thing we do every column: take all the code snippets, tighten them up, and see the complete code for our effect. This time it's a biggie!


Produced by Peter Belesis and

All Rights Reserved. Legal Notices.
Created: 08/27/97
Revised: 09/28/97

URL: http://www.webreference.com/dhtml/column3/inWindow.html