размытие ввода, сопровождаемое слушателем события касания, иногда приводит к неправильному направлению пролистывания - в основном ваниль JS - PullRequest
0 голосов
/ 18 апреля 2020

Я использую этот код, чтобы пролистать список элементов div, используя animate, чтобы установить их отступ на странице, а затем анимировать следующий элемент div, установив его поле равным 0. Некоторые элементы div имеют входные данные. Это веб-приложение предназначено для просмотра на мобильных устройствах, поэтому, когда я сосредоточен на вводе, у меня отображается мобильная клавиатура. Если я размываю этот вход и быстро проведу пальцем, или, реже, если я проведу пальцем по входу, когда клавиатура еще не нажата, он зарегистрирует удар в неправильном направлении. Как я могу избежать этого удара в неправильном направлении?

<!DOCTYPE html>
<html>
  <head>
  <title>Driver Vehicle Inspection Report</title>
    <meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=1.0, user-scalable=0"> 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdn.rawgit.com/willowsystems/jSignature/master/libs/jSignature.min.js"></script>
    <style>
      html {
        background: url('https://images.pexels.com/photos/3787939/pexels-photo-3787939.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260') no-repeat center center fixed;
        background-size: cover;
        height: 100%;
        }
      body {
        align-items: center;
        margin-left: 10px;
        margin-right: 10px;
        font-size: 2em;
        overflow-x: hidden;
        }
      #form {
        display: flex;
        margin: auto;
        align-items: center;
        text-align: center;
        height: 750px;
        border: 1px solid black;
        border-radius: 10px;
        position: relative;
        overflow-x: hidden;
        font-size: 1.5em;
        background:rgba(255,255,255, 0.7);
        }
      #btns {
        margin: auto;
        text-align: center;
        width: 250px;
        height: 50px;
        }
      #back {
        float: left;
        }
      #next {
        float: right;
        }
      table {
        margin: auto;
        }
      .part:not(:first-child) {
        display: inline-block;
        position: absolute;
        right: 0px;
        left: 5000px;
        overflow-x: hidden;
        }
      .part:first-child {
        display: inline-block;
        position: absolute;
        right: 0px;
        left: 0px;
        overflow-x: hidden;
        }
      input[type=text],input[type=number],input[type=date],input[type=time], select {
        width: 80%;
        padding: 30px 20px;
        margin: 8px 0;
        border: 1px solid Black;
        border-radius: 10px;
        box-sizing: border-box;
        font-size: 1em;
        color: Black;
        overflow-x: hidden;
        }
    input[type=radio] {
        width: 100px;
        height: 100px;
        border: 1px solid Black;
        background-color: white;
        }
    input[type=checkbox] {
        width: 100px;
        height: 100px;
        border: 1px solid Black;
        background-color: white;
        }
    td {
        text-align: right;
        font-size: 0.8em;
        }
    </style>
  </head>
  <body>
    <div id="form">
    <div id="0" class="part">Company:<br><input id="company" type="text" class="driver" name="company"></div>
    <div id="1" class="part">Station:<br><table>
    <tr><td>PDX:</td><td><input type="radio" class="driver" id="pdx" name="address"></td></tr>
    <tr><td>EUG:</td><td><input type="radio" class="driver" id="eug" name="address"></td></tr>
    <tr><td>SEA:</td><td><input type="radio" class="driver" id="sea" name="address"></td></tr>
    <tr><td>SFO:</td><td><input type="radio" class="driver" id="sfo" name="address"></td></tr></table></div>
    <div id="2" class="part">Name:<br><input type="text" class="driver" name="name" placeholder="Your Full Name"></div>
    <div id="3" class="part">Employee Number:<br><input type="number" class="driver" name="employeeNumber" placeholder="Your Employee Number"></div>
    <div id="4" class="part">Date:<br><input type="date" id="date" class="driver" name="date"></div>
    <div id="5" class="part">Time:<br><input type="time" id="time" class="driver" name="time" value="now"></div>
    <div id="6" class="part"><h2>Vehicle Information</h2></div>
    <div id="7" class="part">Tractor/Truck Number:<br><input type="number" id="tractorTruckNumber" class="truck" name="tractorTruckNumber"></div>
    <div id="8" class="part">Odometer:<br><input type="number" id="odometer" class="truck" name="odometer"></div>
    </div>
    <div id="btns"><input type="button" id="back" onclick="nextPrev(-1);startSwipe();" value="<< Back"><input type="button" id="next" onclick="nextPrev(1);startSwipe();" value="Next >>"></div>
  </body>
  <script> 
  var currentPart = 0;
  var part = $('.part')


  checkButtons();
  var isSwiping = false;

  function startSwipe(){
    if (isSwiping){
      return false;
      }
      else {
      isSwiping = true;
      $('#back, #next').attr('disabled',true);
      return true;
      }
    }
  function endSwipe(){
    $('#back, #next').removeAttr('disabled');
    isSwiping = false;
    }

  function nextPrev(n){
      if (n === 1){
          if (currentPart !== part.length-1){
            if (currentPart === 21){
              if(!$('.truck').is(':checked')){
                $('#22').css({'left':'-5000px','right':'5000px'});
                var n = 2;
                $('.truck#remarks').val('');
                }
              }

            if (currentPart === 24){
              if(!$('#trailernumber').val()){
                $('#25, #26, #27, #28, #29').css({'left':'-5000px','right':'5000px'});
                var n = 6;
                }
              }

            if (currentPart === 28){
              if(!$('.trailer').is(':checked')){
                $('#29').css({'left':'-5000px','right':'5000px'});
                var n = 2;
                $('.trailer#remarks').val('');
                }
              }

            $('#'+currentPart+' :input').blur();
            $('#'+currentPart).filter(':not(:animated)').animate({'left':'-5000px','right':'5000px'},500,function(){
              $(this).css({'left':'-5000px','right':'5000px'});//set current left
              });//move current left
            $('#'+(currentPart+n)).delay(200).filter(':not(:animated)').animate({'left':'0','right':'0'},500,function(){
              $(this).css({'left':'0','right':'0'});//set next centered
              currentPart = currentPart + n;
              checkButtons();
              endSwipe();
              });//move next right 
            }
          else {
            endSwipe();
            }
        }
      else if (n === -1){
        if (currentPart !== 0 || screen.width < 600 && currentPart !== 2){
          if (currentPart === 23){
              if(!$('.truck').is(':checked')){
                $('#22').css({'left':'5000px','right':'-5000px'});
                var n = -2;
                $('.truck#remarks').val('');
                }
              }
          if (currentPart === 30){
              if(!$('#trailernumber').val()){
                $('#25, #26, #27, #28, #29').css({'left':'5000px','right':'-5000px'});
                var n = -6;
                }
              }
          if (currentPart === 30){
              if($('#trailernumber').val() && !$('.trailer').is(':checked')){
                $('#29').css({'left':'5000px','right':'-5000px'});
                var n = -2;
                $('.trailer#remarks').val('');
                }
              }
          $('#'+currentPart+' :input').blur();    
          $('#'+currentPart).filter(':not(:animated)').animate({'left':'5000px','right':'-5000px'},500,function(){
            $(this).css({'left':'5000px','right':'-5000px'});//set current right
            });//move current left
          $('#'+(currentPart+n)).delay(200).filter(':not(:animated)').animate({'left':'0','right':'0'},500,function(){
            $('#'+(currentPart+n)).css({'left':'0','right':'0'});//set next centered
            currentPart = currentPart + n;
            checkButtons();
            endSwipe();
            });//move next right
          }
        else {
            endSwipe();
            }
        }
      else {
        endSwipe();
        }
    }

  function checkButtons(){
    if (currentPart == 0){
      $('#back').css({'display':'none'});
      }
    else if (currentPart == part.length-1){
      $('#next').css({'display':'none'});
      }
    else {
      $('#back').css({'display':'block'});
      $('#next').css({'display':'block'});
      }
    }

