2012-02-28 25 views
24

Tôi đang tạo một ứng dụng web nhỏ cho iPad và tôi có một số yếu tố tôi ngăn người dùng di chuyển bằng cách ngăn mặc định trên sự kiện touchmove. Tuy nhiên, tôi có một tình huống mà tôi cần người dùng có thể cuộn một phần tử con.Ngăn chặn touchmove mặc định trên cha mẹ nhưng không phải con

Tôi đã cố gắng sử dụng e.stopPropagation(); nhưng không may mắn! Tôi cũng cố gắng phát hiện phần tử dưới ngón tay và đặt e.preventDefault(); bên trong một tuyên bố nếu, nhưng một lần nữa, không có may mắn. Hoặc có thể tôi vừa bị trộn lẫn ...

Bất kỳ ý tưởng nào? Loại bỏ các divs .scroll từ div #fix là một phương sách cuối cùng thực sự vì nó sẽ gây ra tất cả các loại nhức đầu.


EDIT

tôi quản lý để sắp xếp nó. Có vẻ như tôi không hiểu việc sử dụng .stopPropagation(); oops!

Mã làm việc:

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

Và Javascript:

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

    e.preventDefault(); 

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

    e.stopPropagation(); 

}); 
+0

Thử thêm trả về false; vào cuối xử lý sự kiện – jancha

+0

ghi ** stopPropagation ** thay vì ** stopPropogation ** – udidu

+0

Ha, yea, may mắn là tôi đã thực sự nhập chính xác mã của mình;) – will

Trả lời

16

Hãy thử điều này:

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

EDITED

e.target chứa nút đích cuối cùng của sự kiện cảm ứng. Bạn có thể dừng tất cả các sự kiện không "bong bóng trên" các div .scroll của bạn.

Tôi nghĩ rằng có những giải pháp tốt hơn, nhưng điều này phải là ok.

+0

Giải pháp tốt nhất mà tôi từng thấy. +1 – EoghanTadhg

2

Tôi tìm thấy một cuộc thảo luận thú vị ở đây: https://github.com/joelambert/ScrollFix/issues/2, và có một giải pháp tốt từ bjrn

Về cơ bản, nó tận dụng hộp flex. Làm việc tốt cho tôi trên ipad. Đây là một liên kết thử nghiệm mà anh ta đã thiết lập hiển thị nó tại nơi làm việc: http://rixman.net/demo/scroll/

Điều đặc biệt thú vị về giải pháp này là tất cả CSS và javascript không cần thiết.

+0

Điều này trông rất thú vị, tôi sẽ xem xét, cảm ơn! – will

8

này nên làm việc:

$(document).on('touchmove', function(e) { 
    if (!$(e.target).parents('.scroll')[0]) { 
     e.preventDefault(); 
    } 
}); 
+0

upvoted bạn, mặc dù tôi thích '.closest (selector)' –

+0

Đối tượng xác định cha mẹ, không phải là phần tử chính nó, do đó, sử dụng gần nhất() sẽ không chính xác. – nick

+0

Cách viết gọn gàng hơn là: '$ (tài liệu) .on (" touchmove ", hàm (e) {e.preventDefault()}); $ (tài liệu) .on ("touchmove", ".scroll", function (e) {e.stopPropagation()}); ' – gwendall

1

Tôi tìm thấy một giải pháp sử dụng css-lớp học và document.ontouchmove. Tôi đang phát triển một ứng dụng Web iPad với Thanh trượt và muốn ngăn chặn tất cả các thành phần khác bị trả lại khi có sự kiện touchmove. Đây là giải pháp của tôi như là một bản tóm tắt:

HTML:

<body> 
    <div id="outterFrame" class="fullscreen"> <!-- class fullscreen is self-explaining I guess --> 
     <div id="touchmove_enabled class="enable_touchmove sliderbutton">Button</div> 
    </div> 
</body> 

Javascript:

/* preventDefault on touchmove events per default */ 
document.ontouchmove = function(event) 
{ 
    var sourceElement = event.target || event.srcElement; 
    if(!hasClass(sourceElement,"enable_touchmove")) 
{ 
    e.preventDefault(); 
} 
}; 

/* helper method "hasClass" */ 
function hasClass(element,class) 
{ 
if(element.className != null) 
{ 
    return element.className.match(new RegExp('(\\s|^)'+class+'(\\s|$)')); 
} 
return false; 
} 

Bây giờ, chỉ có sự kiện touchmove của div "touchmove_enabled" bị sa thải.

Có lẽ giải pháp của tôi có thể hữu ích cho ai đó. Patric

7
document.addEventListener('touchmove', function(e){e.preventDefault()}, false); 
document.getElementById('inner-scroll').addEventListener('touchmove', function(e){e.stopPropagation()}, false); 

Ý tưởng là cuộn chính của bạn luôn luôn là (theo ý bạn) tàn tật, nhưng trong bạn nội di chuyển bạn ngăn chặn các sự kiện từ bọt lên (hoặc tuyên truyền), vì vậy nó sẽ không bao giờ đạt được là người đầu tiên người nghe sự kiện, điều này cuối cùng sẽ hủy sự kiện touchmove.

Tôi hy vọng đây là những gì bạn đang tìm kiếm. Tôi đã có một tình huống tương tự như của bạn, nơi di chuyển chính đã bị vô hiệu hóa trên máy tính bảng, nhưng tôi muốn có một cuộn bên trong để làm việc. Điều này dường như làm công việc.

Các vấn đề liên quan