When working with SVG, if you are using <object>
to embed the SVG code in the HTML, you must create a listener and use handlers to write functions that effect the SVG.
Some background at the goal of this work: Get the SVG to change based on what floor level the user selects. The text (room numbers) change, as well as colors. I wish to acheive this simply by adding the elements for each floor, and hiding all but the first floor on the start. When the second floor is selected, all of the first floor elements that aren't shared with the second floor are hidden, and all the second floor elements are shown.
You can view the work in progress here: http://zadias.me/SVG/Monroe%20Jefferson/MonroeJeff.html
Here is my Javascript (only partial);
var a = document.getElementById("theSVG");
//it's important to add an load event listener to the object, as it will load the svg doc asynchronously
a.addEventListener("load",function(){
var svgDoc = theSVG.contentDocument; //get the inner DOM of the SVG object
var Quads = svgDoc.getElementById("Quads"); //get the inner element by id
var Doubles = svgDoc.getElementById("Doubles");
var Triples = svgDoc.getElementById("Triples");
var Singles = svgDoc.getElementById("Singles");
var Utility = svgDoc.getElementById("Utility");
var floor1 = new Array(svgDoc.getElementsByClassName("floor1").length);
var floor2 = new Array(svgDoc.getElementsByClassName("floor2").length);
var floor3 = new Array(svgDoc.getElementsByClassName("floor3").length);
/*
for (i =0 ; i < svgDoc.getElementsByClassName("floor1").length ; i++) {
alert(svgDoc.getElementsByClassName("floor1")[i]);
}
*/
for (i = 0 ; i < svgDoc.getElementsByClassName("floor1").length ; i++) {
floor1[i] = svgDoc.getElementsByClassName("floor1")[i];
}
for (i = 0 ; i < svgDoc.getElementsByClassName("floor2").length ; i++) {
floor2[i] = svgDoc.getElementsByClassName("floor2")[i];
}
for (i = 0 ; i < svgDoc.getElementsByClassName("floor3").length ; i++) {
floor3[i] = svgDoc.getElementsByClassName("floor3")[i];
}
var floor1toggle = svgDoc.getElementById("f1");
var floor2toggle = svgDoc.getElementById("f2");
var floor3toggle = svgDoc.getElementById("f3");
/*
for (i =0 ; i < floor1.length ; i++) {
alert(floor1[i]);
}
*/
Quads.addEventListener("click",QuadsClick,false); //add behaviour
Quads.addEventListener("mouseover",QuadsHover,false);
Quads.addEventListener("mouseout",QuadsOut,false);
Doubles.addEventListener("click",DoublesClick,false);
Doubles.addEventListener("mouseover",DoublesHover,false)
Doubles.addEventListener("mouseout",DoublesOut,false);
Triples.addEventListener("click",TriplesClick,false);
Triples.addEventListener("mouseover",TriplesHover,false);
Triples.addEventListener("mouseout",TriplesOut,false);
Singles.addEventListener("click",SinglesClick,false);
Singles.addEventListener("mouseover",SinglesHover,false);
Singles.addEventListener("mouseout",SinglesOut,false);
Utility.addEventListener("click",UtilityClick,false);
Utility.addEventListener("mouseover",UtilityHover,false);
Utility.addEventListener("mouseout",UtilityOut,false);
floor1toggle.addEventListener("click",showFloor1,false);
floor2toggle.addEventListener("click",showFloor2,false);
floor3toggle.addEventListener("click",showFloor3,false);
},false);
///////////////// Floor Selection///////////////////////////
function showFloor1() {
for (i = 0 ; i < floor1.length ; i++) {
floor1[i].style.display='inline';
}
for (i = 0 ; i < floor2.length ; i++) {
floor2[i].style.display='none';
}
for (i = 0 ; i < floor3.length ; i++) {
floor3[i].style.display='none';
}
alert("floor2 should show");
}
function showFloor2() {
for (i = 0 ; i < floor1.length ; i++) {
floor1[i].style.display='none';
}
for (i = 0 ; i < floor2.length ; i++) {
floor2[i].style.display='inline';
}
for (i = 0 ; i < floor3.length ; i++) {
floor3[i].style.display='none';
}
alert("floor2 should show");
}
function showFloor3() {
for (i = 0 ; i < floor1.length ; i++) {
floor1[i].style.display='none';
}
for (i = 0 ; i < floor2.length ; i++) {
floor2[i].style.display='none';
}
for (i = 0 ; i < floor3.length ; i++) {
floor3[i].style.display='inline';
}
alert("floor3 should show");
}
And in my SVG file, I have several object classes (be it a path, rect, text) labeled as "floorX" (X being 1, 2, or 3).
I can't seem to get this to work, I've done some debugging, if you notice the for loops that are commented out, and the alert message gives out all of the things that are classified as "floor1" so I'm sure the NodeList has everything I need in it.
The alert function calls in the showFloorX() functions are not being called.. could it be my iteration is bad? I tried it without iteration, simply like so:
function showFloor1() {
floor1[i].style.display='inline';
floor2[i].style.display='none';
floor3[i].style.display='none';
alert("floor2 should show");
}
but still, no cigar.
Is there an alternative route I could go about doing this? Maybe .style.display isn't what I need?
Thanks!
EDIT:I think my problem is here:
var floor1toggle = svgDoc.getElementById("f1");
var floor2toggle = svgDoc.getElementById("f2");
var floor3toggle = svgDoc.getElementById("f3");
In the SVG file, the ID to the buttons 1 2 and 3 on the map are f1 f2 and f3 respectively.
The only reason why nothing occurs when 1 2 and 3 are clicked, I think, is that the floorXtoggle isn't attached properly to the ID, because it is externally in the SVG.
It works when selecting Doubles Triples Singles etc.. which is what's throwing me off..
Thanks again.
EDIT: While looking in the JS debugger in chrome, I've noticed that I get an Uncaught Reference Error: "Uncaught ReferenceError: floor1 is not defined".
But floor1 clearly exists when I run:
for (i =0 ; i < svgDoc.getElementsByClassName("floor1").length ; i++) {
alert(svgDoc.getElementsByClassName("floor1")[i]);
}
So what I can deduct from this is that the array/nodelist of "floor1" is out of scope when being called upon in the functions?
EDIT:
The problem seems to be as @Shvetusya stated, the arrays aren't in the same scope as my functions that are called on click. I've noticed that adding empty arrays var floor1, floor2, floor3 = new Array()
cause the floor1 to remain undefined. Most fault is likely to be instilled in my callback functions, which I'm not sure I did right..
var a = document.getElementById("theSVG");
var floor1, floor2, floor3 = new Array(); //define arrays
alert(floor1); //debug, tells me that floor1 is "undefined"..
//it's important to add an load event listener to the object, as it will load the svg doc asynchronously
a.addEventListener("load",function(){
var svgDoc = theSVG.contentDocument; //get the inner DOM of the SVG object
var Quads = svgDoc.getElementById("Quads"); //get the inner element by id
var Doubles = svgDoc.getElementById("Doubles");
var Triples = svgDoc.getElementById("Triples");
var Singles = svgDoc.getElementById("Singles");
var Utility = svgDoc.getElementById("Utility");
var floor1toggle = svgDoc.getElementById("f1");
var floor2toggle = svgDoc.getElementById("f2");
var floor3toggle = svgDoc.getElementById("f3");
Quads.addEventListener("click",QuadsClick,false); //add behaviour
Quads.addEventListener("mouseover",QuadsHover,false);
Quads.addEventListener("mouseout",QuadsOut,false);
Doubles.addEventListener("click",DoublesClick,false);
Doubles.addEventListener("mouseover",DoublesHover,false);
Doubles.addEventListener("mouseout",DoublesOut,false);
Triples.addEventListener("click",TriplesClick,false);
Triples.addEventListener("mouseover",TriplesHover,false);
Triples.addEventListener("mouseout",TriplesOut,false);
Singles.addEventListener("click",SinglesClick,false);
Singles.addEventListener("mouseover",SinglesHover,false);
Singles.addEventListener("mouseout",SinglesOut,false);
Utility.addEventListener("click",UtilityClick,false);
Utility.addEventListener("mouseover",UtilityHover,false);
Utility.addEventListener("mouseout",UtilityOut,false);
floor1toggle.addEventListener("click",showFloor1,false);
floor2toggle.addEventListener("click",showFloor2,false);
floor3toggle.addEventListener("click",showFloor3,false);
/////////callback functions, go back and change the array, NOT WORKING??
var arraySet1 = function() {
floor1.concat(svgDoc.getElementsByClassName("floor1").length);
for (i = 0 ; i < svgDoc.getElementsByClassName("floor1").length ; i++) {
floor1[i] = svgDoc.getElementsByClassName("floor1")[i];
}
}
var arraySet2 = function() {
floor2.concat(svgDoc.getElementsByClassName("floor2").length);
for (i = 0 ; i < svgDoc.getElementsByClassName("floor2").length ; i++) {
floor2[i] = svgDoc.getElementsByClassName("floor2")[i];
}
}
var arraySet3 = function() {
floor3.concat(svgDoc.getElementsByClassName("floor3").length);
for (i = 0 ; i < svgDoc.getElementsByClassName("floor3").length ; i++) {
floor3[i] = svgDoc.getElementsByClassName("floor3")[i];
}
}
floor1toggle.addEventListener("DOMContentLoaded",arraySet1,false);
floor2toggle.addEventListener("DOMContentLoaded",arraySet2,false);
floor3toggle.addEventListener("DOMContentLoaded",arraySet3,false);
alert(floor1); //still undefined
alert(floor2); //still undefined
alert(floor3); //still undefined
},false);
///////////////// Floor Selection///////////////////////////
function showFloor1() {
for (i = 0 ; i < floor1.length ; i++) {
floor1[i].show;
}
for (i = 0 ; i < floor2.length ; i++) {
floor2[i].hide;
}
for (i = 0 ; i < floor3.length ; i++) {
floor3[i].hide;
}
alert("floor2 should show");
}
function showFloor2() {
for (i = 0 ; i < floor1.length ; i++) {
floor1[i].hide;
}
for (i = 0 ; i < floor2.length ; i++) {
floor2[i].show;
}
for (i = 0 ; i < floor3.length ; i++) {
floor3[i].hide;
}
alert("floor2 should show");
}
function showFloor3() {
for (i = 0 ; i < floor1.length ; i++) {
floor1[i].hide;
}
for (i = 0 ; i < floor2.length ; i++) {
floor2[i].hide;
}
for (i = 0 ; i < floor3.length ; i++) {
floor3[i].show;
}
alert("floor3 should show");
}