2

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");    
        } 

I would like to recommend to take a look at the new project RioFS (Userspace S3 filesystem): https://github.com/skoobe/riofs. This project is “s3fs” alternative, the main advantages comparing to “s3fs” are: simplicity, the speed of operations and bugs-free code. Currently the project is in the “testing” state, but it's been running on several high-loaded fileservers for quite some time.

We are seeking for more people to join our project and help with the testing. From our side we offer quick bugs fix and will listen to your requests to add new features.

Hope it helps you and we are looking forward to seeing you joined our community !

4

1 回答 1

0

我认为问题在于floor1,floor2floor3是在您的匿名回调函数范围内定义的,因此它们超出了showFloor1().

var a =在定义为空数组后尝试定义它们,然后在回调中添加到数组中addEventListener

于 2013-07-17T18:59:04.940 回答