Xử lý sự kiện trong javascript với ví dụ

Một số chương trình hoạt động với đầu vào trực tiếp của người dùng, chẳng hạn như hành động của chuột và bàn phím. Loại đầu vào đó không có sẵn dưới dạng cấu trúc dữ liệu được tổ chức tốt—nó xuất hiện từng phần một, theo thời gian thực và chương trình dự kiến ​​sẽ phản hồi nó khi nó xảy ra

xử lý sự kiện

Hãy tưởng tượng một giao diện mà cách duy nhất để biết liệu một phím trên bàn phím có được nhấn hay không là đọc trạng thái hiện tại của phím đó. Để có thể phản ứng với các lần nhấn phím, bạn sẽ phải liên tục đọc trạng thái của phím để bắt được nó trước khi nó được nhả ra lần nữa. Sẽ rất nguy hiểm khi thực hiện các tính toán tốn nhiều thời gian khác vì bạn có thể bỏ lỡ một lần nhấn phím

Một số máy nguyên thủy xử lý đầu vào như thế. Một bước tiến lên từ điều này là phần cứng hoặc hệ điều hành sẽ nhận thấy thao tác nhấn phím và đặt nó vào hàng đợi. Sau đó, một chương trình có thể định kỳ kiểm tra hàng đợi cho các sự kiện mới và phản ứng với những gì nó tìm thấy ở đó

Tất nhiên, nó phải nhớ xem hàng đợi và làm điều đó thường xuyên, bởi vì bất kỳ khoảng thời gian nào giữa phím được nhấn và chương trình nhận thấy sự kiện sẽ khiến phần mềm cảm thấy không phản hồi. Cách tiếp cận này được gọi là bỏ phiếu. Hầu hết các lập trình viên muốn tránh nó

Một cơ chế tốt hơn là hệ thống sẽ chủ động thông báo cho mã của chúng ta khi có sự kiện xảy ra. Các trình duyệt thực hiện điều này bằng cách cho phép chúng tôi đăng ký các chức năng làm trình xử lý cho các sự kiện cụ thể

<p>Click this document to activate the handler.</p>
<script>
  window.addEventListener("click", () => {
    console.log("You knocked?");
  });
</script>

Liên kết

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
3 đề cập đến một đối tượng tích hợp do trình duyệt cung cấp. Nó đại diện cho cửa sổ trình duyệt chứa tài liệu. Gọi phương thức
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
4 của nó sẽ đăng ký đối số thứ hai đượ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

Sự kiện và nút DOM

Mỗi trình xử lý sự kiện của trình duyệt được đăng ký trong một ngữ cảnh. Trong ví dụ trước, chúng tôi đã gọi

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
4 trên đối tượng
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
3 để đăng ký trình xử lý cho toàn bộ cửa sổ. Một phương thức như vậy cũng có thể được tìm thấy trên các phần tử DOM và một số loại đối tượng khác. Trình lắng nghe sự kiện chỉ được gọi khi sự kiện xảy ra trong ngữ cảnh của đối tượng mà chúng được đăng ký trên đó

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>

Ví dụ đó gắn một trình xử lý vào nút nút. Bấm vào nút khiến trình xử lý đó chạy, nhưng bấm vào phần còn lại của tài liệu thì không

Cung cấp cho một nút một thuộc tính

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
7 có tác dụng tương tự. Điều này phù hợp với hầu hết các loại sự kiện—bạn có thể đính kèm một trình xử lý thông qua thuộc tính có tên là tên sự kiện với
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
8 ở phía trước

Nhưng một nút chỉ có thể có một thuộc tính

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
7, vì vậy bạn chỉ có thể đăng ký một trình xử lý cho mỗi nút theo cách đó. Phương thức
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
4 cho phép bạn thêm bất kỳ số lượng trình xử lý nào để việc thêm trình xử lý được an toàn ngay cả khi đã có một trình xử lý khác trên phần tử

Phương thức

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
01, được gọi với các đối số tương tự như
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
4, loại bỏ một trình xử lý

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>

Hàm được cung cấp cho

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
01 phải có cùng giá trị hàm được cung cấp cho
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
4. Vì vậy, để hủy đăng ký một trình xử lý, bạn sẽ muốn đặt tên cho hàm (trong ví dụ là ___105) để có thể truyền cùng một giá trị hàm cho cả hai phương thức

đối tượng sự kiện

Mặc dù chúng ta đã bỏ qua nó cho đến nay, nhưng các hàm xử lý sự kiện được truyền một đối số. đối tượng sự kiện. Đối tượng này chứa thông tin bổ sung về sự kiện. Ví dụ: nếu chúng ta muốn biết nút chuột nào đã được nhấn, chúng ta có thể xem thuộc tính

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
06 của đối tượng sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
0

Thông tin được lưu trữ trong một đối tượng sự kiện khác nhau tùy theo loại sự kiện. Chúng ta sẽ thảo luận về các loại khác nhau sau trong chương này. Thuộc tính

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
07 của đối tượng luôn chứa một chuỗi xác định sự kiện (chẳng hạn như
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
08 hoặc
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
09)

