Question

I would like to achieve the same effect found on the following website:

http://www.kpf.com/projectlist.asp?T=4

On mouseover of an image, the corresponding text highlights and vice versa.

I've found a JavaScript solution on a forum. I've copy-pasted the solution below:

div code

<div style="width:400;height:500;" onmouseover="hightlight()" onmouseout="removehightlight()"><span id="textspan" >This is a test div to show mouseover</span><img id="imgsrc" src="/images/test.gif" /></div>

javascript

<script language="javascript">
function hightlight() 
{   
document.getElementById("textspan").style.color = "blue";
document.getElementById("imgsrc").style.border = "1px solid blue";
//document.getElementById("textspan").setStyle("color","blue");
//document.getElementById("imgsrc").setStyle("border","1px solid blue");
}
function removehightlight() 
{
document.getElementById("textspan").style.color = "black";
document.getElementById("imgsrc").style.border = "0px solid blue";
}    
</script>

However, this solution is for an image and text in the same div. My image and text reside in two separate divs like so:

javascript

function hightlight() 
{
document.getElementById("textspan").style.text = "underline";
document.getElementById("imgsrc").style.border = "5px solid #005596";
}
function removehightlight() 
{
document.getElementById("textspan").style.text = "none";
document.getElementById("imgsrc").style.border = "5px solid white";
}

text

<div id="left-menu" >
<div align="right">
<p><!-- #BeginLibraryItem "/Library/left-projects-category.lbi" --> <span class="left-title">Category</span><!-- #EndLibraryItem --><br />
<span class="left-sub">Residential</span><br />
<a href="#" class="btn-list"><span id="textspan" onmouseover="hightlight()" onmouseout="removehightlight()">11 Gurney Drive</span><br /></a>
<a href="#" class="btn-list"><span id="textspan" onmouseover="hightlight()" onmouseout="removehightlight()">78 LAD</span><br /></a>
</p>
</div>
</div>

image

<div style="float:left; margin:90px 0 0 305px; padding:0 0 100px 0; height:auto;">
<img src="../../images/completed-projects/thumbnails/11-gurney-drive.jpg" width="215" height="170" id="imgsrc" style="border:5px solid white" onmouseover="hightlight()" onmouseout="removehightlight()"/>
<img src="../../images/completed-projects/thumbnails/78-lad.jpg" width="215" height="171" id="imgsrc" style="border:5px solid white" onmouseover="hightlight()" onmouseout="removehightlight()"/>
/div>

MY PROBLEMS

Let's call 11 Gurney Drive - Text1 and 11-gurney-drive.jpg - Image1
78 LAD - Text2 and 78-lad.jpeg - Image2.

My problems:

On Text1 mouseover, it highlights both Text1 and Image1 - Good.
On Text2 mouseover, it highlights Text2 and Image1 - it should highlight Text2 and Image2.
On Image1 mouseover, it highlights only Image1 - it should highlight Text1 and Image1.
On Image2 mouseover, it highlights only Image1 - it should highlight Text2 and Image2.

I have very little experience in customising Javascript; have tried Googling getElementbyId but it all might as well be in Greek.

Edit

I forgot to mention that I've tried adding a 2nd unique element ID called textspan2 and imgsrc2 but that didn't seem to work. What I did:

javascript

function hightlight() 
{
document.getElementById("textspan").style.text = "underline";
document.getElementById("imgsrc").style.border = "5px solid #005596";
document.getElementById("textspan2").style.text = "underline";
document.getElementById("imgsrc2").style.border = "5px solid #005596";
}
function removehightlight() 
{
document.getElementById("textspan").style.text = "none";
document.getElementById("imgsrc").style.border = "5px solid white";
document.getElementById("textspan2").style.text = "none";
document.getElementById("imgsrc2").style.border = "5px solid white";
}

text

<div id="left-menu" >
<div align="right">
<p><!-- #BeginLibraryItem "/Library/left-projects-category.lbi" --> <span class="left-title">Category</span><!-- #EndLibraryItem --><br />
<span class="left-sub">Residential</span><br />
<a href="#" class="btn-list"><span id="textspan" onmouseover="hightlight()" onmouseout="removehightlight()">11 Gurney Drive</span><br /></a>
<a href="#" class="btn-list"><span id="textspan2" onmouseover="hightlight()" onmouseout="removehightlight()">78 LAD</span><br /></a>
</p>
</div>
</div>

image

<div style="float:left; margin:90px 0 0 305px; padding:0 0 100px 0; height:auto;">
<img src="../../images/completed-projects/thumbnails/11-gurney-drive.jpg" width="215" height="170" id="imgsrc" style="border:5px solid white" onmouseover="hightlight()" onmouseout="removehightlight()"/>
<img src="../../images/completed-projects/thumbnails/78-lad.jpg" width="215" height="171" id="imgsrc2" style="border:5px solid white" onmouseover="hightlight()" onmouseout="removehightlight()"/>
/div>
Was it helpful?

