Sự khác biệt giữa document.addEventListener và window.addEventListener?


134

Khi sử dụng PhoneGap, nó có một số mã JavaScript mặc định sử dụng document.addEventListener, nhưng tôi có mã riêng sử dụng window.addEventListener:

function onBodyLoad(){
    document.addEventListener("deviceready", onDeviceReady, false);
    document.addEventListener("touchmove", preventBehavior, false);
    window.addEventListener('shake', shakeEventDidOccur, false);
}

Sự khác biệt và cái nào tốt hơn để sử dụng?

Câu trả lời:


160

Các documentwindowlà các đối tượng khác nhau và họ có một số sự kiện khác nhau. Sử dụng addEventListener()trên chúng lắng nghe các sự kiện dành cho một đối tượng khác. Bạn nên sử dụng một sự kiện thực sự có sự kiện mà bạn quan tâm.

Ví dụ, có một "resize"sự kiện trên windowđối tượng không nằm trên documentđối tượng.

Ví dụ, "DOMContentLoaded"sự kiện chỉ trên documentđối tượng.

Vì vậy, về cơ bản, bạn cần biết đối tượng nào nhận được sự kiện mà bạn quan tâm và sử dụng .addEventListener()trên đối tượng cụ thể đó.

Đây là một biểu đồ thú vị cho thấy loại đối tượng nào tạo ra loại sự kiện nào: https://developer.mozilla.org/en-US/docs/DOM/DOM_event_Vference


Nếu bạn đang nghe một sự kiện lan truyền (chẳng hạn như sự kiện nhấp chuột), thì bạn có thể nghe sự kiện đó trên đối tượng tài liệu hoặc đối tượng cửa sổ. Sự khác biệt chính duy nhất cho các sự kiện lan truyền là trong thời gian. Sự kiện sẽ đánh vào documentđối tượng trước windowđối tượng vì nó xảy ra đầu tiên trong hệ thống phân cấp, nhưng sự khác biệt đó thường là không quan trọng để bạn có thể chọn một trong hai. Tôi thấy nói chung là tốt hơn để chọn đối tượng gần nhất với nguồn của sự kiện đáp ứng nhu cầu của bạn khi xử lý các sự kiện lan truyền. Điều đó sẽ đề nghị bạn nên chọn documenthơn windowkhi một trong hai sẽ làm việc. Nhưng, tôi thường di chuyển gần hơn đến nguồn và sử dụng document.bodyhoặc thậm chí một số cha mẹ phổ biến gần gũi hơn trong tài liệu (nếu có thể).


Tôi tò mò về điều "sủi bọt lên tài liệu nhưng không phải là cửa sổ". Vì vậy, tôi đã thử nghiệm nó ở đây -> jsfiddle.net/k3qv9/1 Tôi có thiếu một cái gì đó hay sự bong bóng thực sự xảy ra?
banzomaikaka

1
@JOPLOmaceso - trước khi nhận xét của bạn, tôi đã xóa phần nói về bong bóng vì tôi không chắc chắn sự kiện nào xảy ra với cửa sổ và sự kiện nào không. Giao thức mà tôi luôn thấy là chặn tài liệu các sự kiện sủi bọt ở document.bodyđối tượng hoặc documentđối tượng để không có lý do gì để sử dụng windowcho các sự kiện sủi bọt. Trong mọi trường hợp, câu trả lời của tôi là một số sự kiện chỉ được bật windowvà một số sự kiện chỉ được bật và một số sự kiện là documentcả hai vì vậy OP nên chọn đối tượng tương ứng với sự kiện mà họ muốn xử lý.
jfriend00

Được rồi. Đó là những gì tôi thường làm quá - chính xác là lý do tại sao tôi quyết định thử nghiệm nó. Cảm ơn câu trả lời!
banzomaikaka

Vì sự kiện 'click' có sẵn trong cả tài liệu và cửa sổ và nếu chúng tôi đăng ký sự kiện trên cả tài liệu và cửa sổ thì trình xử lý nhấp chuột của tài liệu sẽ cháy trước sau đó là cửa sổ. Vì vậy, đối với quan điểm này, sự lựa chọn của tài liệu là tốt hơn. jsfiddle.net/3LcVw
viên

1
Một ví dụ khác: Nếu bạn sẽ thêm addEventListener("keydown", event)thông qua windowcho TV Samsung, thì nó sẽ không hoạt động. Nhưng bạn sẽ làm điều tương tự với document, sau đó nó sẽ. Cũng phụ thuộc vào thiết bị cụ thể như thế nào nó gọi các sự kiện sủi bọt.
Jakub Kubista

4

Bạn sẽ thấy rằng trong javascript, thường có nhiều cách khác nhau để làm cùng một thứ hoặc tìm cùng một thông tin. Trong ví dụ của bạn, bạn đang tìm kiếm một số yếu tố được đảm bảo luôn tồn tại. windowdocumentcả hai đều phù hợp với hóa đơn (chỉ với một vài khác biệt).

Từ mạng lưới mozilla dev :

addEventListener () đăng ký một trình lắng nghe sự kiện trên một mục tiêu. Mục tiêu sự kiện có thể là một thành phần duy nhất trong tài liệu, chính tài liệu, cửa sổ hoặc XMLHttpRequest.

Vì vậy, miễn là bạn có thể tin tưởng vào "mục tiêu" của mình luôn ở đó, sự khác biệt duy nhất là những sự kiện bạn đang nghe, vì vậy hãy sử dụng mục yêu thích của bạn.


5
Điều này không đúng. Các sự kiện khác nhau xảy ra trên các đối tượng khác nhau. documentwindowkhông nhận được các sự kiện tương tự. Bạn phải chọn đối tượng mà được trường hợp bạn đang quan tâm. Một số sự kiện có thể đi đến cả hai documentwindow, nhưng không phải tất cả.
jfriend00

1

Các windowràng buộc đề cập đến một đối tượng tích hợp được cung cấp bởi trình duyệt. Nó đại diện cho cửa sổ trình duyệt có chứa document. Gọi addEventListenerphương thức của nó đăng ký đối số thứ hai (hàm gọi lại) được gọi bất cứ khi nào sự kiện được mô tả bởi đối số đầu tiên của nó xảy ra.

<p>Some paragraph.</p>
<script>
  window.addEventListener("click", () => {
    console.log("Test");
  });
</script>

Các điểm sau cần được lưu ý trước khi chọn cửa sổ hoặc tài liệu để addEventListners

  1. Hầu hết các sự kiện là tương tự cho windowhay documentnhưng một số sự kiện như thế resize, và các sự kiện khác liên quan đến loading, unloadingopening/closingtất cả nên được đặt trên cửa sổ.
  2. Vì cửa sổ có tài liệu, nên sử dụng tài liệu để xử lý (nếu có thể xử lý) vì sự kiện sẽ đánh vào tài liệu trước.
  3. Internet Explorer không phản hồi với nhiều sự kiện đã đăng ký trên cửa sổ, vì vậy bạn sẽ cần sử dụng tài liệu để đăng ký sự kiện.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.