【问题标题】:Tell if mouse was dragged from one div to another判断鼠标是否从一个 div 拖到另一个
【发布时间】:2018-04-10 05:05:15
【问题描述】:

我的页面包含一个红色和一个蓝色div

<div id="red"></div>
<div id="blue"></div>

它们都是绝对定位的,并且相隔很小:

#red {
    background-color: red;
    width: 5em;
    height: 5em;
    position: absolute;
    left: 5em;
    top: 5em;
}

#blue {
    background-color: blue;
    width: 5em;
    height: 5em;
    position: absolute;
    left: 15em;
    top: 5em;
}

我有一些代码可以判断用户是否单击并将鼠标从一个div 拖动到另一个:

$('#red').mousedown( function () {
    $('#blue').mouseup( function () {
        alert('Red to Blue')
    })
})

$('#blue').mousedown( function () {
    $('#red').mouseup( function () {
        alert('Blue to Red')
    })
})

如果用户在按住鼠标按钮的情况下直接将鼠标从一个div 移动到另一个,这在第一次时会完美运行。

不过有两个问题:

  1. 如果用户在div 之外释放鼠标按钮然后单击另一个按钮,mouseup 仍将运行。
  2. 在第一次之后的任何时候,用户都必须在div 之外单击,以便处理程序正常工作。

【问题讨论】:

    标签: javascript jquery html css user-interface


    【解决方案1】:

    mouseup 事件一旦发生就应该被移除(使用.one()),并且应该在 div 之外检测到它。此外,我们需要通过使用event.preventDefault() 来解决第二个问题来防止mousedown 的默认行为。见代码中的 cmets。

    注意:.one()(一个未启用)用于绑定一次性事件处理程序,该事件处理程序一被触发就会被删除。这可以防止将多个mouseup 事件附加到文档中。

    var $red = $('#red')
    var $blue = $('#blue');
    
    $($.merge($red, $blue)).mousedown(function(e) {
      e.preventDefault(); // prevent the default behavior of mousedown
      var source = $(e.target);
    
      // attach the mouseup to the document as one time event to detect up
      $(document).one('mouseup', function(e) {
        // check if the source is red and the target is blue
        if ($blue.is(e.target) && source.is($red)) {
          alert('Red to Blue');
        } // check if the source is red and the target is blue
          else if ($red.is(e.target) && source.is($blue)) {
          alert('Blue to Red');
        }
      })
    });
    #red {
      background-color: red;
      width: 5em;
      height: 5em;
      position: absolute;
      left: 5em;
      top: 5em;
    }
    
    #blue {
      background-color: blue;
      width: 5em;
      height: 5em;
      position: absolute;
      left: 15em;
      top: 5em;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="red"></div>
    
    <div id="blue"></div>

    还有一个更通用的解决方案,使用data-* 属性来识别源和目标:

    $('[data-color]').mousedown(function(e) {
      e.preventDefault(); // prevent the default behavior of mousedown
      var source = $(e.target).attr('data-color'); // get the source data color
    
      // attach the mouseup to the document as one time event to detect up
      $(document).one('mouseup', function(e) {
        var target = $(e.target).attr('data-color'); // 
        
        if(target !== undefined && source !== target) {
          alert(source + ' to ' + target);
        }
      })
    });
    div[data-color] {
      position: absolute;
      width: 5em;
      height: 5em;
    }
    
    #red {
      left: 5em;
      top: 1em;
      background-color: red;
    }
    
    #blue {
      left: 15em;
      top: 1em;
      background-color: blue;
    }
    
    #yellow {
      left: 5em;
      top: 10em;
      background-color: yellow;
    }
    
    #green {
      left: 15em;
      top: 10em;
      background-color: green;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <!-- set data-type with the color to each element -->
    <div id="red" data-color="Red"></div>
    
    <div id="blue" data-color="Blue"></div>
    
    <div id="yellow" data-color="Yellow"></div>
    
    <div id="green" data-color="Green"></div>

    【讨论】:

    • @Drown - 不用担心,再次感谢您的错字更正。
    【解决方案2】:

    你应该像这样改变你的方法:

    var isDragging = false;
    var dragElement = null;
    
    $('#red, #blue').mousedown(function() {
       dragElement = $(this);
       isDragging = true;
    });
    
    $('#red, #blue').mouseup(function() {
        if(isDragging && dragElement){ 
            alert('Dragged in',dragElement);
            dragElement = null;
            isDragging = false;
        }
    });
    
    $('body *:not(#red, #blue)').mouseup(function() {
        if(isDragging && dragElement){ 
            alert('Not dragged',dragElement);
            dragElement = null;
            isDragging = false;
        }
    });
    

    还有一个问题:Draggable div without jQuery UI

    【讨论】:

    • 如果mouseup 出现在redblue 之外怎么办?
    • 针对这个案例编辑
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-30
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多