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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 19:55:34  来源:igfitidea点击:

Html5 drag and drop on svg element

jqueryhtmlsvgdrag-and-drop

提问by bsr

I am trying to follow the html5 drag and drop tutorial here. I could not get the dragstartevent to be registered on rectelement. If I change the event from draggableto mousedownit calls the handleDragStarthandler. Please ignore the additional blank registration in the code.

我正在尝试按照此处的 html5 拖放教程进行操作。我无法dragstartrect元素上注册该事件。如果我将事件从 更改draggablemousedown它调用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, mouseupand mousemove. This is how it works:

这个小解决方案不使用拖动事件,只使用mousedown,mouseupmousemove。这是它的工作原理:

  • 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 mouseupfunction 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()or width()).
  • 根据这篇文章,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 不能很好地结合在一起。希望有人证明我错了;)。