2015-06-24 46 views
1
頁面

的默認垂直滾動我已經創造了我想要實現codepen水平拖動阻擋

我創建與一對夫婦水平拖動項目的時間表概述。在jqueryjquery-ui旁邊,我還使用jquery-ui-touch-punch使移動設備上的所有手勢成爲可能。在桌面上一切正常,但不是在手機上。

不幸的是$(".timeLineItemContainer").draggable({ ... });非常積極的,它也吞下我這會導致頁面垂直滾動行爲,其中,當我接觸的項目1,我不能向下滾動移動

不知怎的,我需要啓用或禁用項目的拖累能力,這取決於我的滾動操作的方向。當我禁用在jquery-ui-touch-punch.jsevent.preventDefault();它滾動下來,才把clickhorizontal move無法正常工作(在手機上水平輕掃指history.goback,我想阻止,因爲我需要爲我的手勢)。

總結的東西了:我要的是防止默認行爲,除了垂直滾動。

任何想法如何實現這一目標?或者有沒有其他的想法/方法來實現這一點?

Here's a link for a mobile version

HTML(多個項目只是一個簡單的列表)

 <div class="timeLineItemContainer"> 
     <div class="subItemMiddleContainer"> 
      <div class="timeLineHeader"> 
       <div> 
        <span>A TITLE</span> 
       </div> 
       <div> 
        <div>Some other text text</div> 
       </div> 
      </div> 
     </div> 
     <div class="subItemBottomContainer"> 
      <ul> 
       <li class="static"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="info">Thu 12 March</span> 
        </div> 
       </li> 
       <li class="static"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="label">some additional text</span> 
         <span class="info time strikethrough">bla</span> 
         <div class="info time attention"> 
          <span>yup</span> 
         </div> 
        </div> 
       </li> 
       <li class="toggable closed"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="label">Text</span> 
         <span class="info">content</span> 
        </div> 
       </li> 
       <li class="toggable closed"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="label">title</span> 
         <span class="info">value</span> 
        </div> 
       </li> 
       <li class="toggable closed"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="label">Another title</span> 
         <span class="info">another value</span> 
        </div> 
       </li> 
       <li class="static"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="label">always visible</span> 
         <span class="info time strikethrough">just because</span> 
         <div class="info attention"> 
          <span>attention!</span> 
         </div> 
        </div> 
       </li> 
      </ul> 
     </div> 
    </div> 
    <div class="timeLineItemContainer"> 
     <div class="subItemMiddleContainer"> 
      <div class="timeLineLeft"> 
       <div class="timeLinePipe"></div> 
      </div> 
      <div class="timeLineHeader"> 
       <div> 
        <span>Some other text</span> 
       </div> 
       <div> 
        <div>Ola!</div> 
       </div> 
      </div> 
     </div> 
     <div class="subItemBottomContainer"> 
      <ul> 

       <li class="static"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="info">A date</span> 
        </div> 
       </li> 
       <li class="toggable closed"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="label">label</span> 
         <span class="info">value</span> 
        </div> 
       </li> 
       <li class="toggable closed"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="label">anotehr label</span> 
         <span class="info time">different value</span> 
        </div> 
       </li> 
      </ul> 
     </div> 
    </div> 
    <div class="timeLineItemContainer"> 
     <div class="subItemMiddleContainer"> 
      <div class="timeLineHeader"> 
       <div> 
        <span>A TITLE</span> 
       </div> 
       <div> 
        <div>Some other text text</div> 
       </div> 
      </div> 
     </div> 
     <div class="subItemBottomContainer"> 
      <ul> 
       <li class="static"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="info">Thu 12 March</span> 
        </div> 
       </li> 
       <li class="static"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="label">some additional text</span> 
         <span class="info time strikethrough">bla</span> 
         <div class="info time attention"> 
          <span>yup</span> 
         </div> 
        </div> 
       </li> 
       <li class="toggable closed"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="label">Text</span> 
         <span class="info">content</span> 
        </div> 
       </li> 
       <li class="toggable closed"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="label">title</span> 
         <span class="info">value</span> 
        </div> 
       </li> 
       <li class="toggable closed"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="label">Another title</span> 
         <span class="info">another value</span> 
        </div> 
       </li> 
       <li class="static"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="label">always visible</span> 
         <span class="info time strikethrough">just because</span> 
         <div class="info attention"> 
          <span>attention!</span> 
         </div> 
        </div> 
       </li> 
      </ul> 
     </div> 
    </div> 
    <div class="timeLineItemContainer"> 
     <div class="subItemMiddleContainer"> 
      <div class="timeLineLeft"> 
       <div class="timeLinePipe"></div> 
      </div> 
      <div class="timeLineHeader"> 
       <div> 
        <span>Some other text</span> 
       </div> 
       <div> 
        <div>Ola!</div> 
       </div> 
      </div> 
     </div> 
     <div class="subItemBottomContainer"> 
      <ul> 

       <li class="static"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="info">A date</span> 
        </div> 
       </li> 
       <li class="toggable closed"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="label">label</span> 
         <span class="info">value</span> 
        </div> 
       </li> 
       <li class="toggable closed"> 
        <div class="timeLineRight timeLineInfo"> 
         <span class="label">anotehr label</span> 
         <span class="info time">different value</span> 
        </div> 
       </li> 
      </ul> 
     </div> 
    </div> 

