Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect hover/mouseover/mouseenter while dragging an element

How to detect hover/mouseover/mouseenter while dragging an element? I want to have green box after hovering it with the "drag" element. Is there any solution for that?

Note: I know that I could use jQuery UI for it but I want to do it by myself.

    $("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/

Thank you for any help.

like image 608
Hvrxld Avatar asked Jul 31 '17 14:07

Hvrxld


People also ask

How do I know if my mouse is hovering over an element?

You can simply use the CSS :hover pseudo-class selector in combination with the jQuery mousemove() to check whether the mouse is over an element or not in jQuery.

What is the difference between Mouseenter () and mouseover () event?

The mouseover event triggers when the mouse pointer enters the div element, and its child elements. The mouseenter event is only triggered when the mouse pointer enters the div element. The onmousemove event triggers every time the mouse pointer is moved over the div element.

How do you trigger Mouseenter?

The mouseenter event occurs when the mouse pointer is over (enters) the selected element. The mouseenter() method triggers the mouseenter event, or attaches a function to run when a mouseenter event occurs..

Which event is triggered when a mouse is hovering over an element?

The onmouseover event occurs when the mouse pointer is moved onto an element, or onto one of its children. Tip: This event is often used together with the onmouseout event, which occurs when a user moves the mouse pointer out of an element.


2 Answers

I would try to disable pointer events on the dragged object using: pointer-events: none;. That way you should get the events of the hovered objects instead of the dragged.

But you also need to adapt to the situation that the move and mouseup event will not work. You will have to bind them elsewhere (body for example)

This short example is not perfect but schuld give you a hint of how to do it better ;)

$("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>
like image 70
Bellian Avatar answered Sep 19 '22 18:09

Bellian


The reason the container stays green and the other one doesn't change is that the element you're dragging is a child of the first container. So while your mouse is in the blue draggable box it's still considered inside the container on the left because the blue box is a child of the first container.

One way to fix this (and most likely isn't the best way) is to keep track of where the mouse is on the screen (which you're already doing to move the blue block). In there if you add a bit of code checking if the mouse is within the bounding box of either of the other containers and add/remove classes based on that. Then the classes will be added based on mouse position and not whether the mouse is over an element that is a child or is not a child.

Example: 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");
        }
      }

This is likely pretty expensive to add in a page that deals with a more complex page than just a few divs and may not perform well in those more complex situations.

like image 22
Don Avatar answered Sep 16 '22 18:09

Don