简体   繁体   English

JS HTML5拖放:自定义Dock效果在Chrome中跳跃

[英]JS HTML5 Drag and Drop: Custom Dock Effect Jumping Around in Chrome

Situation: I'm using HTML5 drag-and-drop to place tiles in a game I'm writing. 情况:我正在使用HTML5拖放将瓷砖放在我正在编写的游戏中。 I'd like to add an effect where the two tiles that I'm about to drop a new tile between move slightly apart to indicate that this is where you're dropping (similar to the Mac OS dock). 我想添加一个效果,其中两个瓷砖,我即将放置一个新的瓷砖之间稍微移动,以表明这是你正在下降的地方(类似于Mac OS底座)。

My Approach: I have a flexbox into which I'm dropping these tiles. 我的方法:我有一个flexbox ,我正在丢弃这些瓷砖。 I wrote a function that essentially returns one period of a sine wave and I'm using it to update the dropped tiles' right: and top: CSS properties (the tiles are position: relative; ) based on their original position relative to the mouse during drag . 我写了一个函数,基本上返回一个正弦波周期,我用它来更新掉落的瓷砖right: top: CSS属性(瓷砖是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);
    }
  }

Problem: In Chrome (but not in Firefox), at some mouse positions, which I can't find a pattern in, the tile is jumping back-and-forth. 问题:在Chrome中(但不是在Firefox中),在某些鼠标位置(我无法找到图案)中,图块会来回跳跃。 See the .gif below: 请参阅下面的.gif文件:

In Chrome (left) and in Firefox (right): 在Chrome(左)和Firefox(右)中:

在Chrome中演示 在Firefox中演示

I even console.log ged the element's calculated right: property, and while it is shown jumping around on screen, it outputs as a constant value. 我甚至是console.log ged元素的计算right:属性,当它显示在屏幕上跳跃时,它输出为常量值。

What I've Tried/Thought About: 我试过/想过的:

  • Even with the mouse stationary and console.log(event.clientX) outputting a constant value, the tile will jump around. 即使鼠标静止并且console.log(event.clientX)输出一个常量值,瓷砖也会跳转。
  • I thought event.clientX might be changing imperceptibly, so I'm basing my calculations on Math.trunc(event.clientX) to no avail. 我认为event.clientX可能会在不知不觉中发生变化,所以我的计算基于Math.trunc(event.clientX)无济于事。
  • I am using element.getBoundingClientRect() in my calculations, which I'm not very familiar with, and I think it may be the root cause of my problem. 我在我的计算中使用了element.getBoundingClientRect() ,我不是很熟悉,我认为这可能是我问题的根本原因。

I made this CodePen , but wasn't able to completely replicate the issue. 我制作了这个CodePen ,但无法完全复制该问题。 Still, I think someone may be able to spot what's happening. 不过,我认为有人可能能够发现正在发生的事情。

Edit: I've put this up on a github page to fully replicate . 编辑:我把它放在github页面上完全复制 This link may not work for future readers of the question, but I'll keep it up for the foreseeable future. 这个链接可能对问题的未来读者不起作用,但我会在可预见的将来继续保持这种联系。 To demonstrate the issue, view in Chrome and Firefox. 要演示此问题,请在Chrome和Firefox中查看。

Thank you. 谢谢。

Perhaps I can expand my answer later, but for now: 也许我可以稍后扩展我的答案,但现在:

Related questions: How to keep child elements from interfering with HTML5 dragover and drop events? 相关问题: 如何防止子元素干扰HTML5 dragover和drop事件? 'dragleave' of parent element fires when dragging over children elements 拖动子元素时,父元素的'dragleave'会触发

This is what happens: - you start dragging the operator - operator moves over the box, existing operators move along nicely - you move the operator over one of the existing operators - at this point the browser enters a kind of infinite loop thingy, because each time the elements move the position of the elements have to be updated again (because new events are triggered) 这就是: - 你开始拖动操作符 - 操作符移动到框上,现有的操作符很好地移动 - 你将操作符移动到现有的一个操作符上 - 此时浏览器进入一种无限循环的东西,因为每个元素移动的时间必须再次更新元素的位置(因为触发了新事件)

Since you need the click event on the existing operators you can't just set them to pointer-events: none; 由于您需要现有运算符上的click事件,因此您不能将它们设置为pointer-events: none; like in the related question, but you can add a class when you start dragging and apply this style to the operators while you're dragging. 就像在相关问题中一样,但是您可以在开始拖动时添加一个类,并在拖动时将此样式应用于运算符。

Another solution would be to use a library, in the comments of an answer I found the library https://bensmithett.github.io/dragster/ , I use draggable by shopify. 另一个解决方案是使用一个库,在答案的评论中我找到了库https://bensmithett.github.io/dragster/ ,我使用了shopify的draggable。

update 更新

I wasn't able to find the exact term of this behavior, perhaps we could go with "cyclic case" or "undefined behaviour". 我无法找到这种行为的确切术语,也许我们可以选择“循环案例”或“未定义行为”。 See my examples: 看看我的例子:

 :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> 

When the user moves the mouse onto the border the following happens in a loop: 当用户将鼠标移动到边框上时,循环中会发生以下情况:

  1. box1 is being hovered box1正在盘旋
  2. hover styles apply, the border is removed 悬停样式适用,边框被删除
  3. box1 isn't being hovered box1没有被盘旋
  4. hover styles stop applying, the border is readded 悬停样式停止应用,边框被读取

basically for the moment the CSS doesn't really evaluate, because as soon as it evaluates the evaluation is invalid. 基本上目前CSS没有真正评估,因为一旦评估评估是无效的。 This is exactly what happens in your example. 这正是您的示例中发生的情况。 I don't know whether the CSS standard has rules that define how browsers should handle this. 我不知道CSS标准是否有定义浏览器应该如何处理它的规则。 If the expected behavior is defined, either FF or Chrome is wrong and you can file a bug after you find out which browser's behavior is wrong. 如果定义了预期的行为,则FF或Chrome是错误的,您可以在找到哪个浏览器的行为错误后提交错误。 If no expected behavior is defined and the implementation is left open to browsers then both browsers are right. 如果没有定义预期的行为并且实现对浏览器保持开放,则两个浏览器都是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM