11

情况:我正在使用 HTML5 拖放在我正在编写的游戏中放置图块。我想添加一个效果,其中我将要放置一个新瓷砖的两个瓷砖稍微分开,以表明这是你要放下的地方(类似于 Mac OS 扩展坞)。

我的方法:我有一个flexbox将这些瓷砖放入其中的方法。我写了一个函数,它基本上返回一个正弦波的周期,我用它来根据right:它们在.top:position: relative;drag

  // Update occupant style for desired effect
  occupants.forEach(function(occupant, index) {
    $(occupant).css({'right' : -10 * nudgeSine(occupantsMouseOffset[index] * 10) + 'px',
                     'top' : -10 * Math.abs(nudgeSine(occupantsMouseOffset[index] * 10)) + 'px',
                     'opacity' : 1 - Math.abs(nudgeSine(occupantsMouseOffset[index])) });
  });

  // Function to return 1 period of a sine wave
  function nudgeSine(x) {
    if (x < -3.14159 || x > 3.14159) {
      return 0;
    } else {
      return Math.sin(x);
    }
  }

问题:在 Chrome 中(但不是在 Firefox 中),在某些我找不到模式的鼠标位置,图块来回跳跃。请参阅下面的 .gif:

在 Chrome(左)和 Firefox(右)中:

Chrome 中的演示 Firefox 中的演示

我什console.log至 ged 元素的计算right:属性,当它显示在屏幕上跳跃时,它输出为一个常数值。

我尝试过/想到的:

  • 即使鼠标静止并console.log(event.clientX)输出恒定值,图块也会跳来跳去。
  • 我认为event.clientX可能会在不知不觉中发生变化,所以我根据我的计算Math.trunc(event.clientX)无济于事。
  • element.getBoundingClientRect()在我的计算中使用,我不是很熟悉,我认为这可能是我问题的根本原因。

我制作了这个 CodePen,但无法完全复制该问题。不过,我认为有人可能能够发现正在发生的事情。

编辑:我把它放在一个github 页面上以完全复制. 此链接可能不适用于该问题的未来读者,但我会在可预见的将来继续使用它。要演示该问题,请在 Chrome 和 Firefox 中查看。

谢谢你。

4

1 回答 1

2

也许我可以稍后扩展我的答案,但现在:

相关问题:如何防止子元素干扰 HTML5 拖放事件? 拖动子元素时触发父元素的“dragleave”

这就是发生的事情:-您开始拖动运算符-运算符在框上移动,现有运算符很好地移动-您将运算符移动到现有运算符之一上-此时浏览器进入一种无限循环,因为每个元素移动的时间元素的位置必须再次更新(因为触发了新事件)

由于您需要现有运算符的单击事件,因此您不能只pointer-events: none;在相关问题中将它们设置为喜欢,而是可以在开始拖动时添加一个类,并在拖动时将此样式应用于运算符。

另一种解决方案是使用库,在答案的评论中我找到了库https://bensmithett.github.io/dragster/,我使用 shopify 的 draggable。

更新

我无法找到这种行为的确切术语,也许我们可以使用“循环案例”或“未定义行为”。看我的例子:

:root {
  /*colors by clrs.cc*/
  --navy: #001f3f;
  --blue: #0074D9;
  --red: #FF4136;
  font-family: sans-serif;
}

.animated {
  transition: all .5s;
}

h2 {
  color: var(--red);
}

div {
  height: 160px;
  width: 160px;
  padding: 20px;
  background: var(--blue);
  margin-bottom: 20px;
}

.box1 {
  border-right: 20px solid var(--navy);
}

.box1:hover {
  border-right: 0px solid var(--navy);
}

.box2:hover {
  border-radius: 100px;
}
<div class="box1 animated">hover your mouse over my border on the right →&lt;/div>
<div class="box2 animated">hover your mouse over an edge of this box</div>
<h2>Warning, the following boxes have no animations, flashes are expected:</h2>
<div class="box1">hover your mouse over my border on the right →&lt;/div>
<div class="box2">hover your mouse over an edge of this box</div>

当用户将鼠标移动到边框上时,会循环发生以下情况:

  1. box1被悬停
  2. 应用悬停样式,移除边框
  3. box1没有悬停
  4. 悬停样式停止应用,边框被读取

基本上目前CSS并没有真正评估,因为一旦评估,评估就无效了。这正是您的示例中发生的情况。我不知道 CSS 标准是否有定义浏览器应该如何处理这个问题的规则。如果定义了预期的行为,则 FF 或 Chrome 是错误的,您可以在找出哪个浏览器的行为错误后提交错误。如果没有定义预期的行为并且实现对浏览器开放,那么两个浏览器都是正确的。

于 2018-07-25T14:42:41.200 回答