mobilestoppropagationtouchmove

stopPropagation sometimes doesn't


I am trying to do three things:

  1. prevent auto focus of input on mobile

  2. prevent the webpage from moving on mobile

  3. allow touch movement on <ul>

    To prevent auto focus of input on mobile:
    a) add readonly to input tags
    b) add <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" /> 
    
    To prevent the webpage from moving on mobile:
    a) function preventBehavior(e) {
         e.preventDefault(); 
       };
       document.addEventListener("touchmove", preventBehavior, {passive: false}); 
    
    To allow touch movement on <ul> on mobile:
    a) function allowBehavior(e){                   
         e.stopPropagation()
       }
       let tp = document.getElementsByClassName('ui-timepicker-viewport')    
       tp[0].addEventListener("touchmove", allowBehavior);
    

This all seems to work most of the time. Occasionally, when scrolling the the <li> elements the entire screen moves. How do I stop that behavior?

NOTE: inputs with class='timepicker' are used by the js timepicker library that places a dropdown with li elements. See link and use on a mobile device to duplicate behavior.

Here's a link to the page https://sailwbob.com/lagin/views/test_form.html

<head>
    <title>Reservation</title>
    <link rel="stylesheet" href="../public/css/header.css">
    <link rel="icon" type="image/png" href="../favicon.png">
    <script src="../public/js/header.js" type="text/javascript"></script>
   <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />

    
    <style>
    input[type="submit"] { -webkit-appearance:none; -webkit-border-radius:45%;-webkit-width:35vw; }
</style>
   
</head>


<body style="margin-top:0px;">
    <div class='container'>
        <img id='swb' src="../public/images/swb.png" alt="SwB">
        <div class='img-container'>
            <img class='lround small' src="../public/images/img-1.png" alt="img-1">
            <img class='small' src="../public/images/img-2.png" alt="img-2">
            <img class='small' src="../public/images/img-3.png" alt="img-3">
            <img class='small' src="../public/images/img-4.png" alt="img-4">
            <img class='small' src="../public/images/img-5.png" alt="img-5">
            <img class='rround small' src="../public/images/img-6.png" alt="img-6">
        </div>

        <link rel="stylesheet" href="../public/css/test.css">

        <div id='res'>
            <div id='left' class='cols'>
                <p class='narrow'>Date</p>
                <p class='bold'>May 11</p>
                <p class='narrow'>&nbsp;</p>
                <p class='narrow'>Reservation</p>
                <p class='narrow'>Sail Time</p>
                <p class='narrow'>Crew Time</p>
            </div>
            <div id='center' class='cols'>
                <p class='narrow'>Skipper</p>
                <p class='bold'>Bob Smith</p>
                <p class='narrow'>Start Time</p>
                <p class='narrow bold'>09:00 AM</p>
                <p class='narrow bold'>TBD</p>
                <div class='inputWrapper'>
                    <input id='timeStart' class='timepicker' type='text' name='startTime' readonly>
                    <p id='w0' class='warning'>enter availability</p>
                </div>
            </div>
            <div id='right' class='cols'>
                <p class='narrow'>Boat</p>
                <p class='bold'>Syrena 40</p>
                <p class='narrow'>End Time</p>
                <p class='narrow bold'>09:00 PM</p>
                <p class='narrow bold'>TBD</p>
                <div class='inputWrapper'>
                    <input id='timeEnd' class='timepicker' type='text' name='startTime' readonly>
                    <p id='w1' class='warning'>end time > start time</p>
                </div>
            </div>
        </div>
        <div id='bottom'>
            <p id='bottomLeft' class='narrow'>Crew Status</p>
            <p id="bottomRight" class='narrow bold'>OUT</p>
        </div>
        <div id='submit'>
            <div id='spacer'>&nbsp;</div>
            <div id='update'>
                <a style="text-decoration:none;" href="#" onclick="window.location='mailto:rslotpole@gmail.com ?subject=Note to Skipper'; return false;">
                    <img src="../public/images/email-48.png" style="width:48px;height:48px;border:0;">
                </a>
                <input type='submit' value='update'  />
                <a style="text-decoration:none" href="tel:(617) 943-5119">
                    <img src="../public/images/phone-48.png" style="width:48px;height:48px;border:0;">
                </a>
            </div>
        </div>
    </div>
        <link rel="stylesheet" href="../public/css/timepicker/jquery.timepicker133.min.css">
        <script src="../public/js/timepicker/jquery-3.6.0.js"></script>
        <script src="../public/js/timepicker/jquery.timepicker134.min.js"></script>
        <script src="../public/js/test.js"></script>

         <script>
    function preventBehavior(e) {
       e.preventDefault(); 
    };
    document.addEventListener("touchmove", preventBehavior, {passive: false});
    
    function allowBehavior(e){
        console.log(e.target)
       
       e.stopPropagation()
    }

    let tp = document.getElementsByClassName('ui-timepicker-viewport')

    
     tp[0].addEventListener("touchmove", allowBehavior);
    
    
    
    
    
    
    
    </script>


</body>


Solution

  • Try using the css:

    .ui-timepicker-viewport {
      overscroll-behavior: none
    }
    
    body {
      overscroll-behavior: none
    }
    

    or the javascript:

    [...document.getElementsByClassName('ui-timepicker-viewport')].forEach(element => element.style.overscrollBehavior = "none");
    document.body.style.overscrollBehavior = "none";