Prevent touchmove default on parent but not child

will picture will · Feb 28, 2012 · Viewed 45.7k times · Source

I am creating a little web app for the iPad and I've got several elements I am preventing the user from scrolling by preventing default on the touchmove event. However, I have a situation where I need the user to be able to scroll a child element.

I have tried to use e.stopPropagation(); but no luck! I also attempted to detect the element under the finger and put the e.preventDefault(); inside an if statement, but again, no luck. Or maybe I was just getting mixed up...

Any ideas? Removing the .scroll divs from the #fix div is a last resort really as it will cause all sorts of headaches.


EDIT

I managed to sort it. Seems like I didn't understand the use of .stopPropagation(); oops!

The working code:

<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>

And the Javascript:

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

    e.preventDefault();

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

    e.stopPropagation();

});

Answer

adriendenat picture adriendenat · Feb 28, 2012

Try this:

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

EDITED

e.target contains the final target node of the touch event. You can stop all events that are not "bubbling accross" your .scroll divs.

I think there are better solutions, but this one must be ok.