|
from Martin Tsachev's web-site,
an Evolt.org site

You are here:

Compatibility
 |
This script does not work in version 3 or lower browsers |
 |
The fading effect does not work in Opera 5, Konqueror and Omniweb,
because these browser don't support clipping |
 |
Version 3 or lower browsers should just see the photos side by side
and down to the end of the page |
I have seen many slideshow scripts almost all of which support version
3 browsers but require equal sized photos. My script does
not require equal sized photos at all. In addition it
also adds a fading effect( I can't quite remember is that called doors or
only the horizontal version is).
Clipping is a very powerful CSS
property. It tells the browser what area of the visual element should be
displayed, as far as I know only the rect area( rectangle) is supported by
now. You can produce amazing fade effects dynamically changing its value.
The script
The HTML
<h1>My DHTML slideshow gallery</h1>
<div align="center">
<a href="javascript:changeSlide(-1)">Previous</a>
<a href="javascript:changeSlide(1)">Next</a>
<a href="javascript:setFade(false)">No fade</a>
<a href="javascript:setFade(true)">Fade</a><br>
</div>
<div id="slide0" class="slide">
<img src="slide0.jpg" alt="slide0" width="100" height="50">
</div>
<div id="slide1" class="slide">
<img src="slide1.jpg" alt="slide1" width="100" height="50">
</div>
<div id="slide2" class="slide">
<img src="slide2.jpg" alt="slide2" width="50" height="100">
</div>
<div id="slide3" class="slide">
<img src="slide3.jpg" alt="slide3" width="100" height="50">
</div>
Simple but working. Of course you do not have to name your images
slide0.jpg and so on.
The stylesheet
<style type="text/css">
.slide {
position : absolute;
visibility : hidden;
top : 200px;
left : 50px;
}
#slide0 {
visibility : visible;
}
</style>
Maybe you are wondering why I didn't set the clipping in the stylesheet
but left it to the JavaScript. The answer is simple: Netscape Navigator 4
can get only the height/width of the block( actually the clipping area),
when no clipping is set( apparently it doesn't get the height value
properly, but I have never seen a difference more than 10 pixels).
The JavaScript
Explanation
The HTML
First the controls are set using anchors( I also thought of having a
form with a checkbox for the fade effect but the slideshow was to be
included in a layer and it was to be a problem with NN 4). I have never
liked coding for NN 4 browsers but unfortunately I have to do so because
their users cannot be simply discarded off your site. Not that some should
but in such a case it is not a matter (for a browser market share stats
(free) go to www.webreview.com/browsers/browser_faq.shtml).
<div id="slide0" class="slide">
<img src="images/slide0.jpg" alt="slide0" width="100"
height="50" border="0"></div>
This sets the first slide of your DHTML slideshow. The img
should be wraped in a div because NN 4 considers only div's
and span's ( I think) for layers, not counting proprietary
tags. The case is that NN 4 can only set visibility/clipping of a layer.
The class="slide" is for setting the position
and visibility of all slides, and the id is to
identify the needed slide to be viewed.
The stylesheet
.slide {
position : absolute;
visibility : hidden;
top : 200px;
left : 50px;
}
#slide0 {
visibility : visible;
}
First the class definition for all the slides. It sets the position
to absolute to get the impression that the next slides comes
from below the previous (not to have the user scroll down the page to see
the next slide). Visibility : hidden prevents the browser
from visializing the slides on the screen, while still reserving the space
needed. We set also the top and left coordinates
of the slides (px being the pixel unit).
The following style rule is to make only the first slide visible to the
user.
The script
var DHTML =
(document.getElementById || document.all || document.layers);
if (!DHTML) {
alert('Your browser is not capable of displaying DHTML');
}
function getObj(name) {
if (document.getElementById) {
this.obj = document.getElementById(name);
this.style = document.getElementById(name).style;
} else
if (document.all) {
this.obj = document.all[name];
this.style = document.all[name].style;
} else
if (document.layers) {
this.obj = document.layers[name];
this.style = document.layers[name];
}
}
function visib(objName, flag) { // triggers layer visibility
x = new getObj(objName);
x.style.visibility = (flag) ? 'visible' : 'hidden';
}
These are basic DHTML functions that I use for the slideshow. Actually
I took them from www.xs4all.nl/~ppk/js/
I consider them self explaining, but for all of you who never had a chance
to get involved with DHTML:
 |