Lan truyền

Đối với hầu hết các loại sự kiện, trình xử lý đã đăng ký trên các nút có nút con cũng sẽ nhận được các sự kiện xảy ra ở nút con. Nếu một nút bên trong một đoạn văn được nhấp vào, trình xử lý sự kiện trên đoạn văn cũng sẽ thấy sự kiện nhấp chuột

Nhưng nếu cả đoạn văn và nút đều có trình xử lý, thì trình xử lý cụ thể hơn—trình xử lý trên nút—sẽ đi trước. Sự kiện được cho là lan truyền ra bên ngoài, từ nút nơi nó xảy ra đến nút cha của nút đó và đến thư mục gốc của tài liệu. Cuối cùng, sau khi tất cả các trình xử lý đã đăng ký trên một nút cụ thể đã đến lượt của họ, những trình xử lý đã đăng ký trên toàn bộ cửa sổ sẽ có cơ hội phản hồi sự kiện

Tại bất kỳ thời điểm nào, trình xử lý sự kiện có thể gọi phương thức

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
10 trên đối tượng sự kiện để ngăn các trình xử lý tiếp theo nhận sự kiện. Điều này có thể hữu ích khi, ví dụ: bạn có một nút bên trong một phần tử có thể nhấp khác và bạn không muốn nhấp vào nút để kích hoạt hành vi nhấp của phần tử bên ngoài

Ví dụ sau đăng ký trình xử lý

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
09 trên cả nút và đoạn xung quanh nó. Khi được nhấp bằng nút chuột phải, trình xử lý cho nút sẽ gọi
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
10, điều này sẽ ngăn trình xử lý trên đoạn văn chạy. Khi nút được nhấp bằng một nút chuột khác, cả hai trình xử lý sẽ chạy

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
1

Hầu hết các đối tượng sự kiện đều có thuộc tính

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
13 đề cập đến nút nơi chúng bắt nguồn. Bạn có thể sử dụng thuộc tính này để đảm bảo rằng bạn không vô tình xử lý thứ gì đó được truyền lên từ một nút mà bạn không muốn xử lý

Cũng có thể sử dụng thuộc tính

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
13 để tạo một mạng lưới rộng cho một loại sự kiện cụ thể. Ví dụ: nếu bạn có một nút chứa danh sách dài các nút, sẽ thuận tiện hơn khi đăng ký một trình xử lý nhấp chuột duy nhất trên nút bên ngoài và yêu cầu nó sử dụng thuộc tính
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
13 để tìm hiểu xem một nút có được nhấp hay không, thay vì đăng ký riêng lẻ.

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
8

hành động mặc định

Nhiều sự kiện có một hành động mặc định được liên kết với chúng. Nếu bạn nhấp vào một liên kết, bạn sẽ được đưa đến mục tiêu của liên kết. Nếu bạn nhấn mũi tên xuống, trình duyệt sẽ cuộn trang xuống. Nếu bạn nhấp chuột phải, bạn sẽ nhận được một menu ngữ cảnh. Và như thế

Đối với hầu hết các loại sự kiện, trình xử lý sự kiện JavaScript được gọi trước khi hành vi mặc định diễn ra. Nếu trình xử lý không muốn hành vi bình thường này xảy ra, thường là do nó đã xử lý sự kiện rồi, thì nó có thể gọi phương thức

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
16 trên đối tượng sự kiện

Điều này có thể được sử dụng để thực hiện các phím tắt hoặc menu ngữ cảnh của riêng bạn. Nó cũng có thể được sử dụng để can thiệp một cách đáng ghét vào hành vi mà người dùng mong đợi. Ví dụ: đây là một liên kết không thể theo dõi

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
0

Cố gắng không làm những việc như vậy trừ khi bạn có lý do thực sự chính đáng để. Sẽ rất khó chịu cho những người sử dụng trang của bạn khi hành vi dự kiến ​​bị phá vỡ

Tùy thuộc vào trình duyệt, một số sự kiện hoàn toàn không thể bị chặn. Ví dụ: trên Chrome, phím tắt để đóng tab hiện tại ( điều khiển -W hoặc lệnh-W) cannot be handled by JavaScript.

Sự kiện chính

Khi nhấn một phím trên bàn phím, trình duyệt của bạn sẽ kích hoạt sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
17. Khi nó được phát hành, bạn sẽ nhận được một sự kiện
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
18

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
3

Mặc dù có tên như vậy, nhưng

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
17 không chỉ kích hoạt khi chìa khóa được ấn xuống. Khi một phím được nhấn và giữ, sự kiện sẽ kích hoạt lại mỗi khi phím đó lặp lại. Đôi khi bạn phải cẩn thận về điều này. Ví dụ: nếu bạn thêm một nút vào DOM khi một phím được nhấn và lại xóa nút đó khi nhả phím, bạn có thể vô tình thêm hàng trăm nút khi giữ phím lâu hơn

