我正在尝试遵循html5拖放教程。我无法将dragstart
事件注册到rect
元素上。如果我将事件从draggable
更改为mousedown
,它将调用handleDragStart
处理程序。请忽略代码中额外的空白注册。
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
$(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();
});
我知道这是一个老问题,我从另一个被标记为这个问题的副本的问题到达这里,并希望添加一个可能的解决方案,不需要jQuery或任何库,并在所有主要浏览器中工作。它是基于@AmirHossein Mehrvarzi推荐的教程。
这个小的解决方案不使用拖动事件,只使用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" width="100" height="80" fill="#69c" />
<rect x="50" y="50" width="90" height="50" fill="#c66" />
</svg>
您也可以在这个JSFiddle上看到它:http://jsfiddle.net/YNReB/61/
如果您想添加拖放功能,您可以修改mouseup
函数来读取光标位置上的元素(使用document.elementFromPoint(e.clientX, e.clientY)
),然后您可以对原始元素和它被拖放的元素执行操作。
此行为可能由以下几个原因引起:
- 根据这篇文章,HTML 5的拖放是一团乱麻。我知道它有点旧,但问题似乎仍然没有解决jQuery不支持SVG dom模型。因此,它的某些部分可能工作,其他部分不(如
offset()
或width()
)。我绝对不会依赖HTML5拖拽&现在放弃支持,而是使用一个库来处理这个问题。如果您想使用SVG,可以尝试Raphaël。如果您也需要jQuery,那么SVG插件可能是最好的选择。请注意,这两个项目目前都没有积极开发。我知道这不是一个真正令人满意的答案,但我也必须认识到,jQuery和SVG不能很好地结合在一起。希望有人能证明我是错的。