的Javascript

var sw = screen.width; 
var thresholdPercentageSwipeTimeLineItem = 15; 
var thresholdPercentageSwipeDetailScreen = 10;  

$(".timeLineItemContainer").draggable({ 
    scroll: false, 
    axis: "x", 
    drag: function (event, ui) { 
     if (ui.position.left < 0) { 
      ui.position.left = 0; 
     } 
     else { 
      if (calculateOffsetPercentage(ui.position.left) > thresholdPercentageSwipeTimeLineItem) { 
       return false; 
      }; 
     } 
    }, 
    stop: function (event, ui) { 
     $(this).animate({ 
      left: 0, 
     }, { 
      duration: 200, 
      queue: false 
     }); 
    } 
}).click(function() { 
    var nextObjs = $(this).toggleClass("visible").find(".toggable"); 

    $.each(nextObjs, function() { 
     $(this).stop().animate({ 
      height: "toggle", 
      queue: false 
     }).toggleClass("closed"); 
    }); 

}); 

function calculateOffsetPercentage(screenValue) { 
    return (100/(sw/screenValue)); 
} 

回答

0

釘它!

首先想到它看起來像$(".timeLineItemContainer").draggable({ ... });正在消耗所有的事件,但實際上它是jquery-ui-touch-punch.js誰阻止了一切。

jquery-ui-touch-punch.js作品中,所有的觸摸事件,結果被避免,從而執行默認行爲的一種方式。因此我調整了jquery-ui-touch-punch.js以獲得正確的行爲。

  1. 我從simulateMouseEvent()函數中刪除了event.preventDefault()

  2. 我觸摸的開始存儲在mouseProto._touchStart事件

    tsx = event.originalEvent.touches[0].clientX; tsy = event.originalEvent.touches[0].clientY;

  3. 我添加mouseProto._touchMove事件內的條件,以檢查是否我在水平或垂直方向上正在滾動。如果是水平方向,我正在執行event.preventDefault()。爲了得到這一點,你可以使用:

    // Higher then 1 means a (more) horizontal direction // Lower then 1 means a (more) vertical direction // 1 is an exact 45 degrees swipe, which will be handled as a vertical swipe if ((Math.abs(CurrentX - StartX))/Math.abs(CurrentY - StartY) > 1) { event.preventDefault(); }

mouseProto._touchStart的endresult和mouseProto._touchMove功能是這樣的:

