【问题标题】:Detect hover/mouseover/mouseenter while dragging an element拖动元素时检测悬停/鼠标悬停/鼠标输入
【发布时间】:2017-07-31 14:02:24
【问题描述】:

如何在拖动元素时检测悬停/鼠标悬停/鼠标输入?我想在用“拖动”元素悬停它后有一个绿色框。有什么解决办法吗?

注意:我知道我可以使用 jQuery UI,但我想自己做。

    $("box").mouseover(function() {
  $(this).addClass("green");
  var box = $(this).attr("id");
  $("#result").html(box);
});

$("box").mouseleave(function() {
  $(this).removeClass("green");
});

$("drag").bind({
  mousedown: function() {
    $(this).addClass("absolute");
  },
  mouseup: function() {
    $(this).removeClass("absolute");
  },
  mousemove: function(e) {
    $(this).css({
      left: e.pageX - (50 / 2),
      top: e.pageY - (50 / 2)
    });
  }
});

$("body").mousemove(function(event) {
  $("#log").text("pageX: " + event.pageX + ", pageY: " + event.pageY);
});

https://jsfiddle.net/38zecoL1/1/

感谢您的帮助。

【问题讨论】:

  • @Rick 这对你有点不公平......他正试图完成它并且在一小部分有问题。编写现有库的功能只是为了知道事情是如何工作的/说你有,这是不错的做法。
  • 使用 html5 拖放事件...html5rocks.com/en/tutorials/dnd/basics
  • 有一个有趣的实验性 API 可以找出特定 (x,y) 位置的多个元素。 document.elementsFromPoint。也许使用 body 上的mousemove 事件来检查box2 和drag 是否在同一位置。

标签: javascript jquery html css drag-and-drop


【解决方案1】:

我会尝试使用:pointer-events: none; 禁用拖动对象上的指针事件。这样,您应该获取悬停对象的事件而不是拖动对象。

但是你也需要适应move和mouseup事件不起作用的情况。您必须将它们绑定到其他地方(例如正文)

这个简短的例子并不完美,但它会告诉你如何做得更好;)

$("box").mouseover(function () {
    $(this).addClass("green");
    var box = $(this).attr("id");
    $("#result").html(box);
});

$("box").mouseleave(function () {
    $(this).removeClass("green");
});

$("#drag").bind({
    mousedown : function (e) {
        $(document.body).css({ 'user-select': 'none' })
        var dragged = $(this);
        dragged.css({
            left : e.pageX - (50 / 2),
            top : e.pageY - (50 / 2)
        });
        dragged.css({
            'pointer-events' : 'none'
        })
        var upHandler = function () {
            dragged.removeClass("absolute");
            dragged.css({
                'pointer-events' : 'all'
            })
            $(document.body).css({ 'user-select': 'initial' })
            $("body").off('mouseup', upHandler);
            $("body").off('mousemove', moveHandler);
        }
        var moveHandler = function (e) {
            dragged.addClass("absolute");
            dragged.css({
                left : e.pageX - (50 / 2),
                top : e.pageY - (50 / 2)
            });
        }

        $("body").bind({
            mouseup : upHandler,
            mousemove : moveHandler
        })
    }
});

$("body").mousemove(function (event) {
    $("#log").text("pageX: " + event.pageX + ", pageY: " + event.pageY);
});
box {
  float: left;
  width: 100px;
  height: 100px;
  background-color: red;
  margin: 20px;
}

#log {
  position: absolute;
  top: 150px;
}

.green {
  background-color: green;
}

#drag {
  width: 50px;
  height: 50px;
  float: left;
  background-color: blue;
}

#drag.absolute {
  position: absolute;
}

html,
body {
  width: 100%;
  height: 100%;
}

* {
  margin: 0;
  padding: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<box id="box1">
  <div id="drag"></div>
</box>
<box id="box2"></box>

<div id="result"></div>
<div id="log"></div>

【讨论】:

  • 非常感谢您的反馈,我离实现自己的拖放功能又近了一步! ;)
  • 你好。我发现了指针事件的问题。当我拖动元素时,有时会出现“不允许”光标,我不能再拖动这个元素了。有什么解决办法吗?
  • 发生这种情况是因为浏览器试图移动“选定的内容”。在拖动开始处添加$(document.body).css({ 'user-select': 'none' }),在拖动结束处添加$(document.body).css({ 'user-select': 'initial' })。 (见我的代码编辑)
  • “我会尝试禁用拖动对象上的指针事件:指针事件:无” - 天才!
【解决方案2】:

容器保持绿色而另一个不变的原因是您拖动的元素是第一个容器的子元素。因此,当您的鼠标位于蓝色可拖动框中时,它仍被视为位于左侧容器内,因为蓝色框是第一个容器的子容器。

解决此问题的一种方法(很可能不是最好的方法)是跟踪鼠标在屏幕上的位置(您已经在移动蓝色块)。在那里,如果您添加一些代码检查鼠标是否在其他容器的边界框内,并基于此添加/删除类。然后将根据鼠标位置添加类,而不是鼠标是否在子元素上。

示例:https://jsfiddle.net/38zecoL1/3/

      var boxes = $("box")
      for(var i = 0; i < boxes.length; i++){
        var boundingBox = boxes[i].getBoundingClientRect();
        if(e.pageX < boundingBox.right &&
             e.pageX > boundingBox.left &&
           e.pageY < boundingBox.bottom &&
           e.pageY > boundingBox.top){
          $(boxes[i]).addClass("green");
        } else{
          $(boxes[i]).removeClass("green");
        }
      }

在一个处理比几个 div 更复杂的页面的页面中添加这可能会非常昂贵,并且在那些更复杂的情况下可能表现不佳。

【讨论】:

  • 感谢您的回答,这对我帮助很大。
  • 当然,我想这里的很多人都忘记解释为什么会发生这种情况,而只是给出解决方案。不过很高兴能提供帮助。
【解决方案3】:

如果你想拖动元素我推荐你使用这个JS库https://github.com/RubaXa/Sortable

有一个opt叫做

chosenClass: "sortable-chosen", // Class name for the chosen item

在这个类中,你可以添加不同的颜色和你想要的一切。

但如果你想自己做,我现在不做

【讨论】:

  • 感谢您的反馈,但正如我所说,我想用纯 jQuery 来做。
猜你喜欢
  • 1970-01-01
  • 2018-03-04
  • 2011-08-04
  • 2018-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多