Thr*_*did 5 html javascript jquery svg dom
我有一个SVG地图,我使用JQUERY Ajax嵌入到html内联.然后我使用java脚本来处理svg对象中的许多元素,以更改属性并根据数据系列添加事件侦听器.数据和地图是互动的.用户可以通过多种排列来改变状态.
我也在使用JQUERY UI 1.10.3标签
有很多类别.因此,根据演示文稿,可能在同一个选项卡上有多个svg地图副本,并且许多不同的选项卡具有相同的svg地图.
svg文档的每个副本都具有相同的元素ID.我遇到的问题是元素ID在HTML DOM中相互冲突.因此,唯一可寻址的元素是svg对象中首先出现在HTML文档中的元素.
我是否需要为svg对象的每个实例创建唯一的元素ID?或者有没有办法在HTML DOM中为svg对象设置范围和上下文?
每个包含div的都有一个唯一的ID,我用它来插入svg文档并检索SVG文档.
<div id="svgMap_div_1" class="cIG" style="height: 500px; width: 750px"></div>
Run Code Online (Sandbox Code Playgroud)
用于加载从ajax(mimeType ="image/svg + xml")接收的svg文档的代码:
document.getElementById('svgMap_div_1').appendChild(svgXMLObject.documentElement)
Run Code Online (Sandbox Code Playgroud)
用于检索svg文档的代码.svgDoc的声明是它实现的函数的本地声明,并且是唯一的.
var svgDoc = document.getElementById('svgMap_div_1').ownerDocument;
Run Code Online (Sandbox Code Playgroud)
用于更新各个元素的代码.当相同的svg对象(子元素具有相同的ID)位于同一个HTML DOM中时,这个javascript将始终寻址首先出现在HTML DOM中的svg对象,即使它是从离散div中检索的,例如id =' svgMap_div_2' .
var svgElem = svgDoc.getElementById('elemID');
svgElem.setAttribute("fill", '#0000FF');
Run Code Online (Sandbox Code Playgroud)
我相信问题的根源是使用ownerDocument检索svgDoc.它不是创建具有范围和上下文的离散对象,而是遍历整个DOM,以便DOM是上下文.请参阅IDE中的代码参考:
HTMLDocument Node.ownerDocument
Property ownerDocument http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
See Also:
Document
Since:
Standard ECMA-262 3rd. Edition
Level 2 Document Object Model Core Definition.
@type
Document
Run Code Online (Sandbox Code Playgroud)
如果必须的话,我可以开发一个工作算法来使所有的id都是唯一的,但我确实想找到更好的方法.我已经尝试了其他方法和属性来获得一个有效的svg文档对象,但这些都不适用于我.
下面是一个工作示例,用于演示当两个svg对象位于同一页面上的不同div中时会发生什么.所有四种组合都会改变第一个矩形的颜色.如果您将第二个对象中的rect的ID更改为"box-b"并相应地对其进行寻址('bbox_div','box-b'),则两个矩形将彼此独立地操作.
<script type='text/javascript'>
function colorBox(divID, svgElem, colorHex) {
/* DOM This is the original solution that did not work !!!*/
// var svgDoc = document.getElementById(divID).ownerDocument.
// var svgBox = svgDoc.getElementById(svgElem);
// svgBox.setAttribute("fill", colorHex);
/* querySelector */
// document.querySelector("#"+divID + " ."+svgElem).setAttribute("fill", colorHex);
/* jquery div */
// var svgBox = $('#'+divID+' svg').find('#'+svgElem);
// svgBox.css("fill", colorHex);
/* jquery class */
$('#'+divID+' svg').find('.'+svgElem).css("fill", colorHex);
}
</script>
<div style="height: 100px; width: 100px">
<a href="#" onclick="colorBox('abox_div', 'box-a', '#FF0000');return false;">Box A Red</a><br>
<a href="#" onclick="colorBox('abox_div', 'box-a', '#0000FF');return false;">Box A Blue</a><br>
<a href="#" onclick="colorBox('bbox_div', 'box-a', '#FF0000');return false;">Box B Red</a><br>
<a href="#" onclick="colorBox('bbox_div', 'box-a', '#0000FF');return false;">Box B Blue</a><br -->
</div>
<div id="abox_div" style="height: 100px; width: 100px">
<svg xmlns="http://www.w3.org/2000/svg"
width="0.990919in"
height="0.597218in"
viewBox="0 0 71.3461 42.9997">
<style type="text/css">
<![CDATA[
.allboxes {fill:#00FF00}
]]>
</style>
<g class="box-a allboxes" transform="translate(0.24,-0.24)" fill="#e8eef7">
<rect x="0" y="0.48" width="70.8661" height="42.5197" ><title>Box A</title></rect>
</g>
</svg>
</div>
<div id="bbox_div" style="height: 100px; width: 100px">
<svg xmlns="http://www.w3.org/2000/svg"
width="0.990919in"
height="0.597218in"
viewBox="0 0 71.3461 42.9997">
<g class="box-a allboxes" transform="translate(0.24,-0.24)" fill="#e8eef7">
<rect x="0" y="0.48" width="70.8661" height="42.5197" ><title>Box B</title></rect>
</g>
</svg>
</div>
Run Code Online (Sandbox Code Playgroud)
我认为严格来说,如果您有重复的 ID,则它是无效的 HTML。我建议使用其他一些机制来识别元素,或者使用类而不是 ID 或data-
属性。然后你可以从.getElemntById()
以下任一位置移动.querySelector()
(尝试使用 JS Bin):
<html>
<head>
<title></title>
</head>
<body>
<div id="div1">
<svg xmlns="http://www.w3.org/2000/svg" width="50px" height="50px">
<rect class="rect1" width="50px" height="50px"/>
</svg>
</div>
<div id="div2">
<svg xmlns="http://www.w3.org/2000/svg" width="50px" height="50px">
<rect class="rect1" width="50px" height="50px"/>
</svg>
</div>
<script type="text/javascript">
document.querySelector("#div1 .rect1").setAttribute("fill","red");
document.querySelector("#div2 .rect1").setAttribute("fill","green");
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
或.getElementsByClassName()
(尝试 JS Bin):
<html>
<head>
<title></title>
</head>
<body>
<div id="div1">
<svg xmlns="http://www.w3.org/2000/svg" width="50px" height="50px">
<rect class="rect1" width="50px" height="50px"/>
</svg>
</div>
<div id="div2">
<svg xmlns="http://www.w3.org/2000/svg" width="50px" height="50px">
<rect class="rect1" width="50px" height="50px"/>
</svg>
</div>
<script type="text/javascript">
document.getElementById("div1").getElementsByClassName("rect1")[0].setAttribute("fill","red");
document.getElementById("div2").getElementsByClassName("rect1")[0].setAttribute("fill","green");
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
如果您保留 ID 属性不变,可能.querySelector()
也会起作用,例如:
document.querySelector("#div1 [id=rect1]")
Run Code Online (Sandbox Code Playgroud)
但我仍然建议使用data-
属性,因为这可以避免任何潜在的 ID 陷阱。