First we test for DHTML support( i.e. DOM1: the getElementById
method, IE 4 the document.all collection, NN 4 the document.layers
array). If there is such a method/array its toBoolean converted result
is true otherwise it is false, and if all evaluate to false that means
that the browser does not support DHTML. |
 |
Having the DHTML variable, described above we check if the browser
does not support DHTML, and if this is so we inform the users that
their browser won't show the slideshow properly. |
 |
The getObj function is used to handle that browser
incompatibilities in a way that won't get the hell out of you just to
write a DHTML cross-browser code. What it does is to check what DOM is
supported and according to the result create an object and stuff its obj
and style properties with references to the style rules
applied to the layer, and its HTML properties too. |
 |
The visib function triggers the visibility of a layer
and is used basicly to ease the programmer not having to call the getObj
function by himself. |
Only to note that in NN 4 if you want to get a reference to a sublayer
you have to use document.layers['parentLayer'].
document.layers['subLayer'] instead of the easier non-changing way
of the other browsers.
slides = new Array( // The id's of the slides
'slide0',
'slide1',
'slide2',
'slide3',
'slide4',
'slide5',
'slide6',
'slide7');
var fadeOn = false;
function setFade(switchFade) {// Fade switch function
if ( !fadeOn ) {
prepLyr(slides[curImg], true);
} else { // No fade
stopFade();
for ( var i = 0; i < 8; i++ ) {
prepLyr(slides[i], true);
if ( slides[i] != slides[curImg] )
visib(slides[i], false);
}
}
fadeOn = switchFade;
}
First create an array of the id's of the slides, later used when
switching from one image to another. The setFade() function
is used to trigger fading effects on/off( initially no fading is set). The
function uses some of the other functions to change the layers settings in
a way that is sensible for the fade or no fade slideshow.
var curImg = 0; // index of the array entry
var lastImg = 0;
function changeSlide ( change ) {
if (!DHTML) return;
curImg += change;
if ( curImg < 0 ) curImg = slides.length-1;
else
if ( curImg >= slides.length ) curImg = 0;
if ( fadeOn ) {
firstFade = true;
prepLyr(slides[lastImg], true );
fadeLayer(slides[lastImg], 10, 50);
} else {
visib(slides[lastImg], false);
visib(slides[curImg], true);
}
lastImg = curImg;
}
This is the function that I use to change the current slide displayed.
I no fade is set it only hides the previous image and shows the next one,
otherwise it sets the firstFade variable to true, which is required to
determine wheter after the fade a next one should be invoked. Then the
layers clipping is set to no-clipping by the prepLayer function( the true
parameter), and the fadeLayer function executed sets the global variables
which are later used by the realFade function.
var clipTop, clipWidth, clipBottom, lyrheight;
var time,amount,theTime,middle;
var slideSize = new Array()
function prepLyr(lyr, vis) {
if (!DHTML) return;
x = new getObj( lyr );
if (document.layers) {
if ( !slideSize[lyr] ) {
lyrheight = x.style.clip.bottom;
clipWidth = x.style.clip.right;
slideSize[lyr] = lyrheight + 'x' + clipWidth;
} else {
lyrheight = parseInt(slideSize[lyr]);
clipWidth = slideSize[lyr].substr(
slideSize[lyr].indexOf('x')+1);
}
if ( vis ) {
clipTop = 0;
middle = Math.round(lyrheight/2);
clipBottom = lyrheight;
} else {
middle = Math.round(lyrheight/2);
clipBottom = middle;
clipTop = middle;
}
x.style.clip.top = clipTop;
x.style.clip.left = 0;
x.style.clip.right = clipWidth;
x.style.clip.bottom = clipBottom;
x.style.visibility = 'show';
} else
if (document.getElementById || document.all) {
lyrheight = x.obj.offsetHeight;
clipWidth = x.obj.offsetWidth;
if ( vis ) {
clipTop = 0;
middle = Math.round(lyrheight/2);
clipBottom = lyrheight;
} else {
middle = Math.round(lyrheight/2);
clipBottom = middle;
clipTop = middle;
}
x.style.clip =
'rect('+clipTop+' '+clipWidth+' '+ clipBottom +' 0)';
visib(lyr, true);
}
}
First declaration of the global variables. The prepLyr function first
tests the global variable DHTML wheter to be executes or not. Then it
creates object x which refers to the layer manipulated, when it comes to
the hard part of it. This is where there is no way to write a code that
will be executed on all browsers, and especially great problems with NN 4
(not wondering). I use the fact that arrays in JavaScript can have string
indices, not only numbers to determine whether this layer's size has been
determined before. If not set the lyrheight to the clipping
area's bottom (which should mean the image's height), and the clipWidth
to the image width. Then create an array entry with that data, because if
you don't do so NN 4 will get a constanlty reducing image size for your
slides until they cannot be much longer visible. If the images has been
shown before it justs reads the array entry to get these values. Then it
is time to test the vis parameter which tells us whether the
image should be faded in or faded out. When fading in we initially set the
clippig area's top and bottom to be the middle of the image, otherwise the
are the top and bottom coordinates respectively.
When all these calculations have been made we actually apply the
settings to the layer, in NN 4 it is through the clip.top/right/bottom/left
properties and set it's visibility to show(
Netscape's proprietary value).
Then we have finished NN 4 code and we check for DOM 1 or IE 4 support.
The task is easier here because no matter what clipping set we can always
get the image height/width. Then we make the same test for fade in or fade
out, and at the end apply the settings as a string to the clip property.
Actually I first made a version of the slideshow with the units
specified( px), but I didn't like it at all because I couldn't get it to
work in NN 4 and Opera 5. Then I found this layer
scroll script, and I got the idea of the compatibility and decided to
make a version in which the fading can be swiched off. The thing is that
the browser assume the pixels as default measure units, and I can't really
tell you whether you should specify them.
function fadeLayer(layername, amt, tim) {
if (!DHTML) return;
thelayer = new getObj( layername );
if (!thelayer) return;
amount = amt;
theTime = tim;
realFade();
}
function stopFade() {
if (time) clearTimeout(time);
}
The fadeLayer function is used just to set the global
variables to the parameters passed to it and then invoke the realFade
function to do the hard work.
The only thing that the stopFade function does is that it
checks the timer ID and if the timer is running it stops it.
function realFade() {
clipTop += amount;
clipBottom -= amount;
if (clipTop < 0 || clipBottom > lyrheight || clipTop > middle) {
if ( clipTop > middle ) thelayer.style.visibility = 'hidden';
if ( firstFade ) nextFade();
return;
}
if (document.getElementById || document.all) {
clipstring = 'rect('+clipTop+' '+clipWidth+' '+clipBottom+' 0)'
thelayer.style.clip = clipstring;
} else
if (document.layers) {
thelayer.style.clip.top = clipTop;
thelayer.style.clip.bottom = clipBottom;
}
time = setTimeout('realFade()',theTime);
}
var firstFade = true;
function nextFade() {
firstFade = false;
prepLyr(slides[curImg], false);
fadeLayer(slides[curImg], -10, 50);
}
The realFade function adds the amount to the clipTop and
subtracts it from the clipBottom. Then we check whether the clipping is
off the image, if it is we check whether it is fade out. When fade out we
hide the slide, otherwise sometimes there are stripes that stay visible
and distract the whole slideshow. If the firstFade variable
is true we execute the nextFade function which fades in the
next slide. In both case of fading we end the function, preventing the
setTimeout invokation which would result in an infinite loop. The next
thing to do is to actually apply the calculated clipping area to the
layer, there are differences in the DOM 1 / IE 4 way and the NN 4
(described above in the prepLyr function explanation).
Afterwards we set a timeout that executes the same function again.
The nextFade function then sets the fisrtFade
variable to false, to prevent looping the fading in effect and invokes the
prepLyr function with parameters the next slide and false to
initialize the image to fade in( clipping top and bottom to the middle).
The realFade function is then invoked, passing it the current
slide, a change amount of -10 pixels, which means that the clipping area
should get bigger, and a delay of 50 miliseconds to widen the area.

More information on this site
|