使用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文件中,我有几个对象类(无论是路径、rect还是文本)标记为"floorX"(X是1、2或3)。
我似乎无法实现这一点,我已经做了一些调试,如果你注意到for循环被注释掉了,并且警报消息给出了所有被归类为"floor1"的东西,所以我确信NodeList中有我需要的一切。
showFloorX()函数中的alert函数调用未被调用。。可能是我的迭代不好吗?我尝试了它,没有迭代,就像这样:
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文件中,映射上按钮1、2和3的ID分别为f1、f2和f3。我认为,单击1 2和3时没有发生任何事情的唯一原因是floorXtoggle没有正确连接到ID,因为它在SVG的外部。
它在选择双打、三杆、单打等时有效。这让我很失望。
再次感谢。
EDIT:在chrome中查看JS调试器时,我注意到我得到了一个未捕获的引用错误:"未捕获的参考错误:floor1未定义"。
但当我跑步时,地板1显然存在:
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");
}
我认为问题在于floor1
、floor2
和floor3
是在匿名回调函数范围内定义的,因此它们不在showFloor1()
的范围内。
在将var a =
定义为空数组之后,尝试定义它们,然后在addEventListener
的回调中添加到数组中。