2016-07-30 69 views
0

在iPad Safari(以及桌面Safari和Chrome)上,我需要在垂直滾動的頁面上有水平滑塊,滑塊不會意外移動。不幸的是,jQuery手機滑塊對iPad上的(不完美)垂直滑動做出了迴應。限制jQuery Mobile滑塊響應按住並拖動

解決此問題的一個好方法是設置滑塊,以便移動旋鈕的唯一方法是按住並拖動。下面是我砍死在一起(注:在觸摸界面這隻適用):

<!DOCTYPE html> 
<html> 
<head> 
<meta name="viewport" content="width=device-width, initial-scale=1"> 
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css"> 
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script> 
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script> 
<style> 
div.input-container { 
    -webkit-user-select: none; 
    -webkit-touch-callout: none; 
    -webkit-tap-highlight-color: rgba(0,0,0,0); 
} 
</style> 
</head> 
<body> 

<div id="top"> 
    <div> 
     <h1>Sliders for iPad</h1> 
    </div> 
    <div> 
     <label for="test1">Test:</label> 
     <div class="input-container"> 
      <input type="range" name="test1" value="50" min="0" max="100" disabled> 
     </div> 
    </div> 
    <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> 
    <div> 
     <label for="test2">Test:</label> 
     <div class="input-container"> 
      <input type="range" name="test2" value="50" min="0" max="100" disabled> 
     </div> 
    </div> 
    <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /> 
    <div> 
     <label for="test3">Test:</label> 
     <div class="input-container"> 
      <input type="range" name="test3" value="50" min="0" max="100" disabled> 
     </div> 
    </div> 
</div> 

<script> 
$(function() { 

$(".input-container").addClass("disable-drag") 
    .on("taphold", tapholdHandler) 
    .on('touchmove', moveHandler) 
    .on('touchend', endHandler) 
; 

function moveHandler(event) { 
    var containingDiv = $(".input-container"); 
    if (!containingDiv.hasClass('disable-drag')) { 
     /// 
     console.log(event); 
     $('a').offset({left: event.originalEvent.targetTouches[0].clientX}); 
     var left = 68;///parseInt($('.ui-slider-track')[0].css('margin-left')); 
     var w = event.originalEvent.target.offsetWidth - left; 
     var percent = ((event.originalEvent.targetTouches[0].clientX - left)/w) * 100; 
     $('input').val(percent).slider('refresh'); 
     /// 
    } 
} 

function tapholdHandler(event) { 
    console.log(event) 
    var containingDiv = $(".input-container"); 
    if (containingDiv.hasClass('disable-drag')) { 
     containingDiv.removeClass("disable-drag"); 
     event.preventDefault(); 
     event.stopPropagation(); 
     $('input').slider('enable').slider('refresh'); 
    } 
} 

function endHandler(event) { 
    $('input').slider('disable').slider('refresh'); 
    $(".input-container").addClass("disable-drag") 
} 

}); 
</script> 
</body> 
</html> 

直到檢測到按下並按住滑塊被禁用,此時它了生機,更新旋鈕位置用戶拖動時的值,並在觸摸結束時返回到禁用狀態。它有些作品,但太脆弱了,我不想做與滑塊已經做過的相同的計算。在///標記之間,我真的很喜歡以編程方式單擊當前鼠標位置,以便旋鈕移動到該位置 - 而不會中斷按住拖動的手勢。這可能嗎?這裏是我試過,但它不工作:

/// 
$(".ui-slider-track").trigger('click'); //todo: narrow the selector to the target slider 
/// 

/// 
$(document.elementFromPoint(event.originalEvent.targetTouches[0].clientX, event.originalEvent.targetTouches[0].clientY)).click(); 
/// 

...還是有與不垂直揮筆響應滑塊一些其他的移動UI庫?

回答

0

好的,我想出了一個相當乾淨簡單的解決方案。在iPad Safari上測試。它也使文本字段保持啓用狀態,因此可以直接編輯。

<script> 
    // The following manages the sliders so that vertical swiping (scrolling) never inadvertently changes a slider value 
    $(function() { 
     var timerId; 
     $.event.special.tap.tapholdThreshold = 250; // default is 750, but that seems too long for this scenario 

     $(".input-container") 
      .on('taphold', tapholdHandler) 
      .on('touchmove', moveHandler) 
      .on('touchend', endHandler) 
     ; 
     $('.input-container input') 
      .prop('disabled', false).removeClass('ui-state-disabled') // allow the user to edit the displayed value 
      .on('change', function() { 
       $(this).slider('refresh'); 
       $(this).prop('disabled', false).removeClass('ui-state-disabled'); // override the above line's disabling of the text field 
       $(this).blur(); 
      }) 
     ; 

     function tapholdHandler(event) { 
      $(event.currentTarget).find('input').slider('enable').slider('refresh'); 
     } 

     function moveHandler(event) { 
      if (timerId) 
       clearTimeout(timerId); // as long as the user is interacting with the slider, don't revert it to disabled 
      $(document.elementFromPoint(event.originalEvent.targetTouches[0].clientX, event.originalEvent.targetTouches[0].clientY)).trigger('vmousedown'); 
     } 

     function endHandler(event) { 
      $(document.elementFromPoint(event.originalEvent.changedTouches[0].clientX, event.originalEvent.changedTouches[0].clientY)).trigger('vmousedown').trigger('vmouseup'); // the purpose of this is to move the slider knob even if the user's touch didn't move 
      timerId = setTimeout(function() { // give the above induced event time to run the associated handler 
        $(event.currentTarget).find('input').slider('disable').slider('refresh'); 
        $(event.currentTarget).find('input').prop('disabled', false).removeClass('ui-state-disabled'); // allow the user to edit the displayed value 
      }, 2000); 
     } 
    }); 
</script>