我正在尝试操纵svg
内的元素(例如圆圈或路径)。我需要动态创建它们并能够识别它们。
我从一些在线示例中窃取了一些函数,并提出了以下代码(它应该在鼠标单击时在svg内部创建圆圈,并在鼠标悬停在圆圈上时创建文本标签)。但是,它没有像我预期的那样工作。当鼠标从左侧进入元素时,elementFromPoint(x, y).id
返回valid ID "circle"
,但当鼠标从右边输入元素时,它会返回它的父ID" mySVG"。
我无法在任何地方找到合适的解决方案,所以欢迎任何建议 - 事实上,我会尝试阅读svg的规格并尽可能地学习JS,但是,对我来说,这仍然是一个痛苦的过程了解这些事情。您的时间和建议非常感谢!谢谢。 ķ
JS小提琴:
https://jsfiddle.net/krisfiddle/2xc3tgdr/6/
守则
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
body, canvas, svg {position:absolute; margin:0; padding:0; border:none;}
svg {top:0; left:0;}
.circle:hover {opacity:0.5;}
</style>
</head>
<body>
<svg id="mySVG" xmlns:xlink="http://www.w3.org/1999/xlink" height="400" width="300" style="border: 1px solid black" onClick="circle()"></svg>
<script>
var w = window.innerWidth;
var h = window.innerHeight;
var x;
var y;
var color = undefined;
function handleMouseMove(event) {
var dot, eventDoc, doc, body, pageX, pageY;
event = event || window.event;
if (event.pageX == null && event.clientX != null) {
eventDoc = (event.target && event.target.ownerDocument) || document;
doc = eventDoc.documentElement;
body = eventDoc.body;
event.pageX = event.clientX +
(doc && doc.scrollLeft || body && body.scrollLeft || 0) -
(doc && doc.clientLeft || body && body.clientLeft || 0);
event.pageY = event.clientY +
(doc && doc.scrollTop || body && body.scrollTop || 0) -
(doc && doc.clientTop || body && body.clientTop || 0 );
}
x = event.pageX;
y = event.pageY;
}
document.onmousemove = handleMouseMove;
function circle() {
var myCircle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
myCircle.setAttribute('id', 'circleID');
myCircle.setAttribute('class', 'circle');
myCircle.setAttributeNS(null, "cx", x);
myCircle.setAttributeNS(null, "cy", y);
myCircle.setAttributeNS(null, "r", 50);
myCircle.setAttributeNS(null, "fill", "green");
myCircle.setAttributeNS(null, "stroke", "none");
myCircle.setAttributeNS(null, "onmouseover", "getIdXY()");
myCircle.setAttributeNS(null, "onmouseout", "deleteIdXY()");
document.getElementById("mySVG").appendChild(myCircle);
}
function getIdXY() {
var elementMouseIsOver = document.
var idMark = document.createElementNS("http://www.w3.org/2000/svg", "text");
idMark.setAttributeNS(null, "x", x);
idMark.setAttributeNS(null, "y", y);
idMark.setAttributeNS(null, "fill", "red");
idMark.setAttributeNS(null, "id", "text");
document.getElementById("mySVG").appendChild(idMark);
document.getElementById("text").innerHTML = elementMouseIsOver;
}
function deleteIdXY() {
var parent = document.getElementById("mySVG");
var child = document.getElementById("text");
parent.removeChild(child);
}
</script>
</body>
</html>
答案 0 :(得分:2)
嗯,暂时,我实施了罗伯特和马辛的两种吸烟措施。由于某种原因,我在这个特定的实现中似乎很难处理elementFromPoint(),因此我很乐意转向&#34;这个obj&#34;方法。实际上,将coords存储在全局变量中并将唯一ID赋予元素是一个好主意。认为代码不是很优雅它给了我一个很好的介绍JS和动态创建SVG。许多人都是Marcin和Robert。结果对我目前的目的而言是令人满意的,并且可以在后面的小提琴中观察到:
http://jsfiddle.net/4uu1vbzz/2/
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<svg id="mySVG" xmlns:xlink="http://www.w3.org/1999/xlink" height="400" width="300" style="border: 1px solid black"></svg>
</body>
<script>
var x, y, recentX, recentY; // stores XY mouse coordinations
var circleID = 0; // used as increment to generate unique ID for each circle
var tagID = 0; // used as increment to generate unique ID for each circle's tag
var elementMouseIsOver = ""; // stores ID of the element recently under the pointer
// get mouse coords on mouse move
var mouseMoves = function(e) {
recentX = e.clientX;
recentY = e.clientY;
}
window.onload = function() {this.addEventListener('mousemove', mouseMoves);} //event handler for mousemove coords
//create circle within svg
var draw = function draw(e) {
x = e.clientX;
y = e.clientY;
circleID = circleID + 1; //increment the number for ID
var id = "circle" + circleID; //create string to pass the ID
//place circle with ID into svg
var myCircle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
myCircle.setAttribute('id', id);
myCircle.setAttribute('class', 'circle');
myCircle.setAttributeNS(null, "cx", x);
myCircle.setAttributeNS(null, "cy", y);
myCircle.setAttributeNS(null, "r", 50);
myCircle.setAttributeNS(null, "fill", "green");
myCircle.setAttributeNS(null, "stroke", "none");
myCircle.setAttributeNS(null, "onmouseover", "tagId(this)");
myCircle.setAttributeNS(null, "onmouseout", "deleteTag()");
document.getElementById("mySVG").appendChild(myCircle);
}
document.getElementById("mySVG").addEventListener('click', draw); //event handler for onclick action
//on mouseover get the ID of the element under the pointer and create an tag marking it
function tagId(obj) {
elementMouseIsOver = obj.id;
tagID = tagID + 1;
var id = "tag" + tagID;
var idMark = document.createElementNS("http://www.w3.org/2000/svg", "text");
idMark.setAttributeNS(null, "x", recentX);
idMark.setAttributeNS(null, "y", recentY);
idMark.setAttributeNS(null, "fill", "red");
idMark.setAttributeNS(null, "id", id);
document.getElementById("mySVG").appendChild(idMark);
document.getElementById(id).innerHTML = elementMouseIsOver;
}
//remove the tag when mouse leaves the element
function deleteTag() {
var id = "tag" + tagID;
var parent = document.getElementById("mySVG");
var child = document.getElementById(id);
parent.removeChild(child);
}
</script>
</html>