【问题标题】:Crossing over to new elements during touchmove在 touchmove 期间跨越到新元素
【发布时间】:2012-09-12 21:48:58
【问题描述】:

我想这样当您将手指拖过一组元素时,您手指上的元素的背景会发生变化。

似乎我想为此使用 touchmove 事件,但据我所知,目标元素永远不会改变,即使你拖动它也是如此。 clientX 和 clientY 确实发生了变化,我发现这个 document.elementFromPoint 函数可以在 chrome 中运行,但看起来很迂回(另外我不确定哪些浏览器支持它)

看到这个小提琴,我希望这些框在你触摸它们时变成绿色:

http://jsfiddle.net/QcQYa/9/

顺便说一句,在 chrome 中,您需要进入检查器配置模式的用户代理选项卡并选择“模拟触摸事件”来查看我的示例。

编辑: 我在How to detect html elements on touchmove 找到了使用mouseenter 的想法,并让它在桌面chrome 上工作,但不能在移动Safari 上工作。

【问题讨论】:

  • 您必须查看您的 touchmove 事件的坐标,看看它们是否与您的 html 元素的坐标重叠。我必须为 jquerymobile android 游戏编写相同的代码,我家里没有,但明天可以查找并更新你的小提琴。

标签: javascript jquery touch


【解决方案1】:

我采取了不同的方法:

每个触摸事件我都会检查触摸位置是否在 $('.catch') 对象内。

function highlightHoveredObject(x, y) {
    $('.catch').each(function() {
      // check if is inside boundaries
      if (!(
          x <= $(this).offset().left || x >= $(this).offset().left + $(this).outerWidth() ||
          y <= $(this).offset().top  || y >= $(this).offset().top + $(this).outerHeight()
      )) {

        $('.catch').removeClass('green');
        $(this).addClass('green');
      }
    });
}

您可以看到它在 jsFiddle 上运行。
它适用于 Chrome,我希望它也适用于移动设备。

编辑:
在this fiddle 中,我使用了两个版本,我的版本和来自 cmets 链接的那个版本 (document.elementFromPoint – a jQuery solution),似乎都可以在我的 Android 手机上使用。我还添加了一个快速而肮脏的基准测试(参见控制台),正如预期的那样,document.elementFromPoint 的速度提高了几千分之一,如果您担心这一点,您应该检查document.elementFromPoint 对您想要支持的浏览器的支持。

【讨论】:

  • 似乎有效,注意权衡一下document.elementFromPoint?
  • 当然浏览器不兼容是最大的缺点。我发现了 2 篇您可能非常感兴趣的文章:document.elementFromPoint – a jQuery solution 和 elementFromPoint() under iOS 5。在那里您还看到您必须计算当前视口。我不确定这是否适用于我的解决方案。对我来说,我的解决方案看起来不那么痛苦,但你可以选择什么
  • 我没有想到的是,您需要解决手机/平板电脑浏览器的问题。不幸的是,我不知道哪些移动浏览器支持document.elementFromPoint。但我认为,如果它们都支持它们,性能会略有提高,因为内部函数恰好更快。
  • 感谢您的额外建议。 document.elementFromPoint 适用于 iOS,但我将使用您的解决方案的修改版本。在我的手机上对其进行测试后,当用户向左/向右滑动时,让用户的手指稍微高于或低于盒子是有意义的。例如,应用商店的评分小部件就是这样做的,它让人感觉更好。我无法用document.elementFromPoint 处理这个问题。
【解决方案2】:

您将在 this fiddle 中找到我的解决方案,我在我的 android 手机上对其进行了测试,它工作正常,它使用 jquerymobile 来利用 vmousemove 事件,它还将处理程序附加到 touchmove 事件只是为了防止在移动设备上滚动浏览器视图。

我在这里粘贴相关的 HTML 和 javascript 位:

<div id="main" ontouchmove="touchMove(event);">
   <span class='catch'>One</span>
   <span class='catch'>Two</span>
   <span class='catch'>Three</span>
   <span class='catch'>Four</span>
   <span class='catch'>Five</span>
   <span class='catch'>Six</span>
   <span class='catch'>Seven</span>
</div>

现在是javascript:

function elem_overlap(jqo, left, top) {
   var d = jqo.offset();
   return top >= d.top && left >= d.left && left <= (d.left+jqo[0].offsetWidth)
          && top <= (d.top+jqo[0].offsetHeight);
}

/* To prevent WebView from scrolling on swipe, see http://goo.gl/DIZbm */
touchMove = function(event) {
   event.preventDefault(); //Prevent scrolling on this element
}

$("#main").bind("vmousemove", function(evt){
   $('.catch').each(function(index) {
      if ( elem_overlap($(this), evt.pageX, evt.pageY) ) {
         $('.catch').not('eq('+index+')').removeClass('green');
         if (!$(this).hasClass('green')) {
            $(this).addClass('green');
         }
      }
   });
});

【讨论】:

  • 感谢这个不同的解决方案。我还没有使用 jquery mobile,但这似乎运作良好。
【解决方案3】:

您不能“触发 touchend 事件”或取消触摸,您需要开始触摸另一个。

因此,您最好将 touchmove 事件绑定到容器,并根据框的位置/大小和触摸位置来操作框,就像 Dan Lee 的回答中所做的那样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    • 2014-11-15
    • 1970-01-01
    • 2013-07-29
    • 1970-01-01
    相关资源
    最近更新 更多