Html5拖放到svg元素上
Posted
技术标签:
【中文标题】Html5拖放到svg元素上【英文标题】:Html5 drag and drop on svg element 【发布时间】:2015-08-28 04:28:51 【问题描述】:我正在尝试遵循 html5 拖放教程here。我无法在rect
元素上注册dragstart
事件。如果我将事件从draggable
更改为mousedown
,它将调用handleDragStart
处理程序。请忽略代码中额外的空白注册。
JSFiddle here
<!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" fill="#69c" />
<rect x="50" y="50" fill="#c66" />
</svg>
<script type="text/javascript" src="loc.js"></script>
</body></html>
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();
);
【问题讨论】:
【参考方案1】:我知道这是一个老问题,我从this other question 来到这里,它被标记为这个问题的副本,并想添加一个不需要 jQuery 或任何库的可能解决方案,并且适用于所有主流浏览器。它基于@AmirHossein Mehrvarzi推荐的this tutorial。
这个小解决方案不使用拖动事件,只使用mousedown
、mouseup
和mousemove
。它是这样工作的:
从上面问题中的代码:
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" fill="#69c" />
<rect x="50" y="50" fill="#c66" />
</svg>
你也可以在这个 JSFiddle 上看到它:http://jsfiddle.net/YNReB/61/
如果你想添加drop功能,你可以修改mouseup
函数来读取光标位置上的元素(用document.elementFromPoint(e.clientX, e.clientY)
),然后你可以对原始元素和它被丢弃的元素执行操作.
【讨论】:
【参考方案2】:这种行为可能是由多种原因引起的:
HTML 5 拖放是一团糟,according to this article。我知道它有点老,但问题似乎仍然没有解决 jQuery 不支持 SVG DOM 模型。因此,它的某些部分可能有效,而其他部分则无效(例如offset()
或 width()
)。
我现在绝对不会依赖 HTML5 拖放支持,而是使用库来处理这个问题。如果你想使用 SVG,你可以试试Raphaël。如果您也需要 jQuery,也许SVG plugin 是您的最佳选择。请注意,目前这两个项目都没有积极开发。 我知道这不是一个真正令人满意的答案,但我也必须了解,jQuery 和 SVG 不能很好地结合在一起。希望有人证明我错了;)。
【讨论】:
以上是关于Html5拖放到svg元素上的主要内容,如果未能解决你的问题,请参考以下文章