Подтвердить что ты не робот

Предотвратить по умолчанию касание родителя, но не дочернего

Я создаю небольшое веб-приложение для iPad, и у меня есть несколько элементов, которые я запрещаю прокручивать пользователю, предотвращая дефолт по событию touchmove. Однако у меня есть ситуация, когда мне нужно, чтобы пользователь мог прокручивать дочерний элемент.

Я попытался использовать e.stopPropagation(); но не повезло! Я также попытался обнаружить элемент под пальцем и поставить e.preventDefault(); внутри оператора if, но опять же, не повезло. Или, может быть, меня просто путают...

Любые идеи? Удаление div.scroll из #fix 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();

});
4b9b3361

Ответ 1

Попробуйте следующее:

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

EDITED

e.target содержит конечную цель node события касания. Вы можете остановить все события, которые не "пузырятся" над вашими div.scroll.

Я думаю, что есть лучшие решения, но это должно быть хорошо.

Ответ 2

Это должно работать:

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

Ответ 3

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

Идея состоит в том, что ваш основной прокрутки всегда (по вашему усмотрению) отключен, но в вашем внутреннем прокрутке вы предотвращаете пузыриться (или распространяете) событие, поэтому он никогда не достигнет первого прослушивателя событий, что в конечном итоге отмените событие touchmove.

Надеюсь, это то, что вы искали. У меня была ситуация, похожая на вашу, где основной прокрутки отключен на планшете, но мне нужен внутренний свиток для работы. Кажется, это работало.

Ответ 4

Я нашел интересную дискуссию здесь: https://github.com/joelambert/ScrollFix/issues/2, и там хорошее решение от bjrn

В принципе, он использует преимущества гибких ящиков. Хорошо работал у меня на ipad. Вот тестовая ссылка, которую он установил, которая показывает ее на работе: http://rixman.net/demo/scroll/

Что особенно приятно в этом решении, так это то, что все CSS и javascript не требуется.

Ответ 5

Я нашел другое решение, используя css-классы и 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;
}

Теперь выполняется только событие touchmove div "touchmove_enabled".

Возможно, мое решение может быть полезным для кого-то. Patric