Html5 перетащите на элемент SVG - PullRequest
14 голосов
/ 03 мая 2011

Я пытаюсь следовать руководству по перетаскиванию 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();
}); 

Ответы [ 2 ]

10 голосов
/ 12 июня 2015

Я знаю, что это старый вопрос, я пришел сюда с этого другого вопроса , который был помечен как дубликат этого, и хотел добавить возможное решение, которое не требует 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)), а затем вы можете выполнять действия с исходным элементом и тем, где он был отброшен. .

8 голосов
/ 25 июня 2011

Такое поведение может быть вызвано несколькими причинами:

  • HTML 5 drag and drop - беспорядок, согласно этой статье . Я знаю, что он немного старше, но проблема все еще не решена
  • jQuery не поддерживает DOM-модель SVG. Поэтому некоторые его части могут работать, другие нет (например, offset() или width()).

Я бы определенно не полагался на поддержку перетаскивания в HTML5, а использовал бы библиотеку для решения этой проблемы. Если вы хотите работать с SVG, вы можете попробовать Raphaël . Если вам нужен также jQuery, возможно, вам подойдет SVG-плагин . Обратите внимание, что оба проекта в настоящее время активно не развиваются. Я знаю, что это не совсем удовлетворительный ответ, но я также должен был понять, что jQuery и SVG не очень хорошо сочетаются друг с другом. Надеюсь, кто-то докажет, что я не прав;).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...