0

I'm a novice having problems with a program. The HTM has coordinates for a picture displayed on the website, and a seperate Javascript file named brain.js to display the text when the picture is mouseover. There are four quadrants and four sets of title and summary remarks to display. The idea is to mouse over a coord, whiel holding the mouse over the area, a window displays information about the area, then move over another area the original display clears and a new display is shown.

Most of my code works but I'm having trouble with the setupFrame Function transferring the index from my setupFrame function to the writeFrame function and cycling as the mouse is moved to a different coordinate on the picture, can anyone tell me how to do this?

Here is my Script file:

function addEvent(object, evName, fnName, cap) {  
   if (object.attachEvent)   
       object.attachEvent("on" + evName, fnName);  
   else if (object.addEventListener)   
       object.addEventListener(evName, fnName, cap);  
}

addEvent(window, "load", setupFrame, false);  
var index;  
var allAreas = new Array();    
function setupFrame() {  
   allAreas = document.getElementsByTagName("area");  
   for (var i = 0; i < allAreas.length; i++) {  
      addEvent(allAreas[i], "mouseover", writeFrame);  
      addEvent(allAreas[i], "mouseout", clearFrame);  
      allAreas.index = [i];  

   }  
}

function writeFrame() {

var areaIndex = this.index;  
   var frameWin = document.getElementById("parts");  
   var frameDoc = frameWin.contentWindow.document;  
   frameDoc.getElementById("docTitle").innerHTML = title[areaIndex];  
   frameDoc.getElementById("docSummary").innerHTML = summary[areaIndex];  
}

function clearFrame() {  
   var areaIndex = this.index;  
   var frameWin = document.getElementById("parts");  
   var frameDoc = frameWin.contentWindow.document;  
   frameDoc.getElementById("docTitle").innerHTML = "";  
   frameDoc.getElementById("docSummary").innerHTML = "";  
}
Bmcc
  • 3
  • 4
  • Use code tags and avoid paragraphs that never end. I edited your post so it is more readable. – epascarello Dec 18 '10 at 13:16
  • Thanks epascarello, Like I said <--- Novice. Any thoughts on how to get the index to recycle when I move the mouse? From what I can tell it's looking for a numeric value from 0 - 3, I know because I hard coded areaIndex in the title and summary portion and got it to display what I needed. – Bmcc Dec 18 '10 at 13:21

3 Answers3

0

Do you realize that allAreas.index = [i]; is making an array and you are treating it as an integer when you read it. I think you want to drop the [ and ] so it looks like allAreas.index = i;.

Also you are not writing to the whole group when you set the index and not the individual area elements.

allAreas.index = [i];

should be

allAreas[i].index = i;
epascarello
  • 204,599
  • 20
  • 195
  • 236
  • I did that but I'm just getting "undefined" as my output. – Bmcc Dec 18 '10 at 13:25
  • Did you apply the changes suggested above? In the loop, alert allAreas[i] and allAreas[i].index at the very end. – andrej_k Dec 18 '10 at 13:50
  • ok, lets try that again. First, change to allAreas[i].index = i; and then alert allAreas.index at the end of the loop – andrej_k Dec 18 '10 at 13:58
  • on the alert(allAreas[i]); I got "#", and I got 0, 1, 2, 3 on the alert(allAreas.index); – Bmcc Dec 18 '10 at 14:01
  • alert(allAreas.index); or alert(allAreas[i].index); ? – andrej_k Dec 18 '10 at 14:02
  • I didn't put the index bracket on the alert, does that do something? – Bmcc Dec 18 '10 at 14:06
  • yes, references the element the mouseover is attached to, instead of the array holding all elements. Re-read the above answer carefully and make sure you apply the suggested change. – andrej_k Dec 18 '10 at 14:10
  • When I dropped the braket off the i, I got the same alert output, 0, 1, 2, 3. – Bmcc Dec 18 '10 at 14:12
  • oh and by adding "allAreas[i].index = i" causes undefined four times. – Bmcc Dec 18 '10 at 14:14
  • ok, and when you do allAreas[i].index = i; alert(allAreas[i].index); – andrej_k Dec 18 '10 at 14:18
  • I get "undefined" four times. – Bmcc Dec 18 '10 at 14:21
  • can you post your loop here again? – andrej_k Dec 18 '10 at 14:25
  • function setupFrame() { allAreas = document.getElementsByTagName("area"); for (var i = 0; i < allAreas.length; i++) { allAreas.index = i; addEvent(allAreas[i], "mouseover", writeFrame); addEvent(allAreas[i], "mouseout", clearFrame); alert(allAreas[i].index); } } – Bmcc Dec 18 '10 at 14:27
  • you still have allAreas.index = i; instead of allAreas[i].index = i; – andrej_k Dec 18 '10 at 14:29
  • Ok once I changed allAreas[i].index = i; I got 0, 1, 2, 3. in the alert. – Bmcc Dec 18 '10 at 14:30
  • I checked and I'm still getting "undefined in the window for both title and summary. There are two HTM files, two css files and two js files plus a jpeg file in this Webpage. would it help if I emailed the files to you? – Bmcc Dec 18 '10 at 14:34
  • The iframe.js and brain.htm files are the only two file I can modify. – Bmcc Dec 18 '10 at 14:47
  • o, let me take a look - [redacted] – andrej_k Dec 18 '10 at 15:03
