2013-11-15 43 views
5

Tôi có một thiết lập đơn giản GWT để thử nghiệm:Chức năng GWT sinkEvent hoạt động như thế nào?

<g:HTMLPanel ui:field="container" width="500px" height="300px"> 
    <g:Label ui:field="inner" text="hello"></g:Label> 
</g:HTMLPanel> 

Với bộ xử lý thêm:

container.addDomHandler(new ClickHandler() 
{ 
    @Override 
    public void onClick(ClickEvent event) 
    { 
     Window.alert("click on container"); 
    } 
}, ClickEvent.getType()); 

inner.addDomHandler(new ClickHandler() 
{ 
    @Override 
    public void onClick(ClickEvent event) 
    { 
     Window.alert("click on inner"); 
    } 
}, ClickEvent.getType()); 

Mỗi AddHandler gọi, như chúng ta biết từ các nguồn khác nhau,

DOM. sinkEvents (Element elem, int eventBits)

bên trong, và sau, theo tài liệu, "Đặt tập hợp sự kiện hiện tại bị đánh chìm bởi một phần tử đã cho. Những sự kiện này sẽ được kích hoạt cho {@link EventListener} gần nhất được chỉ định trên bất kỳ cha mẹ của phần tử nào. "

Nhưng thực tế, nếu bạn nhấp vào div bên trong, nhấp chuột sẽ được kích hoạt đến div mẹ của nó trong bất kỳ 3 cách:

  • nếu tôi đã không đặt bất kỳ ClickHandlers trên con

  • nếu tôi đã thiết lập xử lý trên con

  • nếu tôi đã thiết lập các bộ xử lý, nhưng xóa các đánh chìm ClickEv ent với

DOM.sinkEvents (inner.getElement(), DOM.getEventsSunk (getElement()) & ~ Event.getTypeInt (ClickEvent.getType() getName()).);

Tại sao điều này xảy ra và vai trò thực sự của việc đánh chìm sự kiện là gì? Tại sao việc thêm Trình xử lý có liên quan đến các sự kiện chìm, tức là để kích hoạt sự kiện tương tự cho phụ huynh của phần tử đã cho? Có thể ngăn chặn tất cả các trình xử lý, được thêm vào tiện ích con đã gọi mà không xóa chúng một cách rõ ràng không? I E. có cách nào để ngừng xử lý tất cả các sự kiện trên một số tiện ích không?

Trả lời

7

Đầu tiên, sinkEvent là về cách thêm trình xử lý sự kiện gốc vào phần tử, như được giải thích trong GWT wiki.

Điều bạn đang thấy là sự kiện sôi nổi, đó là cách sự kiện hoạt động trong trình duyệt: có 2 giai đoạn khi gửi một sự kiện: giai đoạn chụp (không được triển khai trong IE cũ) cho phép bất kỳ phần tử tổ tiên nào nắm bắt sự kiện trước đó đạt được mục tiêu của nó, sau đó trong pha sủi bọt sự kiện bong bóng lên cấu trúc phân cấp DOM. Vì vậy, nếu bạn nghe các nhấp chuột vào số HTMLPanel, bạn cũng sẽ nhận được các sự kiện nhấp nháy bọt từ Label.

Bạn có thể ngăn điều đó bằng cách nghe sự kiện ở cấp độ Label và gọi số stopPropagation() để nó không phát ra tối đa HTMLPanel.

+0

Cảm ơn, Thomas. Nhưng nếu tôi muốn ngăn chặn bất kỳ sự kiện nào từ việc xử lý ngay cả trên cấp độ Nhãn - có vẻ như tất cả những gì tôi cần là không ra khỏi sunkEvents qua DOM.sinkEvents (label.getElement(), 0), tôi có đúng không? Và tôi có thể dễ dàng chuyển đổi nó trở lại bằng cách thêm bitmap ClickEvent, mà không cần thêm/gỡ bỏ các trình xử lý. – KutaBeach

+0

Đó là công việc nhưng là một hack xấu xí lớn! Làm thế nào về chỉ cần thử nghiệm trong xử lý sự kiện cho dù bạn có một số công việc để làm hay không (tức là cho dù bạn đang bị vô hiệu hóa hay không)?'sinkEvents' thực sự là một API cấp thấp chỉ nên được sử dụng trong các widget nội bộ; không gây rối với các vật dụng khác hoặc bạn có thể sẽ phá vỡ chúng. –

+0

Đó là những gì tôi đã làm - được thêm vào nếu mệnh đề trong tất cả các trình xử lý sự kiện của tôi để ngăn sự kiện được xử lý khi tiện ích của tôi bị tắt. Tuy nhiên, việc sao chép cùng một 'if' trong 5 trình xử lý cũng không có vẻ tốt như vậy, thật ra ..:/ – KutaBeach

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