var tsx = 0, 
    tsy = 0, 
    currentx = 0, 
    currenty = 0; 

mouseProto._touchStart = function (event) { 
    var self = this; 

    tsx = event.originalEvent.touches[0].clientX; 
    tsy = event.originalEvent.touches[0].clientY; 

    // Ignore the event if another widget is already being handled 
    if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) { 
     return; 
    } 

    // Set the flag to prevent other widgets from inheriting the touch event 
    touchHandled = true; 

    // Track movement to determine if interaction was a click 
    self._touchMoved = false; 

    //// Simulate the mouseover event 
    simulateMouseEvent(event, 'mouseover'); 

    //// Simulate the mousemove event 
    simulateMouseEvent(event, 'mousemove'); 

    // Simulate the mousedown event 
    simulateMouseEvent(event, 'mousedown'); 

}; 

mouseProto._touchMove = function (event) { 
    // Ignore event if not handled 
    if (!touchHandled) { 
     return; 
    } 

    // Higher then 1 means a (more) horizontal direction 
    // Lower then 1 means a (more) vertical direction 
    // 1 is an exact 45 degrees swipe, which will be handled as a vertical swipe 
    if ((Math.abs(event.originalEvent.changedTouches[0].clientX - tsx))/Math.abs(event.originalEvent.changedTouches[0].clientY - tsy) > 1) { 
     event.preventDefault(); 
    } 

    // Interaction was not a click 
    this._touchMoved = true; 

    // Simulate the mousemove event 
    simulateMouseEvent(event, 'mousemove'); 
}; 
0

我嘗試了有機磷農藥的解決方案,但我認爲jQuery UI draggable自您上次發佈此帖後可能已更改。在我的測試中,即使在完全刪除jquery-ui-touch-punch.js之後,我發現拖動事件仍然被jQuery UI draggable佔用。我不想深入研究jQuery UI代碼並分解庫,所以我設計了一個相當簡單的替代方案。

在我的場景中,我有一個收件箱列表,其中的項目可以拖動到左側或右側以顯示操作按鈕。整個收件箱項目必須是可拖動的 - 所以拖動手柄的使用不是一個選項。

如果觸摸是在draggable元素內啓動的,則jQuery的draggable可防止觸摸屏上的垂直滾動。因此,如果屏幕上充滿了可拖動的收件箱項目,那麼用戶將陷入困境 - 無法向上或向下滾動。

爲我工作的解決辦法是測量光標的垂直位置的變化,並使用window.scrollBy相同的量,手動滾動窗口:

var firstY = null;  
var lastY = null; 
var currentY = null; 
var vertScroll = false; 
var initAdjustment = 0; 

// record the initial position of the cursor on start of the touch 
jqDraggableItem.on("touchstart", function(event) { 
    lastY = currentY = firstY = event.originalEvent.touches[0].pageY; 
}); 

// fires whenever the cursor moves 
jqDraggableItem.on("touchmove", function(event) { 
    currentY = event.originalEvent.touches[0].pageY; 
    var adjustment = lastY-currentY; 

    // Mimic native vertical scrolling where scrolling only starts after the 
    // cursor has moved up or down from its original position by ~30 pixels. 
    if (vertScroll == false && Math.abs(currentY-firstY) > 30) { 
     vertScroll = true; 
     initAdjustment = currentY-firstY; 
    } 

    // only apply the adjustment if the user has met the threshold for vertical scrolling 
    if (vertScroll == true) { 
     window.scrollBy(0,adjustment + initAdjustment); 
     lastY = currentY + adjustment; 
    } 

}); 

// when the user lifts their finger, they will again need to meet the 
// threshold before vertical scrolling starts. 
jqDraggableItem.on("touchend", function(event) { 
    vertScroll = false; 
}); 

一個觸摸屏設備上這將密切模擬天然滾動。

+0

請問您可以爲此創建一個jsfiddle,謝謝! –