Ví dụ đã xem xét thuộc tính

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
80 của đối tượng sự kiện để xem sự kiện nói về khóa nào. Thuộc tính này chứa một chuỗi, đối với hầu hết các phím, tương ứng với thứ mà nhấn phím đó sẽ gõ. Đối với các khóa đặc biệt như enter , nó chứa một chuỗi đặt tên cho khóa (trong trường hợp này là
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
81). Nếu bạn giữ shift trong khi nhấn một phím, điều đó cũng có thể ảnh hưởng đến tên của phím—
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
82 trở thành
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
83 và
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
84 có thể trở thành
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
85, nếu đó là . shift-1 produces on your keyboard.

Các phím bổ trợ như shift , control , < . Tuy nhiên, khi tìm kiếm các tổ hợp phím, bạn cũng có thể tìm hiểu xem các phím này có được nhấn giữ hay không bằng cách xem các thuộc tính

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
86,
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
87,
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
88 và
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
89 của các sự kiện bàn phím và chuột. alt, and meta (command on Mac) generate key events just like normal keys. But when looking for key combinations, you can also find out whether these keys are held down by looking at the
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
86,
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
87,
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
88, and
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
89 properties of keyboard and mouse events.

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
5

Nút DOM nơi một sự kiện quan trọng bắt đầu phụ thuộc vào phần tử có tiêu điểm khi nhấn phím. Hầu hết các nút không thể có tiêu điểm trừ khi bạn cung cấp cho chúng thuộc tính

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
00, nhưng những thứ như liên kết, nút và trường biểu mẫu có thể. Chúng tôi sẽ quay lại để tạo các trường trong. Khi không có tiêu điểm cụ thể nào,
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
01 đóng vai trò là nút mục tiêu của các sự kiện chính

Khi người dùng đang nhập văn bản, việc sử dụng các sự kiện chính để tìm ra nội dung đang được nhập là một vấn đề. Một số nền tảng, đáng chú ý nhất là bàn phím ảo trên điện thoại Android, không kích hoạt các sự kiện quan trọng. Nhưng ngay cả khi bạn có bàn phím kiểu cũ, một số kiểu nhập văn bản không khớp với các phím bấm một cách đơn giản, chẳng hạn như phần mềm trình soạn phương thức nhập (IME) được sử dụng bởi những người có tập lệnh không vừa với bàn phím, trong đó

Để thông báo khi nội dung nào đó được nhập, các yếu tố mà bạn có thể nhập vào, chẳng hạn như thẻ

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
02 và
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
03, kích hoạt sự kiện
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
04 bất cứ khi nào người dùng thay đổi nội dung của họ. Để có được nội dung thực tế đã được nhập, tốt nhất là đọc trực tiếp nội dung đó từ trường tiêu điểm. sẽ chỉ ra cách

sự kiện con trỏ

Hiện tại có hai cách được sử dụng rộng rãi để chỉ vào những thứ trên màn hình. chuột (bao gồm các thiết bị hoạt động như chuột, chẳng hạn như bàn di chuột và bi xoay) và màn hình cảm ứng. Chúng tạo ra các loại sự kiện khác nhau

nhấp chuột

Nhấn nút chuột khiến một số sự kiện kích hoạt. Sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
09 và
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
06 tương tự như sự kiện
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
17 và
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
18 và kích hoạt khi nhấn và thả nút. Những điều này xảy ra trên các nút DOM ngay bên dưới con trỏ chuột khi sự kiện xảy ra

Sau sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
06, một sự kiện
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
08 kích hoạt trên nút cụ thể nhất chứa cả thao tác nhấn và nhả nút. Ví dụ: nếu tôi nhấn nút chuột trên một đoạn văn, sau đó di chuyển con trỏ sang đoạn văn khác và nhả nút, sự kiện
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
08 sẽ xảy ra trên phần tử chứa cả hai đoạn văn đó

Nếu hai lần nhấp xảy ra gần nhau, sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
32 (nhấp đúp) cũng kích hoạt, sau sự kiện nhấp thứ hai

Để có thông tin chính xác về địa điểm xảy ra sự kiện chuột, bạn có thể xem các thuộc tính

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
33 và
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
34 của nó, chứa tọa độ của sự kiện (tính bằng pixel) so với góc trên cùng bên trái của cửa sổ hoặc
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
35 và
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
36, là

Sau đây thực hiện một chương trình vẽ nguyên thủy. Mỗi khi bạn nhấp vào tài liệu, nó sẽ thêm một dấu chấm dưới con trỏ chuột của bạn. Xem Chương 19 để biết chương trình vẽ ít nguyên thủy hơn

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
3

chuyển động chuột

Mỗi khi con trỏ chuột di chuyển, một sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
37 được kích hoạt. Sự kiện này có thể được sử dụng để theo dõi vị trí của chuột. Một tình huống phổ biến mà điều này hữu ích là khi triển khai một số dạng chức năng kéo chuột

