javascript - 使用 JS/Jquery 和 SVG 来显示/隐藏 <object> SVG 中的元素

标签 javascript jquery svg

使用 SVG 时,如果您使用 <object>要在 HTML 中嵌入 SVG 代码,您必须创建一个监听器并使用处理程序来编写影响 SVG 的函数。

这项工作的目标背景:让 SVG 根据用户选择的楼层而改变。文本(房间号)和颜色都会发生变化。我希望通过为每一层添加元素并在开始时隐藏除第一层以外的所有元素来实现这一点。选择二楼时,所有不与二楼共享的一楼元素都将隐藏,并显示所有二楼元素。

您可以在此处查看正在进行的工作:http://zadias.me/SVG/Monroe%20Jefferson/MonroeJeff.html

这是我的 Javascript(仅部分);

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

在我的 SVG 文件中,我有几个标记为“floorX”(X 为 1、2 或 3)的对象类(路径、矩形、文本)。

我似乎无法让它工作,我已经做了一些调试,如果你注意到 for 循环被注释掉了,并且警报消息给出了所有被归类为“floor1”的东西,所以我确信 NodeList 中包含我需要的一切。

没有调用 showFloorX() 函数中的警报函数调用。可能是我的迭代有问题吗?我没有迭代就试过了,就像这样:

function showFloor1() {
                floor1[i].style.display='inline';
                floor2[i].style.display='none'; 
                floor3[i].style.display='none';                 
            alert("floor2 should show"); 
        } 

但仍然没有雪茄。

有没有其他方法可以解决这个问题?也许 .style.display 不是我需要的?

谢谢!

编辑:我认为我的问题出在这里:

    var floor1toggle = svgDoc.getElementById("f1");
    var floor2toggle = svgDoc.getElementById("f2");
    var floor3toggle = svgDoc.getElementById("f3");

在SVG文件中, map 上按钮1、2、3的ID分别为f1、f2、f3。 我认为,点击 1 2 和 3 时没有任何反应的唯一原因是 floorXtoggle 没有正确附加到 ID,因为它位于 SVG 的外部。

它在选择 Doubles Triples Singles 等时起作用..这让我失望..

再次感谢。

编辑:在 chrome 中查看 JS 调试器时,我注意到我收到 Uncaught ReferenceError :“ Uncaught ReferenceError :floor1 未定义”。

但是当我运行时 floor1 显然存在:

            for (i =0 ; i < svgDoc.getElementsByClassName("floor1").length ; i++) {
                alert(svgDoc.getElementsByClassName("floor1")[i]);  
        }

那么我可以从中推断出“floor1”的数组/节点列表在函数中被调用时超出范围?

编辑:

问题似乎如@Shvetusya 所述,数组与我在单击时调用的函数不在同一范围内。我注意到添加空数组 var floor1, floor2, floor3 = new Array()导致 floor1 保持未定义状态。大多数错误很可能是在我的回调函数中灌输的,我不确定我做对了..

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

最佳答案

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

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

关于javascript - 使用 JS/Jquery 和 SVG 来显示/隐藏 <object> SVG 中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17680329/

相关文章:

javascript - C# mv5 通过链接传递参数然后在 View 中获取它

javascript - jQuery:如何在方法中获取 this 的原始值

javascript - jQuery Json 按 json 值中最高数字排序列表

jQuery - 具有多个实例的推子

svg - feColorMatrix 反转颜色的问题出在哪里?

javascript - 验证默认选择的登录链接

javascript - 创建对象时Nodejs "Unexpected token ."

javascript - 通过 JavaScript 制作 SVG 路径动画

javascript - 为什么我的 Javascript 在 IE8 中无法运行?

javascript - 使用 Raphael.js 转换为绑定(bind)框