jQuery Html5 在 svg 元素上拖放
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5864249/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Html5 drag and drop on svg element
提问by bsr
I am trying to follow the html5 drag and drop tutorial here. I could not get the dragstart
event to be registered on rect
element. If I change the event from draggable
to mousedown
it calls the handleDragStart
handler. Please ignore the additional blank registration in the code.
我正在尝试按照此处的 html5 拖放教程进行操作。我无法dragstart
在rect
元素上注册该事件。如果我将事件从 更改draggable
为mousedown
它调用handleDragStart
处理程序。请忽略代码中额外的空白注册。
JSFiddle here
JSFiddle在这里
<!DOCTYPE html>
<html><head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<style type="text/css" media="screen">
svg rect { cursor: move; }
</style>
</head><body>
<h1>SVG/HTML 5 Example</h1>
<svg id="cvs">
<rect draggable="true" x="0" y="10" width="100" height="80" fill="#69c" />
<rect x="50" y="50" width="90" height="50" fill="#c66" />
</svg>
<script type="text/javascript" src="loc.js"></script>
</body></html>
loc.js
loc.js
$(document).ready(function() {
function handleDragStart(e) {
log("handleDragStart");
this.style.opacity = '0.4'; // this ==> e.target is the source node.
};
var registercb = function () {
$("#cvs > rect").each(function() {
$(this).attr('draggable', 'true');
});
$("#cvs > rect").bind('dragstart', handleDragStart);
$(window).mousedown(function (e) {
});
$(window).mousemove(function (e) {
});
$(window).mouseup(function (e) {
log("mouseup");
});
};
function log() {
if (window.console && window.console.log)
window.console.log('[XXX] ' + Array.prototype.join.call(arguments, ' '));
};
registercb();
});
回答by Alvaro Montoro
I know this is an old question, I arrived here from this other questionthat was marked as a duplicate of this one, and wanted to add a possible solution that doesn't require jQuery or any libraries, and that works in all major browsers. It is based on this tutorialrecommended by @AmirHossein Mehrvarzi.
我知道这是一个老问题,我是从另一个问题来到这里的,这个问题被标记为这个问题的重复,并想添加一个不需要 jQuery 或任何库的可能解决方案,并且适用于所有主要浏览器。它基于@AmirHossein Mehrvarzi推荐的本教程。
This small solution doesn't use the drag events, just the mousedown
, mouseup
and mousemove
. This is how it works:
这个小解决方案不使用拖动事件,只使用mousedown
,mouseup
和mousemove
。这是它的工作原理:
- When the mouse is down on the rectangle, it saves the mouse position and the active element.
- When the mouse moves, the rectangle coordinates are updated with the new mouse position.
- When the mouse is up, it resets the active element.
- 当鼠标在矩形上按下时,它会保存鼠标位置和活动元素。
- 当鼠标移动时,矩形坐标会更新为新的鼠标位置。
- 当鼠标向上时,它会重置活动元素。
From the code in the question above:
从上面问题中的代码:
var selectedElement = null;
var currentX = 0;
var currentY = 0;
$(document).ready(function() {
function handleDragStart(e) {
log("handleDragStart");
this.style.opacity = '0.4'; // this ==> e.target is the source node.
};
var registercb = function () {
$("#cvs > rect").mousedown(function (e) {
// save the original values when the user clicks on the element
currentX = e.clientX;
currentY = e.clientY;
selectedElement = e.target;
}).mousemove(function (e) {
// if there is an active element, move it around by updating its coordinates
if (selectedElement) {
var dx = parseInt(selectedElement.getAttribute("x")) + e.clientX - currentX;
var dy = parseInt(selectedElement.getAttribute("y")) + e.clientY - currentY;
currentX = e.clientX;
currentY = e.clientY;
selectedElement.setAttribute("x", dx);
selectedElement.setAttribute("y", dy);
}
}).mouseup(function (e) {
// deactivate element when the mouse is up
selectedElement = null;
});
};
function log() {
if (window.console && window.console.log)
window.console.log('[XXX] ' + Array.prototype.join.call(arguments, ' '));
};
registercb();
});
rect { cursor: move; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h1>SVG/HTML 5 Example</h1>
<svg id="cvs">
<rect x="0" y="10" width="100" height="80" fill="#69c" />
<rect x="50" y="50" width="90" height="50" fill="#c66" />
</svg>
You can also see it on this JSFiddle: http://jsfiddle.net/YNReB/61/
你也可以在这个 JSFiddle 上看到它:http: //jsfiddle.net/YNReB/61/
If you want to add drop functionality, you can modify the mouseup
function to read the element on the cursor position (with document.elementFromPoint(e.clientX, e.clientY)
) and then you can perform actions on the original element and the one where it was dropped.
如果您想添加放置功能,您可以修改该mouseup
函数以读取光标位置上的元素(使用document.elementFromPoint(e.clientX, e.clientY)
),然后您可以对原始元素和放置它的元素执行操作。
回答by Manuel Leuenberger
This behavior may be caused by several reasons:
此行为可能由以下几个原因引起:
- HTML 5 drag and drop is a mess, according to this article. I know it's a bit older, but the issue still seems not to be solved
- jQuery does not support the SVG DOM-model. Therefore some parts of it may work, others don't (like
offset()
orwidth()
).
- 根据这篇文章,HTML 5 拖放是一团糟。我知道它有点旧,但问题似乎仍然没有解决
- jQuery 不支持 SVG DOM 模型。因此,它的某些部分可能会起作用,而其他部分则不起作用(例如
offset()
或width()
)。
I'd definitely not rely on HTML5 drag & drop support right now, but rather use a library to handle this issue. If you want to work with SVG, you could try Rapha?l. If you need jQuery too, maybe the SVG pluginis the way to go. Note that both projects are not actively developed at the moment. I know this is not really a satisfactory answer, but I had to learn too, that jQuery and SVG do not go that well together. Hopefully someone proves me wrong ;).
我现在绝对不会依赖 HTML5 拖放支持,而是使用库来处理这个问题。如果你想使用 SVG,你可以试试Rapha?l。如果您也需要 jQuery,也许SVG 插件就是您要走的路。请注意,这两个项目目前都没有积极开发。我知道这不是一个真正令人满意的答案,但我也必须学习,jQuery 和 SVG 不能很好地结合在一起。希望有人证明我错了;)。