This article was published in PC Plus issue 150 (Apr 99), and is reproduced here for information purposes only. This is the original copy which was sent to the magazine, not the subbed version which appeared on the page. |
Web Workshop, PC Plus issue 150 (April 99)This is the copy for Web Workshop in issue 150 of PC Plus, including captions and images (resized to make them download-friendly). Accompanying it were HTML pages and ScreenCam movies for the magazine's cover-mounted CD-ROM (see link on previous page).
|
|
|||||||||||||||||||
|
[BEGINS]
<head> Web Workshop <strap> Image file
substitution is one of the few 'Dynamic HTML' tricks you can do with the
same code in both Netscape and Microsoft browsers. What's more it's
powerful stuff and great fun, as Paul Stephens finds out. <boxout for
opening area> More on the
SuperCD For example
image substitution pages, JavaScript source code and ScreenCam movies, see
this month's SuperCD, or my website at http://www.bigfoot.com/~pstephens. <body> Issue 148's
Internet Explorer-only animated pushbuttons brought howls of anguish from
Netscape fans, so this month I'll try to make amends by looking at an
image substitution technique which works in both IE and Netscape
Navigator. 'Image substitution' means replacing the .gif or .jpg file displayed by
an <IMG> tag with a different file, so that the on-screen image
changes - a good example of 'Dynamic HTML', and one of the all too few
instances where DHTML code can be made to work with both major browsers.
Substitution is often used in conjunction with mouse events, for example
creating icons which appear to light up or move when the mouse pointer
passes over them (the infamous 'rollover' effect) - or, indeed,
pushbuttons which animate when clicked. You can also use it to create
multi-image slide shows, controlled either by button clicks or timer
events. Image substitution is fairly straightforward if you're writing purely for
IE4. Here are an IE4-only image tag and JavaScript routine: <script> <IMG
ID="MyPic" SRC="PicA.gif" When the mouse
pointer moves over the image, its .src property is changed to 'PicB.gif',
causing the browser to update the screen display. When the mouse pointer
moves off the image, the image's source is changed back to 'PicA.gif'. The
function changepic() accepts two parameters, an object variable pointing
to an IMG object, and a string representing an image file name. It simply
sets the object's .src property equal to the string value, and the job is
done.
Making the code Netscape-compatible involves quite a few changes,
although the results are , at least, still compatible with IE. Netscape
doesn't allow you to address IMG objects directly by name (as in 'MyPic.src='),
and doesn't allow <IMG> tags to trigger onMouseOver, onMouseOut or
onClick events. To solve these problems, you have to access the IMG object
via the document.images collection (an array of object variables pointing
to all the <IMG> tags in the document), and embed the <IMG>
tag inside a hyperlink (<A>...</A>) element, which Netscape
allows to trigger the necessary mouse events. Here's the Netscape (and IE) compatible version: <script> <A HREF="dummypage.htm"
The <IMG>
tag no longer has an ID= attribute, but has a NAME= attribute instead,
while the <A> (hyperlink) tag now contains the event-handler calls.
Because the image represents the entire contents of the hyperlink,
clicking on the link and the image are effectively the same thing. (A
useful tip is to place the </A> hyperlink terminator hard up against
the end of the <IMG> tag (for example ... SRC="PicA.gif"></A>)
- if you allow any spaces or newline characters between the two tags, then
Navigator inserts them, in blue-underlined format, on the screen). In this
example, the hyperlink has been rendered inactive by an onClick="return
false" event handler statement, but you can make it active in a
variety of ways - see 'the Versatile Link' for details.
The function changepic() works differently too; it can't address
the IMG object directly, so has to accept the object's name as a string
value, and use that to index the document.images collection ('
document.images[imgTagName]....'). The basic principle of updating the
object's .src property remains unchanged, however, as does the end result
- when the .src property's value is altered, the browser updates the
screen display, rendering the new image file at the <IMG> tag's
location.
As an alternative to onmouseover and onmouseout, you can trap the
onmousedown and onmouseup events. This results in an image which changes
when the mouse button is pressed, then reverts to its original form when
the button is released. Oddly enough, Netscape supports these events
directly on <IMG> tags, so in theory you don't need an enveloping
<A>...</A> hyperlink. However to be completely safe with mouse
down/up event handling you also need to trap the onmouseout event (see
'The Main Event' for details). Navigator doesn't, of course, support
onmouseout events on <IMG> tags, so it's back to the hyperlinks. Be prepared To avoid this problem, you can pre-download PicB.gif when the page loads,
so that it's (hopefully) already in the browser's cache when changepic()
is first executed (this still may not be the case if the user moves the
pointer over the image immediately after the page appears). The
Navigator/IE compatible way of pre-loading images involves creating dummy
Image objects via a script in the document's <HEAD> section, like
this: <SCRIPT> These Image
objects don't appear on screen, but updating their .src properties ('
MyPicA.src = "PicA.gif"') makes the browser download the
specified image files and place them in its cache. Note that, as well as
the object for the alternative image file (PicB.gif), there's also one for
the <IMG> tag's default image (PicA.gif) - this isn't for
pre-loading purposes, but so that the original image can be restored using
the modified version of changepic() described below.
In theory our original <A> tags and changepic() routine will
work unmodified with these pre-loading Image objects - as long as the
filenames you supply to changepic() are the same as the ones you specify
for the Image object .srcs. To eliminate the risk of errors, however, we
can change the code slightly, like this: <script> <A HREF="dummypage.htm"
The second
parameter to changepic() is now an object variable (imjObj), and must
point to one of the 'new Image' objects created in the <HEAD>
section (so the parameter value is an object name, e.g. MyPicB , not a
string in quotes, such as "PicB.gif"). Instead of updating the
<IMG> tag's .src with a string value, the function now sets it equal
to the .src property of the specified Image object (imgObj.src). You only
have to type the image file once in the source code, so there's no danger
of a mismatch between function call and object declaration.
This system is automatically backward-compatible with browsers that
don't support JavaScript, since they'll simply ignore the <A> tag's
event handlers, and the initial images will remain static. You can take
this a stage further, and protect against browsers which support
JavaScript but don't support the document.images collection, by adding an
if() statement to changepic(), like this: <script> Now the
function will only attempt to manipulate the image tag's .src property if
the document.images collection exists. A wide choice.
At its simplest, image substitution can produce two-state
animations, such as 'winking' eyes and 'illuminating' light bulbs, which
liven up your page as the mouse pointer rolls over them. The visual effect
depends entirely on the contents of the image files - tips are not to make
objects appear to move too far between frames (it doesn't look realistic),
and to use transparent backgrounds (or the same colour as the page
background) to make objects appear to 'float' over the page (drop shadows
enhance this effect).
An animated pushbutton is really just an animated image contained
inside a hyperlink which has an onclick= event handler or an active HREF=
attribute (see 'The Versatile Link' for details). A popular technique is
to make the default button image 'flat', then substitute a 3D-effect popup
version when the onmouseover event occurs (this is the effect used on the
toolbars in Windows applications such as Microsoft Office, so you're in
good company). If you want to go the whole hog you can add a third image,
of the button indented, and show that in response to the onmousedown
event, reverting to the popup version in response to onmouseup or onclick
(see 'The Main Event' for details of the sequence in which mouse events
are fired).
With the addition of a few JavaScript routines, you can create
'checkbox' buttons which toggle between on and off ('lit' and 'unlit')
states, as well as radio button groups, where selecting one button
deselects whichever one was previous 'lit'. I've written JavaScript
functions for these buttons and - terrible confession time - I think that,
although not quite as flexible, they're a better bet than the IE4-only
buttons in issue 148, partly because they're easier to set up, but mainly
because they're cross-browser compatible. That'll teach me to take too
IE-centric a view of things!
Examples of rollovers buttons and slide shows, as well as those
button-handling JavaScript libraries and explanatory ScreenCams, are all
on this month's SuperCD and my web site. Until next month, happy
authoring. <END OF BODY
COPY> <CAPTION FOR
MAIN DIAGRAM - ROUGH LAYOUT IN " web workshop 150 diagram rough.gif",
SUPPLIED WITH THIS COPY> An image
rollover in action. The <IMG> tag places the default image file
"kiss1.gif" on screen when the page is first loaded. The <IMG>
is contained inside a hyperlink (<A>...</A>) container, and
when the mouse pointer moves over the container, the <A> tag's
onmouseover event-handler code substitutes the image file
"kiss2.gif" on screen. When the pointer moves off, the <A>
tag's onmouseout handler restores the default image file "kiss1.gif2. <OTHER
VISUALS - DROP FROM LAST IF OVER> <3-PIC
MONTAGE - WW1502A.GIF, WW1502B.GIF & WW1502C.GIF>
A transparent
(or page-equivalent) background and drop shadow makes an image 'float'
above the surface. The neon-light effect is simply a soft-edged drop
shadow in colour rather than black. <WW1503.GIF>
Yes, you can
even create Netscape-compatible animated pushbuttons, which - to my shame
- I have to admit are more useful than the IE4-only ones in issue 148. The
necessary JavaScript functions are on the SuperCD. <WW1504.GIF>
Image
substitution isn't just about rollovers and buttons - this slideshow page
uses event timers to auto-advance the images in the viewing panel. You can
see it in action in the Altered Images Guide on the SuperCD. <BOXOUT> The Versatile
Link. <BOXOUT PIC - WW1501.GIF>
<CAPTION> If Netscape
supported mouse events in <IMG> tags, then this hyperlink wouldn't
be necessary - but at least it makes page-loading buttons easy to create. <box
body> It seems a
chore having to wrap <IMG> tags in hyperlink (<A>...</A>
containers just so that Navigator can trigger mouse events (see main
text). However the hyperlink is a versatile tag, able to load a new page
into the browser, call JavaScript routines, or just do nothing in response
to mouse clicks. It can also trigger all five major mouse events (onclick,
onmousedown, onmouseup, onmouseover and onmouseout) in Netscape browsers,
so it's easily capable of earning its living.
At its simplest, you might just want the visual effect of an image
animation, for example a bulb that 'lights up' when the mouse rolls over
it. In this case you can disable the hyperlink altogether, like this: The onclick
handler will make JavaScript-enabled browsers ignore mouse clicks on the
link. You can deal with non-JavaScript browsers (which will execute
the link) by making the link's HREF= target ('nojs.htm' in this case) a
'sorry, you need JavaScript to view this site' page.
Alternatively, you can make the <A> tag a functional
hyperlink - just omit the onclick= handler, point its HREF= attribute at a
valid URL, and it will work as standard (remember to add a TARGET=
attribute if you want the page loaded into a different frame). You can
still make the image animate as the pointer moves over it, by trapping the
hyperlink's onmouseover event (don't forget to 'un-animate' it again in
response to the hyperlink's onmouseout event, in case the user moves the
pointer back off without clicking). For a really smart effect on
pushbutton images, you can use the hyperlink's onmousedown event to call a
function which substitutes a third image, simulating the button being
pushed 'in'.
Here's an example of functional, animated-image hyperlink tag: <A HREF="newpage.htm" Instead of
loading a new page, you may want a click on the link/image to do something
on the current page, such as advancing a slideshow. In this case reinstate
the onclick= event handler, and make it a composite statement, like this: <A HREF="nojs.htm" The onclick
handler now contains two JavaScript statements, separated by the
semi-colon. When the user clicks, the browser first executes the function
'advance_show()', then the statement 'return false', which disables the
hyperlink. You can call image substitution routines from the hyperlink's
other mouse-handling events, as in the 'normal' hyperlink example above.
Action routine calls (such as 'advance_show()" aren't restricted to
the onclick event, so if you want to advance your slideshow in response to
the pointer moving over the link, you can say: <A HREF="nojs.htm" If you really
want to work your hyperlink hard, you can combine an action routine call
and a normal hyperlink action, like this: <A HREF="newpage.htm" When the link
is clicked, the browser will execute the function "say_goodbye()",
then, because there's no "return false" in the onclick= string,
it will load the new page.
Working examples of all these hyperlink techniques are on this
month's SuperCD and my web site. <boxout - no pic> The Main Events These are the key mouse events which you can trap on <A> (hyperlink) tags in Netscape Navigator. They also work in Internet Explorer, but in IE you can trap them directly on <IMG> tags as well. Navigator only supports onmousedown and onmouseup on <IMGs>. Clicking
on a hyperlink generates an onclick event, as well as onmousedown and
onmouseup. Reading from the top down, the table shows the sequence in
which the events are triggered, assuming that the user moves the pointer
over an object, clicks (presses and releases the mouse button) while on
it, then moves the pointer away.
If, however, the user clicks down
on an object, holds the button in place, then drags the pointer off the
object before releasing the button, the onmouseup and onclick events
aren't fired. The sequence is now:
This click-drag sequence often occurs in real life, so it's important to anticipate it. Here are some tips: 1. If you're
animating an image via onmousedown and onmouseup event handlers (for
example a button that lights up when clicked and stays lit until the mouse
is released), then add an onmouseout handler with the same action as
onmouseup, for example: 2. If you want
a button or other clickable image's action to be 'abandonable', so that,
having clicked down on it, the user can drag the pointer off before
releasing the button, then attach your function call to its onclick event. 3. If you want
a button or other image's action to be non-abandonable (once the user has
clicked down they're committed), then attach your function call to its
onmousedown event. 4. If you want
a button to light up when clicked, and to stay lit until its action has
completed (or been abadoned), then call its 'un-light' routine from the
end of its onclick event handler string, and also from its onmouseout
event, like this: <A HREF="nopage.htm" <END OF
BOXOUT> [ENDS] (C) Paul Stephens 1999. All rights reserved.
|
|||||||||||||||||||||