Предотвратить по умолчанию касание родителя, но не дочернего
Я создаю небольшое веб-приложение для 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();
});
Ответы
Ответ 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