【问题标题】:Using ESC event to cancel Drag and Drop使用 ESC 事件取消拖放
【发布时间】:2015-11-03 17:49:03
【问题描述】:

我正在寻找一种允许用户通过按 ESC 键来取消鼠标拖动操作的方法。

这可以使用 Javascript 来完成吗?

谢谢

更新

当鼠标将 div 元素拖动到可放置区域上时,按 ESC 键应将元素拖动到不可放置区域。一旦元素被拖到不可放置的区域,我会在被拖动的元素上调用“mouseup”事件,这会导致被拖动的元素被放置到不可放置的区域。

如何使用 jQuery Draggable 和 jQuery Droppable 做到这一点?

【问题讨论】:

标签: javascript jquery html jquery-ui


【解决方案1】:

当鼠标将 div 元素拖动到可放置区域上时,按 ESC 键应将元素拖动到不可放置区域

我创建了一个可能的解决方案demo,您可以在 plunker 中查看。

@ioneyed所说,你可以直接使用选择器.ui-draggable-dragging选择被拖动的元素,如果你有很多可拖动的元素应该会更高效。

使用的代码如下,但是,显然它在 sn-p 部分中不起作用。使用 plunker 上的fullscreen 功能或在本地复制它。

var CANCELLED_CLASS = 'cancelled';

$(function() {

  $(".draggable").draggable({

    revert: function() {

      // if element has the flag, remove the flag and revert the drop
      if (this.hasClass(CANCELLED_CLASS)) {
        this.removeClass(CANCELLED_CLASS);
        return true;
      }

      return false;

    }

  });

  $("#droppable").droppable();

});

function cancelDrag(e) {

  if (e.keyCode != 27) return; // ESC = 27

  $('.draggable') // get all draggable elements
    .filter('.ui-draggable-dragging') // filter to remove the ones not being dragged
    .addClass(CANCELLED_CLASS) // flag the element for a revert
    .trigger('mouseup'); // trigger the mouseup to emulate the drop & force the revert

}

$(document).on('keyup', cancelDrag);
        .draggable {
          padding: 10px;
          margin: 10px;
          display: inline-block;
        }
        #droppable {
          padding: 25px;
          margin: 10px;
          display: inline-block;
        }
<div id="droppable" class="ui-widget-header">
  <p>droppable</p>
</div>

<div class="ui-widget-content draggable">
  <p>draggable</p>
</div>

<div class="ui-widget-content draggable">
  <p>draggable</p>
</div>

<div class="ui-widget-content draggable">
  <p>draggable</p>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.css">

【讨论】:

  • 为什么要过滤 .ui-draggable-dragging 而不是将其作为初始选择器或进行子选择 $('.ui-draggable-dragging','.draggable')
  • 您的代码不起作用。假设我将可拖动元素拖到可放置元素上。当我按下 ESE 键时,可拖动元素不应放在可放置元素上。但是,您提供的解决方案允许在按下 ESC 键后将可拖动元素拖放到可放置元素上。
  • 他的解决方案是您所要求的,但是您没有声明您希望取消保留。此外,这是对可拖动对象的简单附加,使其查找已取消的类并忽略可拖动状态。 cancel: ".cancelled" 在您的可拖动声明中
  • 当按下 ESC 键时,我要求将元素放置在不可放置的元素上。
  • 什么不可丢弃的元素?因为您没有提供 HTML,所以我简单地恢复了拖动,但从那里很容易完成。
【解决方案2】:

我试图提供帮助,但没有得到预期的结果...... 在 google 上搜索您会发现 在拖动时其他事件被锁定,与 window.alert 期间发生的行为类似...

顺便说一句,我在 Mac 上,我可以捕获所有键盘事件,但不能捕获“控制键,例如 command、ctrl、esc、ecc。”

希望对您有所帮助!

function DragAndDropCtrl($) {
  var self = this;
  
  self.ESC = 27;
  self.draggables = $('.draggable');
  self.dropArea = $('#droppable');
  self.currentDraggingElement = null;
  self.currentDismissed = false;

  self.dismissDragging = function(event, eventManager) {
    
    self.currentDismissed = true;
    
    //Using the manager you can't use the revert function OMG!
    //return eventManager.cancel();
  };
  
  self.dropArea.droppable();
  self.draggables.draggable({
    revert: function() {
      var revert = self.currentDismissed;
      
      self.currentDismissed = false;
      console.log(revert, self.currentDismissed)
      
      return revert;
    },
    start: function() {
      self.currentDraggingElement = $(this);
    },
    end: function() {
      self.currentDraggingElement = null;
    }
    
  });
  
  $(document).keypress(function(event) {
    
    console.log('key pressed', event)
    
    //How to intercept the esc keypress?
    self.dismissDragging(event, $.ui.ddmanager.current);
    
    if(event.which  === self.ESC || event.keyCode  === self.ESC) {
      self.dismissDragging(event, $.ui.ddmanager.current);
    }
  });
}

jQuery(document).ready(DragAndDropCtrl);
#droppable {
  border: 1px solid #ddd;
  background: lightseagreen;
  text-align: center;
  line-height: 200px;
  margin: 1em .3em;
}

.draggable {
  border: 1px solid #ddd;
  display: inline-block;
  width: 100%;
  margin: .5em 0;
  padding: 1em 2em;
  cursor: move;
}

.sidebar { width: 30%; float: left; }
.main { width: 70%; float: right; }
* { box-sizing: border-box; }
<div class="sidebar">
  <div class="ui-widget-content draggable">
    <p>draggable</p>
  </div>
  <div class="ui-widget-content draggable">
    <p>draggable</p>
  </div>

  <div class="ui-widget-content draggable">
    <p>draggable</p>
  </div>
</div>


<div class="main">  
  <div id="droppable" class="ui-widget-header">
    <p>droppable</p>
  </div>
</div>



<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.css">

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多