web-dev-qa-db-ja.com

親ではなく、子ではtouchmoveのデフォルトを禁止します

IPad用の小さなWebアプリを作成していますが、touchmoveイベントのデフォルトを防ぐことでユーザーがスクロールできないようにする要素がいくつかあります。ただし、ユーザーが子要素をスクロールできるようにする必要がある状況があります。

E.stopPropagation()を使用しようとしました。しかし、運はありません!また、指の下の要素を検出し、e.preventDefault()を配置しようとしました。 if文の中にありますが、これもまた運がありません。または多分私はちょうど混乱していた...

何か案は? #fix divから.scroll divを削除することは、あらゆる種類の頭痛の種となるため、本当に最後の手段です。


[〜#〜] edit [〜#〜]

なんとか整理できました。 .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();

});
24
will

これを試して:

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

[〜#〜]編集済み[〜#〜]

e.targetには、タッチイベントの最終ターゲットノードが含まれます。 .scroll divを「バブリング」していないすべてのイベントを停止できます。

より良い解決策があると思いますが、これは大丈夫です。

18
Grsmto
document.addEventListener('touchmove', function(e){e.preventDefault()}, false);
document.getElementById('inner-scroll').addEventListener('touchmove', function(e){e.stopPropagation()}, false);

メインスクロールは常に(自由裁量で)無効にされますが、内部スクロールではイベントがバブリング(または伝播)するのを防ぐため、最初のイベントリスナーに到達することはなく、最終的にtouchmoveがキャンセルされますイベント。

これがあなたが探していたものであることを願っています。メインスクロールがタブレットで無効になっているあなたと同じような状況がありましたが、内側のスクロールが機能することを望みました。これは仕事をしているようでした。

10
Prusprus

これは動作するはずです:

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

私はここで興味深い議論を見つけました: https://github.com/joelambert/ScrollFix/issues/2 、そして bjrn から良い解決策があります

基本的に、フレックスボックスを利用します。 iPadでうまく機能しました。以下に、彼が設定したテストリンクを示します。 http://rixman.net/demo/scroll/

このソリューションの特に素晴らしい点は、すべてCSSであり、javascriptが不要であることです。

2
ryan

Css-classesとdocument.ontouchmoveを使用した別のソリューションを見つけました。スライダーを使用してIPad Webappを開発していますが、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イベントのみが発生します。

おそらく私のソリューションは誰かに役立つかもしれません。パトリック

1
Patric S.