触摸移动时切换到新元素

Crossing over to new elements during touchmove

本文关键字:元素 新元素 移动 触摸      更新时间:2023-09-26

我想这样做,当你把手指拖到一组元素上时,你手指所在元素的背景会发生变化。

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

看到这把小提琴,我希望盒子在你触摸它们时变成绿色:

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

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

编辑:我在这里找到了一个使用mouseenter的想法。如何在touchmove上检测html元素,并使其能够在桌面chrome上工作,但不能在移动safari上工作。

我采取了一种不同的方法:

每次触摸事件,我都会检查触摸位置是否在$('.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浏览器,我希望它也适用于移动设备。

编辑
这个小提琴中,我使用了两个版本,我的版本和评论中链接中的那个版本(document.elementFromPoint–一个jQuery解决方案),这两个版本似乎都适用于我的Android手机。我还添加了一个快速而肮脏的基准测试(请参阅控制台),正如预期的那样,document.elementFromPoint的速度要快几千分之一,如果这是你所关心的问题,你应该检查document.elementFromPoint对你想要支持的浏览器的支持。

你会在这个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');
         }
      }
   });
});

您不能"触发触摸结束事件"或取消触摸,您需要开始触摸另一个。

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