【问题标题】:JS HTML5 Drag and Drop: Custom Dock Effect Jumping Around in ChromeJS HTML5 拖放:自定义 Dock 效果在 Chrome 中跳跃
【发布时间】:2018-12-24 17:37:37
【问题描述】:

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

我的方法:我有一个flexbox,我将这些图块放入其中。我写了一个函数,它基本上返回一个正弦波的周期,我用它来根据它们相对于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(右)中:

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

我尝试过/想到的:

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

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

编辑:我把它放在github page to fully replicate 上。此链接可能不适用于该问题的未来读者,但我会在可预见的将来继续使用它。要演示该问题,请在 Chrome 和 Firefox 中查看。

谢谢。

【问题讨论】:

    标签: javascript google-chrome user-interface drag-and-drop html5-draggable


    【解决方案1】:

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

    相关问题:How to keep child elements from interfering with HTML5 dragover and drop events? 'dragleave' of parent element fires when dragging over children elements

    会发生这种情况: - 你开始拖动操作员 - 操作员在盒子上移动,现有操作员很好地移动 - 您将运算符移到现有运算符之一上 - 此时浏览器进入了一种无限循环的状态,因为每次元素移动时元素的位置都必须再次更新(因为触发了新事件)

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

    另一个解决方案是使用库,在答案的 cmets 中我找到了库 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 →</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 →</div>
    <div class="box2">hover your mouse over an edge of this box</div>

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

    1. box1 被悬停
    2. 应用悬停样式,移除边框
    3. box1 没有被悬停
    4. 悬停样式停止应用,边框被重新添加

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

    【讨论】:

    • 我真的很想看到你扩展这个答案。我明白了你的大意,但为什么 Firefox 没有出现波动?
    • 感谢您的更新。我基本上一直都明白,运动会干扰拖动事件。由于这是一个有趣和学习的副项目,我想避免仅仅实现一个库。这教会了我很多关于拖放的知识,我想坚持下去。谢谢!
    • 没问题,我也从中学到了不少东西。你还有什么不明白的吗?
    猜你喜欢
    • 2015-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    • 2014-06-16
    相关资源
    最近更新 更多