Forum Moderators: open

Message Too Old, No Replies

rotating images + links

         

lazydave23

2:29 pm on Jun 10, 2004 (gmt 0)

10+ Year Member



i want to have two images, which switch after a certain set time interval. But, i also want each image to have its own link

can anyone point me to the code to do this?

also, how is this javascript in accessibility terms?

thanks in advance

createErrorMsg

7:54 pm on Jun 10, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If you know the javascript for timing events, you can use it to fire a function that switches the images using the innerHTML property. Put a <span id="whatever"> around your <img> tag, then in the function that switches images, do this:

//first, establish the code to show the image and make it an active link
var newImage = "<a href='thelink.htm'><img src='theimage.gif'><\/a>"

//then, use innerHTML to replace whatever was in between the old <span> tag
document.getElementById('whatever').innerHTML = newImage

This is obviously just one way to do it. The more official way would be to use the various node manipulating methods, but it's a lot more complicated than innerHTML.

As for the timer part, I'm not familiar with how that aspect of JS works, but believe me, this place is bursting with people who are.

For accessibility, remember to add an alt='textdescriptionofimage' into the <img> tag so page readers can describe the image to a user.

Rambo Tribble

10:41 pm on Jun 10, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Another way to do it would be to absolutely position the images within a container, such as a div, and then switch visibility. I'm not sure, but I think it will take fewer processor cycles than innerHTML.

Bernard Marx

11:21 pm on Jun 10, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Indeed. InnerHTML is a bit 'brute force'.
The older methods are probably even better where that's concerned - just changing the src & href props.
A bit like this - not so well organized, but a start:

[pre]
<script>
// params
var interval = 5000
var LINKS = ["page1.htm","page2.htm"]// extendable
var IMAGES = ["pic1.gif","pic2.gif"]
//

preloadImages(IMAGES)

window.onload = swapImages

function swapImages()
{
var image = document.images["theimage"]
var link = document.getElementById("thelink")

var count = 0
setInterval(repeat,interval)
function repeat()
{
count = (count+1)%IMAGES.length
image.src = IMAGES[count].src
link.href = LINKS[count]
}
}

// swaps url strings for images
function preloadImages(arr)
{
var image
for(var k=0;k<arr.length;k++)
{
image = new Image()
image.src = arr[k]
arr[k] = image
}
}

</script>
</head>
<body>
<a href="link1.htm" id="thelink">
<img id="theimage" src = "pic1.gif" border="1" />
</a>
</body>
</html>
[/pre]

Efficiency-wise, probably the best is where the images are all-in-one, and the change is done via a BG shift, or clipping....let's not go there.

createErrorMsg

2:13 am on Jun 11, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Rambo, that's an interesting idea. Would you give both images the same position in the CSS, then use JS to change the CSS rule for each image when the timer fires the function? So:

html:
<div class="image one"><a href="page1.htm"><img src="image1.jpg"></a></div>
<div class="image two"><a href="page2.htm"><img src="image2.jpg"></a></div>

css:
div.image {
position:absolute;
top: 10px;
left: 10px;
}

.one {
visibility: visible;
}

.two {
visibility: hidden;
}

js:
(Again, I know nothing about timers in js, but assuming one could manage to work out the timing part to fire a swap function...)

function swapImage() {
document.stylesheets[0].rules[1].style.visibility = "hidden"
document.stylesheets[0].rules[2].style.visibility = "visible"
}

I wonder, though, wouldn't you have to use display, not visibility? Since visibility saves space in the flow for the element, wouldn't it throw things off for two elements to occupy the same space, even if one is hidden?

Rambo Tribble

3:53 am on Jun 11, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The position:absolute takes care of the displacement issue. Try this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Untitled</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<style type="text/css">
#imgOne,#imgTwo{position:absolute;}
#imgTwo{visibility:hidden;}
</style>
<script type="text/javascript">
var a,b,c,n;
function imgSwap(){
a=document.getElementById("imgOne");
b=document.getElementById("imgTwo");
n=setInterval("flipFlop()",1000);
}
function flipFlop(){
a.style.visibility="hidden";
b.style.visibility="visible";
c=a;
a=b;
b=c;
}
</script>
</head>
<body onload="imgSwap();">
<div>
<img id="imgOne" src="image_1.gif" alt="" />
<img id="imgTwo" src="image_2.gif" alt="" />
</div>
</body>
</html>

Rambo Tribble

5:12 am on Jun 11, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Apropos the original inquiry, let me point out that the id's could be applied to anchor tags (when with an href value, commonly referred to as links) surrounding the images with the same effect.

lazydave23

7:51 am on Jun 11, 2004 (gmt 0)

