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。

这个小解决方案不使用拖动事件,只使用mousedownmouseupmousemove。它是这样工作的:

当鼠标在矩形上按下时,它会保存鼠标位置和活动元素。 当鼠标移动时,矩形坐标会更新为新的鼠标位置。 当鼠标向上时,它会重置活动元素。

从上面问题中的代码:

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元素上的主要内容,如果未能解决你的问题,请参考以下文章

Html5拖放到svg元素上

HTML5 拖放 - 没有透明度?

如何在 OS X 上拖放到 (python) 脚本上?

使用 HTML5 原生拖放时如何约束移动?

HTML5之拖拽和拖放

解决 OnDropFiles 可能无响应的问题