0

Last edit: I've found this question. It looks to be a Chrome issue.


I'm trying to drag a jQuery UI draggable element over an element which on CSS :hover bring up (z-index based) some of its childrens. I need that those childrens to accept my dragging object (they are all jQuery UI droppable).

Here is the jsFiddle.

How it should work: drag a blue circle on the left element to another circle on the right element. Draggable element is turning in a red one, and all droppable elements must bring on top and become green bordered. Same behavior is expected if we drag a circle from right element to the left one.

After each drop event, draggable and droppable elements involved become heavy bordered, as a visual feedback of the user action.

However, I've tested this one in the following browsers, each of them have some issues:

  • Chrome 43.0.2357.124 m - the CSS :hover state isn't triggered, but droppable elements accept the draggable one. activeClass and hoverClass from droppable element refuse to work, and the CSS :hover have the same issue.
  • Firefox 38.0.5 - the CSS :hover state is triggered only if I use cursorAt option in draggable element. activeClass and hoverClass from droppable element also works fine. Problem in Firefox is that droppable drop event isn't fired (or I reffer the element itself wrong).
  • Internet Explorer 11.0.20 - nothing works, it fires some errors in the console (Access is denied, 'jQuery' is undefined, '$' is undefined).

For almost one and a half day I try to figure out if this a jQuery glitch, a browser problem, or is anything wrong with my code. And of course to find a cross browser solution for this problem.

Thanks for your time and your interest!


Edit: updated jsFiddle link.

Community
  • 1
  • 1
SYNCRo
  • 450
  • 5
  • 21

1 Answers1

1

The solution for Internet Explorer is quite simple. You are using an outdated version of jQuery. You're using version 1.10.1, but the current supported version is 2.1.3. Switching to a newer version should solve problems in modern browsers.

$(function() {
    $("#flowEditor").disableSelection();
    $("button").on("click", function() {
        $("span.anchor").css("border-width", "2px");
    });
    $("span.anchor").draggable({
        helper: "clone",
        accept: "span.anchor",
        containment: "#flowEditor",
//    cursorAt: { top: -10, left: -10 },
        start: function(event, ui) {
            $(ui.helper).css("z-index", "9999999");
            $(ui.helper.context).addClass("context");
        },
        stop: function(event, ui) {
            $(ui.helper.context).removeClass("context");
            $(ui.helper.context).css("border-width", "5px");
        }
    }).droppable({
        accept: "span.anchor",
        activeClass: "active",
        hoverClass: "hover",
        drop: function(event, ui) {
            $(this).css("border-width", "5px");
        }
    });
});
#flowEditor {
  list-style-type: none;
  padding: 0px;
  height: 640px;
  box-sizing: border-box;
  border: 3px double gold;
}
#flowEditor li {
  width: 100px;
  height: 100px;
  margin: 4px;
  border: 1px solid wheat;
}
#flowEditor li span.caption {
  display: block;
  margin-top: 40px;
  height: 36px;
  text-align: center;
}
#flowEditor>li {
  background-color: white;
}
#flowEditor {
  position: relative;
}
#flowEditor li span.anchor {
  display: block;
  position: absolute;
  width: 8px;
  height: 8px;
  border: 2px solid blue;
  z-index: -1;
  cursor: pointer;
}
#flowEditor li:hover span.anchor {
  z-index: 999999;
}
#flowEditor li:hover span.anchor.active {
  z-index: 999999;
  border-color: green;
}
#flowEditor li:hover span.anchor.hover {
  z-index: 999999;
  background-color: green;
}
#flowEditor li span.anchor:hover {
  background-color: blue;
}
#flowEditor li span.anchor.context {
  background-color: red;
}
#flowEditor li span.anchor-top {
  top: -6px;
  left: calc(50% - 6px);
}
#flowEditor li span.anchor-left {
  left: -6px;
  top: calc(50% - 6px);
}
#flowEditor li span.anchor-right {
  right: -6px;
  top: calc(50% - 6px);
}
#flowEditor li span.anchor-bottom {
  bottom: -6px;
  left: calc(50% - 6px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.11.2/themes/cupertino/jquery-ui.css">
<script type="text/javascript" src="https://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>

<button>Reseteaza</button>
<ul id="flowEditor" style="width: 100%; height: 480px; border: 3px double gold;">
    <li class="ui-corner-all" style="position: absolute; left: 17px; top: 31px;">
        <span class="caption">Item 1</span>
        <img class="move" />
        <span class="ui-corner-all anchor anchor-top"></span>
        <span class="ui-corner-all anchor anchor-left"></span>
        <span class="ui-corner-all anchor anchor-right"></span>
        <span class="ui-corner-all anchor anchor-bottom"></span>
    </li>
    <li class="ui-corner-all" style="position: absolute; left: 170px; top: 31px;">
        <span class="caption">Item 2</span>
        <img class="move" />
        <span class="ui-corner-all anchor anchor-top"></span>
        <span class="ui-corner-all anchor anchor-left"></span>
        <span class="ui-corner-all anchor anchor-right"></span>
        <span class="ui-corner-all anchor anchor-bottom"></span>
    </li>
</ul>

As for why the hover effect isn't working, the CSS hover event doesn't seem to be triggered while the mouse is down unless it was originally hovered over that specific element. To make this work regardless of whether the mouse is pressed, JavaScript would be more reliable to detect the hover event instead of CSS.

For example, trying pressing the mouse down originally from outside of the divs, constantly holding it down while moving inside them. Notice how the CSS :hover is not triggered while JavaScript is.

$('div').hover(function () {
    console.log(1);
});
div {
    padding: 10px;
    border: 1px solid black;
    background-color: white;
}
div:hover {
    background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div><div></div></div>
Anonymous
  • 11,748
  • 6
  • 35
  • 57
  • Using jQuery 2.1.3 make Internet Explorer to behave like Firefox. Nothing changed in Chrome. Also, droppable's `drop` event isn't triggered. I've tried an `alert(1);` in `drop` function. – SYNCRo Jun 20 '15 at 21:28
  • As for the hover effects, you basically just want the second square to behave the same as the first? – Anonymous Jun 20 '15 at 21:33
  • Yes. But try this in Chrome: uncomment `cursorAt` line; drag a circle from Item1 in Item2 and drop it in the middle of the Item2. Now, move the mouse inside the Item2. It's `:hover` CSS rule doesn't aplly. This is a strange behavior. – SYNCRo Jun 20 '15 at 21:38
  • Yeap, it looks like Chrome handle `:hover` event different that IE & Firefox. Hovering an element with mousedown in Chrome both CSS and JS will not fire `:hover` or `.hover()`. Instead, IE & Firefox both fires it. – SYNCRo Jun 20 '15 at 21:57
  • @SYNCRo Yea, I guess so. I doubt there's much in the spec about users who previously had a mouse down originally located on a different element whose mouse was positioned onto a different element. :) – Anonymous Jun 20 '15 at 21:58
  • @SYNCRo JavaScript hover works fine in Chrome. If you tested on my snippet before the last edit, it wouldn't have worked, but if you test now, it should work fine. – Anonymous Jun 20 '15 at 22:01