document.getElementById('form').addEventListener('touchstart', handleTouchStart, false);        
document.getElementById('form').addEventListener('touchmove', handleTouchMove, false);

var xDown = null;                                                        
var yDown = null;

function getTouches(evt) {
  return evt.touches ||             // browser API
         evt.originalEvent.touches; // jQuery
}                                                     

function handleTouchStart(evt) {
  if($(event.target).attr('class') !== "jSignature") {
    if (startSwipe()){
      const firstTouch = getTouches(evt)[0];                                      
      xDown = firstTouch.clientX;                                      
      yDown = firstTouch.clientY;  
    }
  }
};                                                

function handleTouchMove(evt) {
  if($(event.target).attr('class') !== "jSignature") {
  if (isSwiping){
    if ( ! xDown || ! yDown ) {
        return;
    }
    var xUp = evt.touches[0].clientX;                                    
    var yUp = evt.touches[0].clientY;

    var xDiff = xDown - xUp;
    var yDiff = yDown - yUp;

    if ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {/*most significant*/
        if ( xDiff > 0 ) {
            nextPrev(1);
        } else {
            nextPrev(-1);
        }
    }
    else {
        if ( yDiff > 0 ) {
            endSwipe(); 
        } else { 
            endSwipe();
        }
    }
    /* reset values */
    xDown = null;
    yDown = null;
  }
  }
};


  </script>
</html>

(я пытался свести его к лучшему MCVE, я извиняюсь за его длину)

...