I have a number of show/hide images on my site which allows the user to click on various thumbnails to open up the full image using layer based styles.
However, my Javascript seems to have developed an error saying that the object has no properties and then takes me to the following line of code:
obj.visibility=’hidden’;
This code was written for me so that i could use the script dynamically with PHP an alter the number of div layers it needed to generate.
The full(?) javascript for this function is:
[COLOR=DarkRed]
function showImg(myShow)
{
var loopNum=99;
for (x=1; x<=(loopNum); x++) //1 based loop
{
myImg = “image” + x;
if ((obj=MM_findObj(myImg))!=null)
{
if (obj.style){obj=obj.style;}
}
if (x == myShow)
{//show it!
obj.visibility=’visible’;
}else{//hide it!
obj.visibility=’hidden’;
}
}
}
I would be enorumously grateful if someone could help me here to pinpoint the error. Let me know if I have missed out any detail/code
Lee
Lee
can you give us the code for function MM_findObj(myImg) as it is this
that set the value of obj and it is a bug in there that could well be the
cause of your problems.
Steve[/QUOTE]
You need to nest the 'if (x == myShow)' block inside the 'if ((obj = ...)' block.[/QUOTE]
function showImg(myShow)
{
var loopNum=99;
for (x=1; x<=(loopNum); x++) //1 based loop
{
myImg = "image" + x;
if ((obj=MM_findObj(myImg))!=null)
{
if (obj.style){obj=obj.style;}
}
if (x == myShow)
{//show it!
obj.visibility='visible';
}else{//hide it!
obj.visibility='hidden';
}
}
}
It should be nested like this:function showImg(myShow)
{
var loopNum=99;
for (x=1; x<=(loopNum); x++) //1 based loop
{
myImg = "image" + x;
if ((obj=MM_findObj(myImg))!=null)
{
if (obj.style){obj=obj.style;}
<i> </i> if (x == myShow)
<i> </i> {//show it!
<i> </i> obj.visibility='visible';
<i> </i> }else{//hide it!
<i> </i> obj.visibility='hidden';
<i> </i> }
<i> </i> }
<i> </i>}
}
Well, I'd say having that script error warning icon on your page looks quite amateurish. I don't know how many images you actually have on your page, lets say 10: In that case the fixed code has to do 10 times as much work and the MM_findObj function is a slow beast.
If you are just interested in finding IMG tags, try replacing 'obj=MM_findObj(myImg)' with 'obj=document.images[myImg]', that should give a nice performance boost.[/QUOTE]
Well, when a script produces an error, IE show a yellow exclamation mark in the bottom left corner and the message "Error on page" in the status bar, other browsers report the error in the JS console. For the more computer-savy visitors this give the impression the page author has done a poor job; others could be confused: "Have I done something wrong?" "Must I correct this error? How?" "Is the page functional?"
[*]What do you mean to say my script error warning icon looks amatuerish?
[/quote]
[*]Are you saying just to replace 'obj=MM_findObj(myImg)' with 'obj=document.images[myImg]' - this i did but now it does not work at all![/quote]? I wasn't very optimistic it would work. Since it don't know what your HTML looks like, I could only make a wild guess.
[*]Does it matter if the page has javascript errors? Is just that before it worked - and it worked fast! (I have upto 60 thumbs and the same in full size images on a page.)[/quote]See 1. There's certainly a way to this implement fast [b]and[/b] bug-free, but not without seeing the complete page. The least thing you can do is hide this error from your users by including
window.onerror = function () { return true }
at the beginning of your script.[CODE]if(obj=document.images[x-1]!=null)[/CODE]
[CODE]function showImg(myShow) {
myImg = "image" + myShow;
MM_findObj(myImg).style.visibility="visible";
}
[/CODE]
[code=html]<img src="..." name="image1" visibility="hidden" />[/code]
[CODE]function showImg(myShow)
{
var loopNum=99;
for (x=1; x<=(loopNum); x++) //1 based loop
{
myImg = "image" + x;
if ((obj=MM_findObj(myImg))!=null)
{
if (obj.style){obj=obj.style;}
if (x == myShow)
{//show it!
obj.visibility='visible';
}else{//hide it!
obj.visibility='hidden';
}
}
}
}[/CODE]
[CODE]function showImg(myShow) {
var loopNum=99;
for (x=1; x<=(loopNum); x++) { //loop 99 times
myImg = "image" + x; //create image name
if (obj=MM_findObj(myImg)) {
if (obj.style){
obj=obj.style;
if (x == myShow) obj.visibility='visible';
else obj.visibility='hidden';
}
}
}
}[/CODE]
[CODE]function showImg(myShow) {
myImg = "image" + myShow;
var currentImg = document.images;
var i = 0;
while(currentImg[i]) {
if(currentImg[i].name==myImg) currentImg[i].style.visibility="visible";
else currentImg[i].style.visibility="hidden";
i++;
}
}[/CODE]
Okay, numero uno. I believe that this could run significantly faster just by moving the curly brace at the end of "if (obj.style){obj=obj.style;}" to encompass the whole of that block. Here is my (differently formatted) version of this solution:
[CODE]function showImg(myShow) {
var loopNum=99;
for (x=1; x<=(loopNum); x++) { //loop 99 times
myImg = "image" + x; //create image name
if (obj=MM_findObj(myImg)) {
if (obj.style){
obj=obj.style;
if (x == myShow) obj.visibility='visible';
else obj.visibility='hidden';
}
}
}
}[/CODE]
My other idea was to go with the document.images idea but modify it so it would have the same functionality. This should be faster because it doesn't have to test every object in the document, just the images. Here it is:
[CODE]function showImg(myShow) {
myImg = "image" + myShow;
var currentImg = document.images;
var i = 0;
while(currentImg[i]) {
if(currentImg[i].name==myImg) currentImg[i].style.visibility="visible";
else currentImg[i].style.visibility="hidden";
i++;
}
}[/CODE]
I believe this second solution should be faster, but I don't have a html page with 60 or so images to test it on, and I can't be bothered to make one. so try them out. It's easy, just copy the script exactly as it is from here and overwrite the current "showImg()" function in your javascript (making sure you've backed up first) and then post here to let me know if they work, and which is better,
Robin.[/QUOTE]
Thanks a lot Robin - this was so much appreciated!
Ok, the results are as follows:
The first solution worked - though not as fast as the original version with the javascript error (but faster than the solution suggested by Orc Scorcher). Anyhow, it is an acceptable speed but quicker would be better.
The second solution did not work; the javascript was set to hide all images on mouseover, and that's exactly what it did do - including the thumbnails! So left with a pretty blank page after first image was clicked on. Maybe there is a way to get the just the main images to hide (CSS styles?).
The conflict with my other javascript slideshow is still apparent. What I will do tomorrow (Tues) is to post a mock site with the two solutions on so that you can see how it works and also to exemplify the javascript conflicts between the thumbnail click to display the main image and the slideshow buttons (forward and back) to display the same images. If a User switches between the two methods, then the correct image gets out of sync.
Maybe a visual example would be better to explain like I said, but here is the rest of the javascript which works the thumbnails (I don't use the fade feature but don't know which lines to delete):
[CODE]var DHTML = (document.getElementById || document.all || document.layers);
if ( !DHTML ) alert('Your browser is not capable of displaying this page');
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) {
x = new getObj(objName);
x.style.visibility = (flag) ? 'visible' : 'hidden';
}
images = new Array( // The ids of the images generated by php to allow for varying amount of images per page
'image1',
'image2',
'image3','image4');
var fadeOn = false;
function setFade(switchFade) {// Fade switch function
if ( !fadeOn ) {
prepLyr(images[curImg], true);
} else { // No fade
stopFade();
for ( var i = 0; i < 8; i++ ) {
prepLyr(images[i], true);
if ( images[i] != images[curImg] )
visib(images[i], false);
}
}
fadeOn = switchFade;
}
var curImg = 0; // index of the array entry
var lastImg = 0;
function changeSlide ( change ) {
if (!DHTML) return;
curImg += change;
if ( curImg < 0 ) curImg = images.length-1;
else
if ( curImg >= images.length ) curImg = 0;
if ( fadeOn ) {
firstFade = true;
prepLyr(images[lastImg], true );
fadeLayer(images[lastImg], 10, 50);
} else {
visib(images[lastImg], false);
visib(images[curImg], true);
}
lastImg = curImg;
}
var firstFade = true;
function nextFade() {
firstFade = false;
prepLyr(images[curImg], false);
fadeLayer(images[curImg], -10, 50);
}
var clipTop = 0;
var clipWidth = 150;
var clipBottom = 0;
var lyrheight = 0;
var time,amount,theTime,middle;
var imageSize = new Array()
function prepLyr(lyr, vis) {
if (!DHTML) return;
x = new getObj( lyr );
if (document.layers) {
if ( !imageSize[lyr] ) {
lyrheight = x.style.clip.bottom;
clipWidth = x.style.clip.right;
imageSize[lyr] = lyrheight + 'x' + clipWidth;
} else {
lyrheight = parseInt(imageSize[lyr]);
clipWidth = imageSize[lyr].substr(imageSize[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);
}
}
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);
}
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);
}[/CODE]
Please note the conflicts with the two ways of displaying the main images - either by clicking the thumbnail or using the slide show buttons.
I would really appreciate it if you could look at this and get back to me if you can.
Thanks once again.[/COLOR]
[CODE]<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Test Slideshow - Mark Weeks Photography</title>
<style type="text/css" media="screen">
@import url(http://www.markweeksphotography.com/styles/mwp.css);
@import url(http://www.markweeksphotography.com/styles/slideshow.css);
</style>
<script src="/__utm.js" type="text/javascript"></script>
<script type="text/javascript">
<!--
////////////// Description underneath image ///////////////////////////
descText = new Array('Test Image 1','Test Image 2','Test Image 3','Test Image 4','Test Image 5','Test Image 6','Test Image 7');
var curImg = 1; // current image
var lastImg = 7; // number of images
///////////// Move forward or backward one image //////////////////
function changeSlide ( change ) {
curImg += change;
if ( curImg < 1 ){
curImg = lastImg;
} else if ( curImg > lastImg ){
curImg = 1;
}
document.main.src= "images/image" + curImg + ".jpg";
document.getElementById("text").innerHTML = descText[curImg-1];
}
///////////// Move to specific image //////////////////
function showImg(myShow) {
curImg = myShow;
if ( curImg < 0 ){
curImg = lastImg;
} else {
if ( curImg > lastImg ){
curImg = 0;
}
}
document.main.src= "images/image" + curImg + ".jpg";
document.getElementById("text").innerHTML = descText[curImg-1];
}
</script>
</head>
<body>
<!-- Logo and Title layer -->
<div id="title">
<h1 style="text-align:right">Test Slideshow<br />
<br />
</h1>
<hr />
<h2>Gallery 1</h2>
</div>
<!-- Image Area-->
<div id="image1"> <img class="photo" src="images/image1.jpg" alt="Test Image 1" title="Test Image 1" id="main" />
<div id="nav" style="background-color:#FFFFCC; border-left:12px solid #FFFFCC; border-bottom:12px solid #FFFFCC">
<table class="buy">
<tr>
<td></td>
<td></td>
<td style="padding-left:10px"></td>
<td><div style="text-align: right; position: absolute; top: 4px; left: 180px;" id="text">Test Image 1</div></td>
<td style="width:20%"><a href="javascript:changeSlide(1)"><img src="images/nav/right_arrow.gif" alt="Next" class="button" title="Next" /></a></a><a href="javascript:changeSlide(-1)"><img src="images/nav/left_arrow.gif" alt="previous" class="button" title="Previous" /></a></td>
</tr>
</table>
<hr />
</div>
</div>
</div>
<!-- Thumbnail Area-->
<div id="thumb_frame">
<table id="item">
<tr>
<td><img src="images/imageTH01.jpg" alt="Test Image 1" onClick="showImg(1)"></td>
</tr>
<tr>
<td><hr></td>
</tr>
<tr>
<td><img src="images/imageTH02.jpg" alt="Test Image 2" onClick="showImg(2)"></td>
</tr>
<tr>
<td><hr></td>
</tr>
<tr>
<td><img src="images/imageTH03.jpg" alt="Test Image 3" onClick="showImg(3)"></td>
</tr>
<tr>
<td><hr></td>
</tr>
<tr>
<td><img src="images/imageTH04.jpg" alt="Test Image 4" onClick="showImg(4)"></td>
</tr>
<tr>
<td><hr></td>
</tr>
<tr>
<td><img src="images/imageTH05.jpg" alt="Test Image 5" onClick="showImg(5)"></td>
</tr>
<tr>
<td><hr></td>
</tr>
<tr>
<td><img src="images/imageTH06.jpg" alt="Test Image 6" onClick="showImg(6)"></td>
</tr>
<tr>
<td><hr></td>
</tr>
<tr>
<td><img src="images/imageTH07.jpg" alt="Test Image 7" onClick="showImg(7)"></td>
</tr>
<tr>
<td><hr></td>
</tr>
</table>
</div>
<!-- end of thumbs-->
</body>
</html>[/CODE]
[CODE]<!-- Thumbnail Area-->
<div id="thumb_frame">
<table id="item">
<?php
$numImages = 7;
for ($i=1; $i<=$numImages; $i++){
if ($i < 10){ $j = "0$i"; }
echo "<tr>";
echo "<td><img src='images/imageTH$j.jpg' alt='Test Image $i' onClick='showImg($i)'></td>";
echo "</tr>";
echo "<tr>";
echo "<td><hr></td>";
echo "</tr>";
}
?>
</table>
</div>
<!-- end of thumbs-->[/CODE]
[CODE]
function showImg(myShow) {
if (!DHTML) return;
curImg = myShow;
if ( curImg < 0 ) curImg = images.length-1;
else
if ( curImg >= images.length ) curImg = 0;
if ( fadeOn ) {
firstFade = true;
prepLyr(images[lastImg], true );
fadeLayer(images[lastImg], 10, 50);
} else {
visib(images[lastImg], false);
visib(images[curImg], true);
}
lastImg = curImg;
}
[/CODE]
0.1.9 — BETA 5.26