2012-06-13 40 views
9

Tôi đang sử dụng hammer.js và có vẻ như tôi event.stopPropagation() không hoạt động với sự kiện nhấn.stopPropagation() với sự kiện nhấn

Nếu tôi nhấp vào con, sự kiện được liên kết được kích hoạt nhưng sự kiện của phụ huynh cũng được kích hoạt và tôi không muốn điều đó.

$('#parent').hammer().bind('tap', function(e) { 
    $(this).css('background', 'red'); 
});​​​​​​​​ 

$('#child').hammer().bind('tap', function(e) { 
    e.stopPropagation(); 
    $(this).css('background', 'blue'); 
}); 

Dưới đây là một ví dụ: http://jsfiddle.net/Mt9gV/

Tôi cũng đã cố gắng với jGestures và vấn đề này có vẻ là như vậy. Làm thế nào tôi có thể đạt được kết quả này với một trong những thư viện đó? (hoặc một số khác nếu cần)

+0

Tôi nghĩ rằng nó có thể có một cái gì đó để làm với thực tế là bạn đã thiết lập các công cụ "búa" trên cả hai phụ huynh và các yếu tố con. Tôi không chắc chắn 100%. – Pointy

+0

Thật không may nếu tôi không áp dụng búa cho cả hai yếu tố, sự kiện nhấn sẽ không hoạt động. – TimPetricola

Trả lời

8

Như đã đề cập trong các bình luận khác, người ta sẽ mong đợi, như bạn đã làm, đó gọi event.stopPropagation() sẽ là tất cả những gì yêu cầu dừng sự kiện này khỏi sủi bọt lên cha mẹ.

Chi tiết: Tuy nhiên, trong Hammer.js thì không phải như vậy. Hammer tạo ra một máy trạng thái cử chỉ mới cho mỗi phần tử mà bạn gọi là $(el).hammer(). Vì vậy, khi một sự kiện cảm ứng được kích hoạt trên trình duyệt của trẻ, nó sẽ được xử lý trước tiên bởi logic cho trẻ và sau đó một lần nữa bằng logic trên bố mẹ. Để ngăn chặn phụ huynh nhận được sự kiện nhấn, bạn phải ngăn máy trạng thái búa của phụ huynh nhận được sự kiện chạm ban đầu. Nói chung, gọi số event.stopPropagation() cũng sẽ ngừng tuyên truyền sự kiện ban đầu. Tuy nhiên, sự kiện tap của hammer.js được kích hoạt trên touchend nhưng originalEvent là sự kiện được lưu trong bộ nhớ cache touchstart. Do đó, việc dừng tuyên truyền trên sự kiện ban đầu không có hiệu lực bởi vì sự kiện touchstart từ lâu đã sôi nổi thông qua DOM.

Giải pháp? Tôi tin rằng đây là lỗi trong búa - gửi yêu cầu kéo sửa lỗi originalEvent trong sự kiện nhấn. Khi những người khác đã đề xuất bạn có thể kiểm tra mục tiêu của sự kiện, nhưng đó luôn là yếu tố gốc - một lỗi khác theo ý kiến ​​của tôi. Vì vậy, thay vào đó hãy kiểm tra event.originalEvent.target. Dưới đây là một số JS fiddle với giải pháp tầm thường này được triển khai: http://jsfiddle.net/HHRHR/

+5

Lưu ý: Câu trả lời của tôi cho câu hỏi này đã lỗi thời - hammer.js đã được thay đổi đáng kể kể từ khi bài đăng này được đăng. – rharper

+0

Chúng tôi sử dụng mã gần giống với đoạn mã gốc của TimPetricola. Tôi có thể xác nhận nó hoạt động như mong đợi với Hammer.JS - v1.0.5 - 2013-04-07. Có vẻ như Hammer.js đã xem xét vấn đề này một cách nghiêm túc và sửa nó. – Douwe

0

Nếu bạn không thể làm việc này .. chỉ cần gọi phương thức khác trên vòi nước sau khi xác minh cần thiết (arguments.callee là nơi tôi sẽ bắt đầu trong trường hợp này), điều này sẽ có những lợi ích gia tăng của cho phép người dùng khác treo nút cũng ...

function myFn(a) { if(a) $(this).css('background', 'red'); else $(this).css('background', 'blue');}

$('#parent').hammer().bind('tap', function(e) { 
    //Check arguments.callee or other data in event and call myFn 
});​​​​​​​​ 

$('#children').hammer().bind('tap', function(e) { 
    //Same here 
}); 
+3

Tôi không hiểu những từ đó theo thứ tự đó ... –

+2

'arguments.callee' là [hiện không được chấp nhận] (https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments/callee) –

+0

I sẽ tưởng tượng rằng chỉ ở chế độ Nghiêm ngặt ... https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments/callee và tôi sẽ không để một điều nhỏ như vậy ngăn tôi hoàn thành nhiệm vụ trong tầm tay. .. sử dụng điều này và quay trở lại vấn đề khi bạn đã hoàn thành. – Jay

0

Bạn có thể thử kiểm tra e.currentTarget (hoặc là nó e.target?) bên trong handler cha mẹ để tìm ra các yếu tố được khai thác ; nếu đó là phần tử con thì chỉ cần quay lại ngay lập tức, tiếp tục với hàm.

+0

Ý tưởng hay nhưng nó trả lại phần tử gốc ngay cả khi tôi nhấp vào con. – TimPetricola

+0

Hmmm. Tôi nghi ngờ rằng Hammer thực sự liên kết với đối tượng 'window' để thực hiện tất cả các tính toán của nó, làm việc trên các tọa độ X/Y toàn cục của một sự kiện chạm và sau đó xác định yếu tố nào được nhấn từ đó. Trong trường hợp đó, stopPropagation sẽ không có hiệu lực. Nhưng tôi chỉ đoán nhanh từ [nguồn Hammer.js] (https://github.com/EightMedia/hammer.js/blob/master/hammer.js)! –

3

Vì tôi không thể nhận được tác phẩm này, tôi đã sử dụng một biến để biết sự kiện con đã được kích hoạt chưa. Nó hoạt động khá tốt với jGestures (Tôi chưa thử với hammer.js)

var childTriggered = false; 

$('#child').bind('tapone', function(e) { 
    $(this).css('background', 'red'); 
    childTriggered = true; 
}); 

$('#parent').bind('tapone', function(e) { 
    if(childTriggered) { 
     childTriggered = false; 
     return;     
    } 
    $(this).css('background', 'blue'); 
}); 

+1

Tôi có thể xác nhận rằng logic này cũng hoạt động với hammer.js. –

3

Tôi gặp sự cố tương tự với sự kiện chạm.

Tôi giải quyết nó bằng cách sử dụng

return false; 

mà là giống như gọi e.preventDefault(); e.stopPropagation();

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