Ví dụ, chương trình sau hiển thị một thanh và thiết lập các trình xử lý sự kiện để việc kéo sang trái hoặc phải trên thanh này làm cho nó hẹp hơn hoặc rộng hơn

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
0

Lưu ý rằng trình xử lý

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
37 được đăng ký trên toàn bộ cửa sổ. Ngay cả khi chuột đi ra ngoài thanh trong khi thay đổi kích thước, miễn là nút được giữ, chúng tôi vẫn muốn cập nhật kích thước của nó

Chúng ta phải ngừng thay đổi kích thước thanh khi thả nút chuột. Để làm được điều đó, chúng ta có thể sử dụng thuộc tính

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
39 (lưu ý số nhiều), thuộc tính này cho chúng ta biết về các nút hiện đang được nhấn giữ. Khi giá trị này bằng 0, không có nút nào bị hỏng. Khi các nút được giữ, giá trị của nó là tổng các mã cho các nút đó—nút bên trái có mã 1, nút bên phải 2 và nút ở giữa 4. Ví dụ: với các nút trái và phải được giữ, giá trị của
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
39 sẽ là 3

Lưu ý rằng thứ tự của các mã này khác với thứ tự được sử dụng bởi

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
06, trong đó nút ở giữa nằm trước nút bên phải. Như đã đề cập, tính nhất quán không thực sự là điểm mạnh của giao diện lập trình của trình duyệt

sự kiện chạm

Kiểu trình duyệt đồ họa mà chúng tôi sử dụng được thiết kế dành cho giao diện chuột, vào thời điểm mà màn hình cảm ứng còn hiếm. Để làm cho Web “hoạt động” trên điện thoại màn hình cảm ứng đời đầu, ở một mức độ nhất định, các trình duyệt dành cho những thiết bị đó đã giả vờ rằng các sự kiện chạm là sự kiện chuột. Nếu bạn nhấn vào màn hình, bạn sẽ nhận được các sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
09,
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
06 và
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
08

Nhưng ảo ảnh này không phải là rất mạnh mẽ. Màn hình cảm ứng hoạt động khác với chuột. nó không có nhiều nút, bạn không thể theo dõi ngón tay khi nó không ở trên màn hình (để mô phỏng

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
37) và nó cho phép nhiều ngón tay ở trên màn hình cùng một lúc

Sự kiện chuột chỉ bao gồm tương tác chạm trong các trường hợp đơn giản—nếu bạn thêm trình xử lý

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
08 vào nút, người dùng chạm sẽ vẫn có thể sử dụng nó. Nhưng một cái gì đó giống như thanh có thể thay đổi kích thước trong ví dụ trước không hoạt động trên màn hình cảm ứng

Có các loại sự kiện cụ thể được kích hoạt bằng tương tác chạm. Khi một ngón tay bắt đầu chạm vào màn hình, bạn sẽ nhận được sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
57. Khi nó được di chuyển trong khi chạm vào, sự kiện
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
58 sẽ cháy. Cuối cùng, khi nó ngừng chạm vào màn hình, bạn sẽ thấy sự kiện
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
59

Vì nhiều màn hình cảm ứng có thể phát hiện nhiều ngón tay cùng lúc nên những sự kiện này không có một bộ tọa độ nào được liên kết với chúng. Thay vào đó, các đối tượng sự kiện của chúng có một thuộc tính

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
30, chứa một đối tượng giống như mảng gồm các điểm, mỗi đối tượng có các thuộc tính riêng của nó là
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
33,
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
34,
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
35 và
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
36

Bạn có thể làm điều gì đó như thế này để hiển thị các vòng tròn màu đỏ xung quanh mỗi ngón tay chạm vào

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
1

Bạn sẽ thường muốn gọi

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
16 trong các trình xử lý sự kiện chạm để ghi đè hành vi mặc định của trình duyệt (có thể bao gồm cuộn trang khi vuốt) và để ngăn các sự kiện chuột kích hoạt, bạn cũng có thể có một trình xử lý.

Cuộn sự kiện

