jQuery:hover选择器无法在Edge和Firefox中正常工作

时间:2019-06-07 11:23:16

标签: javascript jquery html css

我正在尝试使用可排序的js创建拖放系统,在其中可以通过将磁贴简单地从其容器中扔出来删除它们。 问题是,尽管该代码适用于Chrome,但不适用于Firefox,Edge或IE。 这三个结果是,它永远不会删除图块

链接:http://skynet.ie/~alanfinnin/stack_overflow/js_drag_and_drop/

我一直在寻找我尝试过的解决方案。

  1. 将不透明度全部更改为1,无变化
  2. 使用不同样式的悬停,即is(hover)
  3. 在将鼠标悬停时更改div的颜色,这可以但不能解决问题

    {{1}}

我希望当磁贴移至div之外时,悬停将更改为0并引发警报,但相反,结果是在Firefox和Edge / IE中始终为0,就好像它从未离开div

注意:我正在使用IE 11和firefox 67.0.1版

2 个答案:

答案 0 :(得分:0)

当触发onEnd事件时,Sortable为您提供鼠标位置。

有了它,有了容器的位置和尺寸,就可以计算自己是放在容器中还是容器外部。肯定会在所有浏览器上正常工作,因为我们所做的只是简单的计算。

您需要的代码是:

onEnd: function(event) {
    let mousePositionX = event.originalEvent.clientX; //mouse position x
    let mousePositionY = event.originalEvent.clientY; //mouse position y

     //container is the sortable container
     let container = $("div#lists");
     let containerOffsetLeft = parseInt(container.offset().left);
     let containerWidth = parseInt(container.width());
     let containerOffsetTop = parseInt(container.offset().top);
     let containerHeight = parseInt(container.height());

     if(
        (mousePositionY < containerOffsetTop) ||
        (mousePositionY > (containerOffsetTop + containerHeight)) ||
        (mousePositionX < containerOffsetLeft) ||
        (mousePositionX > (containerOffsetLeft + containerWidth))
     ) {
        alert('remove');
     }
}

答案 1 :(得分:0)

我认为Chrome的行为不正确,或者至少比其他实现之一更令人困惑。

您正在拖动#lists的子级,因此显然您仍在悬停该拖动的元素。由于在DOM中此元素仍然是#lists的子元素,因此#list仍与:hover匹配是有道理的,就像您将鼠标悬停在固定位置的孩子上时如何悬停父元素超出范围。

#parent,#child {
  display: block; 
  width: 50%;
  border:1px solid;
  overflow: visible;
}
#parent {
  height: 75px;
}
#parent:hover {
 background: red; 
}
#child {
  position: fixed;
  height: 50px;
  top: 120px;
}
<div id="parent">
  <div id="child">
  I'm the child, hover over me
  </div>
</div>

如果您阻止了dragstart事件的默认行为(因此是对元素的实际拖动),它会完成您预期的操作,但是您将丢失元素的 phantom

因此,尽管我找不到在每种浏览器中都能实现Chrome行为的任何技巧(尝试克隆元素,在dragstart中更改其父元素的其他技巧,但没有做任何事情...),一种实现所需目标的方法是侦听dragexit父元素上的#lists事件。 触发此事件时,您可以将一个类或js布尔值设置为true,然后在拖动操作完成时或在dragenter中将其删除。这样,您只需要检查此值,而不是仅检查:hover伪类即可。

(()=> {
const parent = document.getElementById('parent');
const dragme = document.getElementById('dragme');
const target = document.getElementById('target');  

parent.ondragexit = e => {
  // check it's not one of our children
  if(e.target === parent) {
    parent.classList.add('out');
  }
};
// remove the class
parent.ondragenter = document.ondragend = e => {
  parent.classList.remove('out');
}

dragme.ondragstart = e => {
  e.dataTransfer.setData('text', '');
};
target.ondrop = e => {
  target.append(dragme);
  dragme.ondragstart = null;
};
parent.ondragover = target.ondragover = e => {
  e.preventDefault();
};
})();
#parent, #target, #dragme {
  border: 1px solid;
}
#parent, #target {
  width: 75px;
  height: 75px;
  display: flex;
  align-items: center;
  justify-content: center; 
}
/* only if not .out */
#parent:hover:not(.out) {
  background: red;
}
<div id="parent">
  <div id="dragme" class="dragclone" draggable="true">drag me</div>
</div>
<div id="target">
</div>