【问题标题】:Prevent touchmove default on parent but not child防止父级而不是子级的touchmove默认值
【发布时间】:2012-03-18 04:13:22
【问题描述】:

我正在为 iPad 创建一个小型 Web 应用程序,并且我有几个元素通过阻止 touchmove 事件的默认设置来阻止用户滚动。但是,我有一种情况需要用户能够滚动子元素。

我曾尝试使用 e.stopPropagation();但没有运气!我还尝试检测手指下的元素并将 e.preventDefault();在 if 语句中,但同样没有运气。或者也许我只是搞混了......

有什么想法吗?从#fix div 中删除 .scroll div 确实是最后的手段,因为它会引起各种头痛。


编辑

我设法对其进行了排序。好像我不明白 .stopPropagation(); 的用法哎呀!

工作代码:

<div id="fix">

    <h1>Hi there</h1>

    <div class="scroll">
        <ul>
            <li>List item</li>
            <li>List item</li>
            <li>List item</li>
        </ul>
    </div>

    <div class="scroll">
        <ul>
            <li>List item</li>
            <li>List item</li>
            <li>List item</li>
        </ul>
    </div>

</div>

还有 Javascript:

$('body').delegate('#fix','touchmove',function(e){

    e.preventDefault();

}).delegate('.scroll','touchmove',function(e){

    e.stopPropagation();

});

【问题讨论】:

  • 尝试添加 return false;在事件处理程序结束时
  • stopPropagation 而不是 stopPropogation
  • 哈,是的,谢天谢地,我实际上在我的代码中输入正确;)
  • 您应该将您的解决方案添加为答案并接受,它对我有用。谢谢!
  • 我很困惑,你到底是怎么解决这个问题的?对于像我这样的麻木,你能指出哪个是工作代码吗?哈哈谢谢:)

标签: javascript jquery ipad touch


【解决方案1】:

试试这个:

$('#fix').on('touchmove',function(e){
    if(!$('.scroll').has($(e.target)).length)
        e.preventDefault();
});

已编辑

e.target 包含触摸事件的最终目标节点。您可以停止所有未“冒泡”您的 .scroll div 的事件。

我认为有更好的解决方案,但是这个肯定没问题。

【讨论】:

  • 我见过的最好的解决方案。 +1
【解决方案2】:

我在这里发现了一个有趣的讨论:https://github.com/joelambert/ScrollFix/issues/2bjrn 提供了一个很好的解决方案

基本上,它利用了弹性盒子。在 ipad 上为我工作得很好。这是他设置的一个测试链接,显示它在工作中:http://rixman.net/demo/scroll/

这个解决方案特别好的地方在于它全是 CSS 并且不需要 javascript。

【讨论】:

    【解决方案3】:

    这应该可行:

    $(document).on('touchmove', function(e) {
        if (!$(e.target).parents('.scroll')[0]) {
            e.preventDefault();
        }
    });
    

    【讨论】:

    • 主题指定了父元素,而不是元素本身,因此使用最接近()是不正确的。
    • 更简洁的写法是:$(document).on("touchmove", function(e) { e.preventDefault() }); $(document).on("touchmove", ".scroll", function(e) { e.stopPropagation() });
    • 这将禁用整个文档的 touchmove。如果你链接函数,你也不需要引用 $(document) 两次。
    【解决方案4】:

    我找到了另一个使用 css-classes 和 document.ontouchmove 的解决方案。 我正在开发一个带有 Sliders 的 iPad Web 应用程序,并希望在发生 touchmove 事件时防止所有其他元素反弹。 这是我作为摘要的解决方案:

    HTML:

    <body>
      <div id="outterFrame" class="fullscreen"> <!-- class fullscreen is self-explaining I guess -->
          <div id="touchmove_enabled class="enable_touchmove sliderbutton">Button</div>
      </div>
    </body>
    

    Javascript:

    /* preventDefault on touchmove events per default */
    document.ontouchmove = function(event)
    {
       var sourceElement = event.target || event.srcElement;
       if(!hasClass(sourceElement,"enable_touchmove"))
    {
       e.preventDefault();
    }
    };
    
    /* helper method "hasClass" */
    function hasClass(element,class)
    {
    if(element.className != null)
    {
        return element.className.match(new RegExp('(\\s|^)'+class+'(\\s|$)'));
    }
    return false;
    }
    

    现在,只有 div "touchmove_enabled" 的 touchmove 事件被触发。

    也许我的解决方案可能对某人有用。 帕特里克

    【讨论】:

      【解决方案5】:
      document.addEventListener('touchmove', function(e){e.preventDefault()}, false);
      document.getElementById('inner-scroll').addEventListener('touchmove', function(e){e.stopPropagation()}, false);
      

      这个想法是您的主滚动始终(由您自行决定)禁用,但在您的内部滚动中,您可以防止事件冒泡(或传播),因此它永远不会到达第一个事件侦听器,这最终会取消 touchmove 事件。

      我希望这就是您想要的。我遇到过与您类似的情况,在平板电脑上禁用了主滚动条,但我希望内部滚动条可以工作。这似乎完成了这项工作。

      【讨论】:

        猜你喜欢
        • 2015-08-14
        • 2013-11-24
        • 2019-12-26
        • 2015-08-18
        • 2018-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-30
        相关资源
        最近更新 更多