Bất cứ khi nào một phần tử được cuộn, một sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
36 sẽ được kích hoạt trên phần tử đó. Điều này có nhiều cách sử dụng khác nhau, chẳng hạn như biết người dùng hiện đang xem gì (để tắt hoạt ảnh ngoài màn hình hoặc gửi báo cáo gián điệp đến trụ sở xấu xa của bạn) hoặc hiển thị một số dấu hiệu tiến triển (bằng cách đánh dấu một phần của mục lục hoặc hiển thị một trang

Ví dụ sau vẽ một thanh tiến trình phía trên tài liệu và cập nhật nó để lấp đầy khi bạn cuộn xuống

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
2

Đặt một phần tử là

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
37 trong số
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
38 hoạt động giống như một vị trí của
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
39 nhưng cũng ngăn không cho phần tử đó cuộn cùng với phần còn lại của tài liệu. Hiệu quả là làm cho thanh tiến trình của chúng ta luôn ở trên cùng. Chiều rộng của nó được thay đổi để chỉ ra tiến trình hiện tại. Chúng tôi sử dụng
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
00, thay vì
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
01, làm đơn vị khi đặt chiều rộng sao cho phần tử có kích thước tương ứng với chiều rộng của trang

Liên kết toàn cầu

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
02 cung cấp cho chúng tôi chiều cao của cửa sổ, chúng tôi phải trừ đi chiều cao này từ tổng chiều cao có thể cuộn—bạn không thể tiếp tục cuộn khi chạm đến cuối tài liệu. Ngoài ra còn có một
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
03 cho chiều rộng cửa sổ. Bằng cách chia
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
04, vị trí cuộn hiện tại, cho vị trí cuộn tối đa và nhân với 100, chúng tôi nhận được tỷ lệ phần trăm cho thanh tiến trình

Gọi

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
16 trong sự kiện cuộn không ngăn việc cuộn xảy ra. Trên thực tế, trình xử lý sự kiện chỉ được gọi sau khi quá trình cuộn diễn ra

Sự kiện tiêu điểm

Khi một phần tử đạt tiêu điểm, trình duyệt sẽ kích hoạt sự kiện

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
06 trên phần tử đó. Khi mất tiêu điểm, phần tử sẽ nhận được sự kiện
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
07

Không giống như các sự kiện đã thảo luận trước đó, hai sự kiện này không lan truyền. Trình xử lý trên phần tử cha không được thông báo khi phần tử con tăng hoặc giảm tiêu điểm

Ví dụ sau hiển thị văn bản trợ giúp cho trường văn bản hiện có tiêu điểm

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
3

Đối tượng cửa sổ sẽ nhận các sự kiện

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
06 và
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
07 khi người dùng di chuyển từ hoặc đến tab trình duyệt hoặc cửa sổ trong đó tài liệu được hiển thị

Tải sự kiện

Khi một trang tải xong, sự kiện

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
10 sẽ kích hoạt cửa sổ và các đối tượng nội dung tài liệu. Điều này thường được sử dụng để lên lịch các hành động khởi tạo yêu cầu toàn bộ tài liệu đã được tạo. Hãy nhớ rằng nội dung của các thẻ
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
11 được chạy ngay lập tức khi gặp thẻ. Điều này có thể là quá sớm, chẳng hạn như khi tập lệnh cần thực hiện điều gì đó với các phần của tài liệu xuất hiện sau thẻ
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
11

Các phần tử như hình ảnh và thẻ tập lệnh tải tệp bên ngoài cũng có sự kiện

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
10 cho biết các tệp mà chúng tham chiếu đã được tải. Giống như các sự kiện liên quan đến tiêu điểm, sự kiện tải không lan truyền

Khi một trang bị đóng hoặc được điều hướng khỏi (ví dụ: bằng cách nhấp vào một liên kết), sự kiện

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
14 sẽ kích hoạt. Công dụng chính của sự kiện này là ngăn người dùng vô tình làm mất công việc do đóng tài liệu. Nếu bạn ngăn hành vi mặc định đối với sự kiện này và đặt thuộc tính
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
15 trên đối tượng sự kiện thành chuỗi, thì trình duyệt sẽ hiển thị cho người dùng hộp thoại hỏi xem họ có thực sự muốn rời khỏi trang không. Hộp thoại đó có thể bao gồm chuỗi của bạn, nhưng vì một số trang web độc hại cố gắng sử dụng các hộp thoại này để khiến mọi người nhầm lẫn ở lại trang của họ để xem các quảng cáo giảm cân tinh vi nên hầu hết các trình duyệt không còn hiển thị chúng nữa

Sự kiện và vòng lặp sự kiện

Trong ngữ cảnh của vòng lặp sự kiện, như đã thảo luận trong Chương 11, trình xử lý sự kiện của trình duyệt hoạt động giống như các thông báo không đồng bộ khác. Chúng được lên lịch khi sự kiện xảy ra nhưng phải đợi các tập lệnh khác đang chạy kết thúc trước khi chúng có cơ hội chạy

Thực tế là các sự kiện chỉ có thể được xử lý khi không có gì khác đang chạy có nghĩa là nếu vòng lặp sự kiện được liên kết với công việc khác, mọi tương tác với trang (xảy ra thông qua các sự kiện) sẽ bị trì hoãn cho đến khi có thời gian để xử lý nó. Vì vậy, nếu bạn lên lịch quá nhiều công việc, với các trình xử lý sự kiện dài hạn hoặc nhiều sự kiện ngắn hạn, thì trang sẽ trở nên chậm và cồng kềnh khi sử dụng

Đối với trường hợp bạn thực sự muốn làm một số việc tốn thời gian trong nền mà không đóng băng trang, trình duyệt cung cấp một thứ gọi là nhân viên web. Công nhân là một quy trình JavaScript chạy dọc theo tập lệnh chính, theo dòng thời gian của chính nó

Hãy tưởng tượng rằng bình phương một số là một phép tính tốn nhiều thời gian mà chúng ta muốn thực hiện trong một chuỗi riêng biệt. Chúng ta có thể viết một tệp tên là

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
16 để trả lời tin nhắn bằng cách tính toán một hình vuông và gửi lại tin nhắn

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
4

Để tránh sự cố có nhiều luồng chạm vào cùng một dữ liệu, worker không chia sẻ phạm vi toàn cầu của họ hoặc bất kỳ dữ liệu nào khác với môi trường của tập lệnh chính. Thay vào đó, bạn phải liên lạc với họ bằng cách gửi tin nhắn qua lại

Mã này sinh ra một công nhân đang chạy tập lệnh đó, gửi cho nó một vài tin nhắn và đưa ra các phản hồi

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
5

Hàm

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
17 gửi một tin nhắn, điều này sẽ gây ra sự kiện
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
18 kích hoạt bên nhận. Tập lệnh đã tạo worker gửi và nhận tin nhắn thông qua đối tượng
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
19, trong khi worker nói chuyện với tập lệnh đã tạo nó bằng cách gửi và nghe trực tiếp trên phạm vi toàn cầu của nó. Chỉ những giá trị có thể được biểu diễn dưới dạng JSON mới có thể được gửi dưới dạng tin nhắn—phía bên kia sẽ nhận được một bản sao của chúng, thay vì chính giá trị đó

hẹn giờ

Chúng ta đã thấy hàm

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
20 trong Chương 11. Nó lên lịch một chức năng khác sẽ được gọi sau, sau một số mili giây nhất định

Đôi khi bạn cần hủy một chức năng mà bạn đã lên lịch. Điều này được thực hiện bằng cách lưu trữ giá trị được trả về bởi

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
20 và gọi
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
22 trên đó

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
6

Hàm

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
23 hoạt động theo cách tương tự như hàm
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
22—gọi nó trên một giá trị được trả về bởi
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
25 sẽ hủy khung đó (giả sử nó chưa được gọi)

Một bộ hàm tương tự,

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
26 và
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
27, được sử dụng để đặt bộ hẹn giờ lặp lại X mili giây một lần

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
7

ra mắt

Một số loại sự kiện có khả năng xảy ra nhanh chóng, nhiều lần liên tiếp (ví dụ: sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
37 và
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
36). Khi xử lý các sự kiện như vậy, bạn phải cẩn thận để không làm bất cứ điều gì quá tốn thời gian, nếu không trình xử lý của bạn sẽ chiếm quá nhiều thời gian khiến việc tương tác với tài liệu bắt đầu chậm lại

Nếu bạn cần làm điều gì đó không cần thiết trong trình xử lý như vậy, bạn có thể sử dụng

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
20 để đảm bảo rằng bạn không làm việc đó quá thường xuyên. Điều này thường được gọi là gỡ lỗi sự kiện. Có một số cách tiếp cận hơi khác nhau đối với điều này

Trong ví dụ đầu tiên, chúng tôi muốn phản ứng khi người dùng đã nhập nội dung nào đó, nhưng chúng tôi không muốn thực hiện ngay lập tức cho mọi sự kiện đầu vào. Khi họ đang gõ nhanh, chúng tôi chỉ muốn đợi cho đến khi tạm dừng xảy ra. Thay vì ngay lập tức thực hiện một hành động trong trình xử lý sự kiện, chúng tôi đặt thời gian chờ. Chúng tôi cũng xóa thời gian chờ trước đó (nếu có) để khi các sự kiện xảy ra gần nhau (gần hơn độ trễ thời gian chờ của chúng tôi), thời gian chờ từ sự kiện trước đó sẽ bị hủy

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
8

Đưa ra một giá trị không xác định cho

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
22 hoặc gọi nó khi hết thời gian chờ đã kích hoạt không có hiệu lực. Vì vậy, chúng tôi không cần phải cẩn thận về thời điểm gọi nó và chúng tôi chỉ cần làm như vậy cho mọi sự kiện

Chúng tôi có thể sử dụng một mẫu hơi khác nếu chúng tôi muốn sắp xếp các phản hồi theo không gian để chúng cách nhau ít nhất một khoảng thời gian nhất định nhưng muốn kích hoạt chúng trong một chuỗi sự kiện, không chỉ sau đó. Ví dụ: chúng tôi có thể muốn phản hồi các sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
37 bằng cách hiển thị tọa độ hiện tại của chuột nhưng chỉ sau mỗi 250 mili giây

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
9

Tóm lược

Trình xử lý sự kiện giúp phát hiện và phản ứng với các sự kiện xảy ra trên trang web của chúng tôi. Phương thức

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
4 được sử dụng để đăng ký một trình xử lý như vậy

Mỗi sự kiện có một loại (

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
17,
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
06, v.v.) xác định sự kiện đó. Hầu hết các sự kiện được gọi trên một phần tử DOM cụ thể và sau đó lan truyền đến tổ tiên của phần tử đó, cho phép các trình xử lý được liên kết với các phần tử đó xử lý chúng

Khi một trình xử lý sự kiện được gọi, nó sẽ truyền một đối tượng sự kiện với thông tin bổ sung về sự kiện. Đối tượng này cũng có các phương thức cho phép chúng tôi ngừng lan truyền thêm (

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
10) và ngăn việc xử lý sự kiện mặc định của trình duyệt (
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
16)

Nhấn một phím sẽ kích hoạt các sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
17 và
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
18. Nhấn nút chuột sẽ kích hoạt các sự kiện
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
09,
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
06 và
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
08. Di chuyển chuột sẽ kích hoạt
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
37 sự kiện. Tương tác với màn hình cảm ứng sẽ dẫn đến các sự kiện
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
57,
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
58 và
<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
59

Thao tác cuộn có thể được phát hiện với sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
36 và có thể phát hiện thay đổi tiêu điểm với sự kiện
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
06 và
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
07. Khi tài liệu tải xong, một sự kiện
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
10 sẽ kích hoạt trên cửa sổ

bài tập

Khí cầu

Viết một trang hiển thị bong bóng (sử dụng biểu tượng cảm xúc bong bóng, 🎈). Khi bạn nhấn vào mũi tên lên, nó sẽ phồng lên (lớn lên) 10 phần trăm và khi bạn nhấn vào mũi tên xuống, nó sẽ xẹp xuống (co lại) 10 phần trăm

Bạn có thể kiểm soát kích thước của văn bản (biểu tượng cảm xúc là văn bản) bằng cách đặt thuộc tính CSS

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
51 (
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
52) trên thành phần chính của nó. Hãy nhớ bao gồm một đơn vị trong giá trị—ví dụ: pixel (______553)

Tên chính của các phím mũi tên là

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
54 và
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
55. Đảm bảo các phím chỉ thay đổi bong bóng mà không cuộn trang

Khi điều đó hoạt động, hãy thêm một tính năng trong đó, nếu bạn thổi quả bóng qua một kích thước nhất định, nó sẽ phát nổ. Trong trường hợp này, phát nổ có nghĩa là nó được thay thế bằng biểu tượng cảm xúc 💥 và trình xử lý sự kiện bị xóa (để bạn không thể thổi phồng hoặc xì hơi vụ nổ)

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
0

Bạn sẽ muốn đăng ký một trình xử lý cho sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
17 và xem xét
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
57 để biết liệu phím mũi tên lên hay xuống đã được nhấn

Kích thước hiện tại có thể được giữ trong một ràng buộc để bạn có thể căn cứ vào kích thước mới trên đó. Sẽ rất hữu ích khi xác định một hàm cập nhật kích thước—cả liên kết và kiểu của bong bóng trong DOM—để bạn có thể gọi hàm đó từ trình xử lý sự kiện của mình và cũng có thể một lần khi bắt đầu, để đặt kích thước ban đầu

Bạn có thể thay đổi bong bóng thành một vụ nổ bằng cách thay thế nút văn bản bằng một nút khác (sử dụng

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
58) hoặc bằng cách đặt thuộc tính
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
59 của nút cha của nó thành một chuỗi mới

đường mòn chuột

Trong những ngày đầu của JavaScript, thời kỳ đỉnh cao của các trang chủ lòe loẹt với nhiều hình ảnh hoạt hình, mọi người đã nghĩ ra một số cách thực sự truyền cảm hứng để sử dụng ngôn ngữ này.

Một trong số đó là đường chuột—một loạt các thành phần sẽ đi theo con trỏ chuột khi bạn di chuyển nó trên trang

Trong bài tập này, tôi muốn bạn thực hiện một vệt chuột. Sử dụng các phần tử

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
60 được định vị tuyệt đối với kích thước và màu nền cố định (tham khảo phần “Nhấp chuột” để biết ví dụ). Tạo một loạt các phần tử như vậy và khi con chuột di chuyển, hãy hiển thị chúng theo con trỏ chuột

Có nhiều cách tiếp cận có thể ở đây. Bạn có thể làm cho giải pháp của mình đơn giản hoặc phức tạp như bạn muốn. Một giải pháp đơn giản để bắt đầu là giữ một số phần tử đường mòn cố định và xoay vòng qua chúng, di chuyển phần tử tiếp theo đến vị trí hiện tại của chuột mỗi khi xảy ra sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
37

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
1

Tạo các phần tử được thực hiện tốt nhất với một vòng lặp. Nối chúng vào tài liệu để làm cho chúng hiển thị. Để có thể truy cập chúng sau này nhằm thay đổi vị trí của chúng, bạn sẽ muốn lưu trữ các phần tử trong một mảng

Việc quay vòng qua chúng có thể được thực hiện bằng cách giữ một biến đếm và thêm 1 vào nó mỗi khi sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
37 xảy ra. Sau đó, toán tử còn lại (
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
63) có thể được sử dụng để lấy chỉ mục mảng hợp lệ để chọn phần tử bạn muốn định vị trong một sự kiện nhất định

Một hiệu ứng thú vị khác có thể đạt được bằng cách mô hình hóa một hệ thống vật lý đơn giản. Chỉ sử dụng sự kiện

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
37 để cập nhật một cặp liên kết theo dõi vị trí chuột. Sau đó, sử dụng
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
25 để mô phỏng các phần tử theo sau bị thu hút vào vị trí của con trỏ chuột. Ở mỗi bước hoạt ảnh, hãy cập nhật vị trí của chúng dựa trên vị trí của chúng so với con trỏ (và, tùy chọn, tốc độ được lưu trữ cho từng phần tử). Tìm ra một cách tốt để làm điều này là tùy thuộc vào bạn

tab

Các bảng theo thẻ được sử dụng rộng rãi trong giao diện người dùng. Chúng cho phép bạn chọn một bảng giao diện bằng cách chọn từ một số tab “nhô ra” phía trên một thành phần

Trong bài tập này, bạn phải triển khai một giao diện theo thẻ đơn giản. Viết một hàm,

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
66, nhận một nút DOM và tạo một giao diện theo thẻ hiển thị các phần tử con của nút đó. Nó sẽ chèn một danh sách các phần tử
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
67 ở đầu nút, một phần tử cho mỗi phần tử con, chứa văn bản được lấy từ thuộc tính
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
68 của phần tử con. Tất cả, trừ một trong những đứa trẻ ban đầu nên được ẩn đi (được cung cấp kiểu
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
69 của
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
70). Có thể chọn nút hiện đang hiển thị bằng cách nhấp vào các nút

Khi điều đó hoạt động, hãy mở rộng nó để tạo kiểu khác cho nút cho tab hiện được chọn để rõ ràng tab nào được chọn

<button>Act-once button</button>
<script>
  let button = document.querySelector("button");
  function once() {
    console.log("Done.");
    button.removeEventListener("click", once);
  }
  button.addEventListener("click", once);
</script>
2

Một cạm bẫy mà bạn có thể gặp phải là bạn không thể trực tiếp sử dụng thuộc tính

<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
71 của nút làm tập hợp các nút tab. Đối với một điều, khi bạn thêm các nút, chúng cũng sẽ trở thành các nút con và kết thúc trong đối tượng này vì đây là cấu trúc dữ liệu trực tiếp. Mặt khác, các nút văn bản được tạo cho khoảng trắng giữa các nút cũng nằm trong
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
71 nhưng sẽ không có tab riêng. Bạn có thể sử dụng
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
73 thay vì
<button>Click me</button>
<p>No handler here.</p>
<script>
  let button = document.querySelector("button");
  button.addEventListener("click", () => {
    console.log("Button clicked.");
  });
</script>
71 để bỏ qua các nút văn bản

Bạn có thể bắt đầu bằng cách xây dựng một dãy tab để bạn có thể dễ dàng truy cập chúng. Để triển khai kiểu dáng của các nút, bạn có thể lưu trữ các đối tượng chứa cả bảng điều khiển tab và nút của nó

Tôi khuyên bạn nên viết một chức năng riêng để thay đổi tab. Bạn có thể lưu trữ tab đã chọn trước đó và chỉ thay đổi các kiểu cần thiết để ẩn tab đó và hiển thị tab mới hoặc bạn chỉ có thể cập nhật kiểu của tất cả các tab mỗi khi một tab mới được chọn

Bạn có thể muốn gọi chức năng này ngay lập tức để giao diện bắt đầu với tab đầu tiên hiển thị

Ví dụ xử lý sự kiện là gì?

Dưới đây là một số ví dụ phổ biến về trình xử lý sự kiện. Thông báo bật lên trên trang web khi tab mới được mở . Một biểu mẫu được gửi khi nhấp vào nút gửi. Màu nền thay đổi khi nhấp chuột.

Ví dụ về sự kiện JavaScript là gì?

Tương tác của JavaScript với HTML được xử lý thông qua các sự kiện xảy ra khi người dùng hoặc trình duyệt thao tác trên một trang. Khi trang tải, nó được gọi là một sự kiện. Khi người dùng nhấp vào một nút, lần nhấp đó cũng là một sự kiện. Các ví dụ khác bao gồm các sự kiện như nhấn phím bất kỳ, đóng cửa sổ, thay đổi kích thước cửa sổ , v.v.

8 loại sự kiện JavaScript là gì?

Các loại sự kiện JavaScript .
Sự kiện giao diện người dùng. Những điều này xảy ra do bất kỳ tương tác nào với cửa sổ trình duyệt chứ không phải trang HTML. .
Tập trung và làm mờ các sự kiện. .
sự kiện chuột. .
sự kiện bàn phím. .
Sự kiện biểu mẫu. .
Sự kiện đột biến và người quan sát. .
sự kiện HTML5. .
sự kiện CSS