10+ Year Member



thanks people

rambo, i used the code you gave in your last post, and wrapped the image id with a href, and it does exactly what i need it to do

one last question, if i stick this code into a site with a high level of accessibility, will the javascript prevent the site from being a high accessiilty website?

thanks again :)

Bernard Marx

9:17 am on Jun 11, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Yes, Rambo's method is much better, for a few reasons.
If you're thinking about accessibility, you could do something along these lines:

Wrap all the images in links. Take out all CSS properties that stop all the images being displayed 'normally':

visibility:hidden;
position:absolute;
etc

Then you'll have a page that displays all the links for JS- and otherwise-disabled browsers/users. Then apply those CSS properties via Javascript by using a document.write() statement that adds an amending stylesheet just below the original. Apply the CSS, and the visibility-swapping script to the links.

createErrorMsg

12:52 pm on Jun 11, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Rambo, what's the c variable for, as in:

c=a;
a=b;
b=c;

?

Bernard Marx

1:20 pm on Jun 11, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I'll attempt to answer that for him, as he's in another time zone.
a and b are global variables that hold the images. Function, flipFlop() hides a and shows b. These variables need to be swapped, so that next time the effect is the opposite.

c is a 'holding' variable that is needed in the process. If you had an apple in one hand, and an orange in the other, and you wanted to swap, you'd have to put one of them on the table temporarily. c is the table.

Rambo Tribble

1:33 pm on Jun 11, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Brenard is right, I am differently zoned. Excellent analogy, Bernard.

lazydave23

1:55 pm on Jun 11, 2004 (gmt 0)

10+ Year Member



i just want to say thanks to all you guys. It works perfectly now, and my knowledge of java script has gone up a notch :)

createErrorMsg

8:03 pm on Jun 11, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thank you, Bernard. A simple and clear explanation. You don't find those very often.

drewbono

10:10 pm on Jun 29, 2004 (gmt 0)



Rambo's script was exactly what I was looking for, but I need it to rotate between four different divs instead of two. I tried modifying the javascript but coudln't get it to work. Does anyone know how to enable this behavior?

Bernard Marx

9:55 am on Jun 30, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I have tried to keep it as close to RT's original, but to make it extendable.
There are changes in the HTML & CSS too.

HTML:
No id's needed on the images, but one used on the containing div.

CSS:
The images' CSS is defined using a single contextual selector
The initially visible image is specified using an inline style declaration.[*1]
#flipcontainer img{...}

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<title>Untitled</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<style type="text/css">
#flipcontainer img{position:absolute;visibility:hidden;}
</style>
<script type="text/javascript">

var flipDelay = 3000;
var flipCurrent_i;
//
var flipTimer;
var flipImages;
//
function flipInit()
{
var container = document.getElementById("flipcontainer");
flipImages = container.getElementsByTagName("img");
// ... find index of initial visible (if not defined)
if(typeof(flipCurrent_i)=="undefined")
{
for(var i=0;i<flipImages.length;i++){
if(flipImages[i].style.visibility){
flipCurrent_i = i;
break;
}
}
}
//..................................................
flipTimer = setInterval("flipFlop()",flipDelay);
}

function flipFlop()
{
flipImages[flipCurrent_i].style.visibility = ""
flipCurrent_i = ++flipCurrent_i % flipImages.length
flipImages[flipCurrent_i].style.visibility = "visible"
}

</script>
</head>
<body onload="flipInit();">
<div id="flipcontainer">
<img src="image01.gif" alt="" style="visibility:visible;" />
<img src="image02.gif" alt="" />
<img src="image03.gif" alt="" />
</div>
</body>
</html>

It works like this:

The script finds the collection of images. These are all the images in the container;
Assigns the collection to a global var.
Then, if the index of the initially visible image isn't defined in the script, it looks for the image that has an inline style attribute with a visibility specification (it assumes this to be 'visible'). It gets the index. This becomes the 'flipCurrent_i'.

The timer is set call flipFlop regularly.

flipFlop sets the visibility of the current to "", thus the stylesheet declaration, "hidden" takes over. flipFlop increments flipCurrent_i - with a modulus to keep it cycling within the range of the image indices. Then sets the style of the new current.

TO USE:

You have 2 choices.

Leave the script as it is (apart from the delay), and allow the inline style on the image to tell the script which image is visible from the start.

..or, if you want to use only global stylesheets, you can specify which image is visible in the stylesheet as in the previous version, with an id and a # selector. You will then have to tell the script by setting the flipCurrent_i (at the top) to whatever index the current image has (probably 0). You can then delete the whole marked block (marked), that does the finding.