0

I think epascarello identified the bug, but I still want to point out another way of passing the index in, using a closure:

var index = i;
addEvent(allAreas[i], "mouseover", function() {writeFrame(index);});

Check out this SO post about closures in javascript

Edit: as epascarello pointed out, due to lack of block scope, this won't work, and index will always point to the same variable, which will in the end always have allAreas.length for its value. There are ways of fixing this, but the original approach is probably simpler in this case.

Community
  • 1
  • 1
andrej_k
  • 481
  • 4
  • 7
  • This will fail since the `i` in the closure will be equal to `allAreas.length` when it is done. – epascarello Dec 18 '10 at 13:26
  • That doesn't seem to change the fact that I keep getting undefined in my output. I didn't see a change in any of the operation. – Bmcc Dec 18 '10 at 13:29
  • alert yourself with the areaIndex from the writeFrame method - what do you get? – andrej_k Dec 18 '10 at 13:34
  • adding the var index = i; doesn't help, my problem isn't in getting the mouseove to work, it's when I change from one coordinate in the HTM file to another coordinate. my alert(areaIndex); shows 3, and doesn't change as I move the mouse around to another zone. – Bmcc Dec 18 '10 at 13:38
  • I got "Undefined from my Alert this time. – Bmcc Dec 18 '10 at 13:46
  • Yeah, that's a symptom of the problem epascarello pointed out. It is fixable, but probably overkill. Your original approach is better. Let's troubleshoot that - what do you get when you alert yourself with areaIndex using the first approach? – andrej_k Dec 18 '10 at 13:49
  • I did four if statements and four writeFrames, – Bmcc Dec 18 '10 at 13:49
  • if (allAreas.index == 0) { addEvent(allAreas[i], "mouseover", writeFrame0; } – Bmcc Dec 18 '10 at 13:51
  • in answer to your question on my first approach; I get "undefined" on my alert. – Bmcc Dec 18 '10 at 13:52
  • That will make it work for 4 areas. We can make the other approach work though. – andrej_k Dec 18 '10 at 13:53
  • see my questions in the other answer – andrej_k Dec 18 '10 at 13:54
0

Your code (with the fix by epascarello) works in chrome, but not IE.

The problem is here:

var areaIndex = this.index;

Using addEventListener, the handler function gets added to the element, so the this variable points to it and your code does what you expect.

However, in IE, using attachEvent, it doesn't, and the this variable now points to the window object.

Luckily, both approaches pass in an event object to the handler, which has a pointer to the source element.

So, you need to do 2 things.

First, accept the event as a param to the handler function:

function writeFrame(event) 

Then, use it to get the source element, instead of using this.

var areaIndex = event.srcElement.index;
andrej_k
  • 481
  • 4
  • 7
  • I tried the event.srcElement.index; but didn't use the function writeFrame(event), guess I skipped that part of the book. – Bmcc Dec 18 '10 at 16:09