Solution

getElementById is one of those calls that actually does what it says. :-) It gets a DOM element by its id attribute. Since id must be unique, it gets you one specific element that you can then interact with (for instance, setting its style properties).

So part of your problem is that you have two elements with the ID "textspan", and two elements with the ID "imgsrc", which means the browser will do something undefined because you can't do that.

Within an event handler, this will point to the element that you've put the handler on. So in your highlight and removeHighlight functions, you can use this (rather than getElementById) to get a reference to the img DOM elements. That just leaves the text ones.

You could use a naming convention ("textspan1" and "imgsrc1", "textspan2" and "imgsrc2" for instance), so the handlers would look like this:

function hightlight() 
{   
    var textid = this.id.replace("imgsrc", "textspan");
    var text = document.getElementById(textid);

    text.style.color = "blue";
    this.style.border = "1px solid blue";
}
function removehightlight() 
{
    var textid = this.id.replace("imgsrc", "textspan");
    var text = document.getElementById(textid);

    text.style.color = "black";
    this.style.border = "0px solid blue";
}  

...or you might use an attribute (say, data-text) on the img tags that gives the ID of the text field linked to it; you can get an attribute from a DOM element like this:

var textid = this.getAttribute("data-text");

Custom attributes are invalid in HTML4 and below, but I've never met a browser that had a problem with them. In HTML5 and above, you can have custom attributes as long as they start with data- as above. So if validation is part of your working practices (and it's usually a good idea), you might consider starting to use the HTML5 doctype unless you have a particular reason for staying with the previous one (like, for instance, you're uncomfortable using a doctype for a version of HTML5 that hasn't even reached candidate recommendation stage yet). A lot of us are happy enough to go ahead now.

this is not the element the way you're hooking up the handlers. I'd forgotten, it's been a long time since I used the DOM0 way of hooking up handlers (onmouseover=). But the below works:

Or, because of the way you're attaching the handlers, you could pass an argument into the functions telling them which one they're dealing with:

function hightlight(index) 
{   
    var img  = document.getElementById("imgsrc" + index);
    var text = document.getElementById("textspan" + index);

    text.style.color = "blue";
    img.style.border = "1px solid blue";
}
function removehightlight(index) 
{
    var img  = document.getElementById("imgsrc" + index);
    var text = document.getElementById("textspan" + index);

    text.style.color = "black";
    img.style.border = "0px solid blue";
}  

...where your onmouseover and onmouseout attributes changes to:

onmouseover="hightlight(1);" onmouseout="removehightlight(1);"
onmouseover="hightlight(2);" onmouseout="removehightlight(2);"

Here's a live example.

Side note: The code you've found is using the mouseover and mouseout events. Be aware that those don't quite do what you may expect they do, and it can bite you, although the specific way you're using them is mostly fine (you're doing more work than necessary, but that's okay). But suppose your markup changed a little:

<a href="#" class="btn-list"><span id="textspan" onmouseover="hightlight()" onmouseout="removehightlight()">11 <strong>Gurney</strong> Drive</span><br /></a>

Now there's an element within the span that you're watching those events on. That means that as the user's mouse travels from left-to-right, you'll see a series of mouseover events as the mouse travels over the text "11(space)", then your code will see a mouseout event as the mouse moves over into the word "Gurney". Why does this happen? Because the mouse has moved out of the span and into the strong element. Then it will immediately see another mouseover, because the mouse is moving over the strong element and the mouseover event bubbles up the DOM, so we see it on the span. This may cause flicker as the mouse moves into and out of the strong element.

Internet Explorer has the mouseenter and mouseleave events, which are more suited to what you're doing — but who wants to use events that are limited to only one brand of browser? Well, most good JavaScript libraries emulate these events even on browsers that don't support them natively, which brings me to...

Off-topic 1:

If you're just starting out with JavaScript on browsers, a word of warning: There are a number of browser inconsistencies and awkwardnesses (if that's a word) that libraries like jQuery, Prototype, YUI, Closure, or any of several others can smooth over for you. For what you're doing in this question, enh, they wouldn't bring a huge amount of value. But for more complicated stuff, they can save you a lot of time and trouble, leveraging the good work many others have done before you. Like, for instance, emulating mouseenter and mouseleave on browsers that don't support them. :-) I know for a fact both jQuery and Prototype do that for you, and I suspect others do as well.

Off-topic 2:

It's "highlight", not "hightlight". If someone needs to come maintain your code later, that typo (which is consistent, and so not a bug!) might well trip them up. Separately, the standard practice (which you're free to ignore!) is to camelCase words in function names, so removeHighlight rather than removehightlight. FWIW.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top