Hướng dẫn for each button click javascript - cho mỗi nút nhấp vào javascript

Tôi đang tạo một trò chơi đơn giản cho một dự án và cần giá trị tương ứng của mỗi nút để được hiển thị trong đầu vào khi nhấp.

Show

Tôi có thể sử dụng thành công "getEuityByid" với JS sau:

window.addEventListener("load", function() {
const button1 = document.getElementById("button-one");

button1.addEventListener("click", function(e) {
   document.getElementById("user-input").value += button1.value;
   document.getElementById("user-input").focus();
});

Tất nhiên tôi có thể lặp lại mã này cho tất cả các nút 0-9 nhưng tôi muốn sử dụng "vòng lặp" nếu có thể thực hiện điều này chỉ với một khối mã. Tôi đã thực hiện nỗ lực sau đây bằng cách chỉ cố gắng mô phỏng mã trên hoạt động cho một "id" và chỉ cần chuyển ra "nút1" cho một vòng lặp qua "nút" (tôi đã thử cả "QuerySelectorall" và "getElementsByClassName"). Tôi nhận được lỗi: "Nút.AdDeventListener không phải là một hàm." Tôi không hiểu vì trong mã nút đơn thành công "nút1.AddeventListener (" Nhấp ", hàm (e)" cũng không phải là một hàm nhưng nó hoạt động ... bên dưới là lần thử vòng lặp, theo sau là toàn bộ trang:

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   

48,475

Khi bạn đính kèm nhiều sự kiện nhấp vào các phần tử như các nút bên trong A For Loop, sự kiện nhấp sẽ luôn cung cấp cho chúng tôi giá trị LastIndex bất kể nhấn nút nào.elements such as buttons inside a for loop, the click event will always give us the last index value regardless of what button is pressed.

Đây là một trong những vấn đề phổ biến mà các nhà phát triển gặp phải khi họ bắt đầu học JavaScript.

Đến cuối bài viết này, bạn sẽ biết nguyên nhân gây ra vấn đề này và một số cách để khắc phục nó.

  • Tại sao tôi cần biết nâng cao?Hoisting?
  • Tại sao tôi thay đổi luôn nhận được chỉ mục cuối cùng trong một vòng lặp?i variable always get the last index in a loop?
  • Vấn đề phạm vi biến đổi
  • Giải pháp số 1: Đóng cửa (iife)
  • Giải pháp #2: Đóng hàm bên ngoài đóng lại chức năng bên trong
  • Giải pháp số 3: Sử dụng foreach thay vì choforEach instead of for
  • Giải pháp số 4: Sử dụng LET thay vì VARlet instead of var
  • Phần thưởng: Khai báo chức năng gọi lại bên ngoài vòng lặp

Mã mã gây ra vấn đềThat Causes The Problem

Như bạn có thể thấy, trang HTML có phần tử

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
2 với
var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
3 được gọi là
var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
4.




  
  
  JS Bin


  

Đây là nơi tôi đã thêm năm nút sử dụng vòng lặp

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
5 trong mã JavaScript bên dưới.

const buttonsContainer = document.getElementById("buttonsContainer");

for (var i = 0; i < 5; i++) {
  const button = document.createElement("button");
  button.innerText = i;
  button.addEventListener("click", function() {
    console.log(i)
  })
  buttonsContainer.appendChild(button);
}

Tôi cũng đã đính kèm một sự kiện nhấp chuột vào một phần tử nút và thêm nó vào phần tử

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
6 trên mỗi lần lặp.

Nếu tôi chạy mã ở giai đoạn này, tôi sẽ nhận được giá trị 5 bất kể nhấn nút nào.

Trước khi hiểu những gì xảy ra ở đây, chúng tôi cần biết những gì đang nâng cao.

Phục hồi khóa học JavaScript hoàn chỉnh 2020: Xây dựng các dự án thực sự!
The Complete JavaScript Course 2020: Build Real Projects!

Kéo

Theo mặc định, một biến được khai báo với từ khóa

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
7 là chức năng phạm vi nhưng không có khối.function scoped but not block-scoped.

Vì vậy, bất kỳ biến nào được khai báo bên trong một hàm, bất kể nó sâu đến mức nào, sẽ được di chuyển lên đỉnh và có thể truy cập ở bất cứ đâu bên trong chức năng đó.

Mặt khác, nếu một biến được khai báo bên ngoài hàm, nó sẽ trở thành một biến phạm vi toàn cầu và chúng ta có thể truy cập nó ở bất cứ đâu trong ứng dụng vì nó thuộc về đối tượng cửa sổ (chỉ trình duyệt).

Hành vi đó được gọi là nâng.Hoisting.

Hãy để xem những gì xảy ra với mã ở trên bây giờ.

Biến

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
8 được khai báo với từ khóa
var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
7 sẽ được tự động di chuyển lên đầu trang vì nó không được khai báo bên trong một hàm để nó trở thành biến toàn cầu do nâng.

Vì vậy, biến

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
8 rõ ràng không được đưa vào vòng lặp
var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
5, nhưng nó có phạm vi toàn cầu và nó ràng buộc với cùng một biến bên ngoài hàm gọi lại trên mỗi lần lặp.

Vào thời điểm vòng lặp

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
5 đạt đến lần lặp cuối cùng, biến
var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
8 sẽ kết thúc giữ giá trị chỉ mục cuối cùng. Đó là lý do tại sao đầu ra sẽ luôn là chỉ số cuối cùng, trong trường hợp của tôi, 5.

✅RECOMPENDERJAVASCRIPT làm việc với hình ảnh
JavaScript Working with Images

Tôi sẽ đăng nhập bảng điều khiển Biến tôi bên ngoài vòng lặp.

} // end of for loop
console.log(i);

Bạn sẽ nhận được 5 trong bảng điều khiển trình duyệt ngay khi mã hoàn thành thực thi mà không cần nhấp vào bất kỳ nút nào.

Điều này chứng minh rằng biến

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
8 được phạm vi toàn cầu.

Bây giờ chúng tôi biết thủ phạm, đó là biến

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
8 được khai báo với từ khóa
var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
7.

Hãy cùng xem một vài giải pháp để khắc phục nó.

Giải pháp số 1: Đóng cửa

Chúng ta có thể sử dụng đóng cửa để thay đổi phạm vi của biến

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
8 cho phép các chức năng có thể có các biến riêng tư.

Sử dụng đóng, chúng ta có thể lưu duy nhất chỉ mục vòng lặp riêng biệt trên mỗi hàm gọi lại.

for (var i = 0; i < 5; i++) {
  var button = document.createElement("button");
  button.innerText = i;
  (function(index){
    button.addEventListener("click", function() {
      console.log(index)
    })
  })(i)
  buttonsContainer.appendChild(button);

}
console.log(i);

Hãy cùng xem điều đó trong hành động.

Đầu tiên, xác định đóng cửa bằng cách sử dụng dấu ngoặc đơn mở và đóng bên trong vòng

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
5.

Sau đó, khai báo một hàm ẩn danh lấy tham số chỉ mục.

Sau đó, chuyển biến toàn cầu

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
8 vào việc đóng cửa với bộ cuối cùng của (), gọi việc đóng cửa một lần trên mỗi lần lặp.

Điều này cũng được gọi là biểu thức chức năng được gọi ngay lập tức (iife), đây là một cách để khai báo đóng cửa.Immediately Invoked Function Expression (IIFE) which is one way of declaring closures.

(function(){
})()

Vì vậy, mã trên nắm bắt giá trị của biến

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
8 tại mỗi lần lặp và chuyển nó thành một đối số cho hàm tạo ra một phạm vi cục bộ.

Bây giờ, mỗi hàm có phiên bản riêng của một biến chỉ mục đã giành được sự thay đổi khi các hàm được tạo trong vòng lặp đó.

Hàm đóng cửa này bảo tồn giá trị của

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
8 (biến riêng tư) duy nhất cho mỗi trình xử lý sự kiện để mỗi người có quyền truy cập vào giá trị riêng của chúng.

Khi bạn nhấp vào bất kỳ nút nào sau khi kết thúc vòng lặp, chức năng gọi lại thích hợp sẽ được thực thi với giá trị chỉ mục chính xác.

Tôi hy vọng điều đó đúng.

Những điều cơ bản về JavaScript được đề xuất cho người mới bắt đầu
JavaScript Basics for Beginners

Giải pháp #2: Đóng hàm bên ngoài đóng lại chức năng bên trong

Ngoài ra, bạn có thể trả về một hàm bên trong chức năng gọi lại đóng.

    button.addEventListener("click", function(index) {
      return function(){
        console.log(index)
      }
    }(i))

Trong ví dụ trước, toàn bộ nút Nhấp vào Mã người nghe sự kiện được gói với đóng cửa.

Trong ví dụ này, chỉ cần nút Nhấp vào chức năng gọi lại được kết thúc bằng một đóng cửa.

Hàm bên ngoài sẽ được thực thi trên mọi lần lặp và

const buttonsContainer = document.getElementById("buttonsContainer");

for (var i = 0; i < 5; i++) {
  const button = document.createElement("button");
  button.innerText = i;
  button.addEventListener("click", function() {
    console.log(i)
  })
  buttonsContainer.appendChild(button);
}
5Varable (toàn cầu) được truyền như một đối số trong người gọi của hàm bên ngoài như thế này (i).

Hàm bên trong sẽ được trả về trên mỗi lần lặp và được gắn vào sự kiện nhấp chuột với giá trị chỉ mục duy nhất.

Đóng cửa, các hàm bên trong có thể có quyền truy cập vào các biến được khai báo bên ngoài nó ngay cả sau khi hàm bên ngoài được trả về.

Điều này sẽ rất tuyệt nếu bạn có một loạt các mục và bạn có thể chỉ cần chạy phương thức

const buttonsContainer = document.getElementById("buttonsContainer");

for (var i = 0; i < 5; i++) {
  const button = document.createElement("button");
  button.innerText = i;
  button.addEventListener("click", function() {
    console.log(i)
  })
  buttonsContainer.appendChild(button);
}
8 trên đó, nhưng nó không được khuyến nghị khi một hoạt động không đồng bộ đang xảy ra trên mọi lần lặp.

Theo mặc định, vòng lặp

const buttonsContainer = document.getElementById("buttonsContainer");

for (var i = 0; i < 5; i++) {
  const button = document.createElement("button");
  button.innerText = i;
  button.addEventListener("click", function() {
    console.log(i)
  })
  buttonsContainer.appendChild(button);
}
6 cung cấp một cách sạch sẽ và tự nhiên để có được chức năng đóng gọi lại riêng biệt trên mỗi lần lặp.

const num = [0, 1, 2, 3, 4];

num.forEach(i => {
  var button = document.createElement("button");
  button.innerText = i;
  
  button.addEventListener("click", function() {
    console.log(i)
  })
  buttonsContainer.appendChild(button);
})

Nó hoạt động mà không cần thêm bất kỳ chức năng trình bao bọc bổ sung nào, sạch hơn so với ví dụ trước!

✅RECOMPENDSCORS Lỗi & Giải pháp trong một Nutshell
CORS Error & Solutions in a Nutshell

Trong ES6, chúng tôi có các từ khóa

} // end of for loop
console.log(i);
0 và
} // end of for loop
console.log(i);
3 được phân tách khối trái ngược với
var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
7 là chức năng phạm vi. Nói cách khác,
} // end of for loop
console.log(i);
0 và
} // end of for loop
console.log(i);
3 cũng được nâng lên như VAR nhưng chúng không được khởi tạo với giá trị mặc định.block-scoped in contrast to
var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
7 that is function scoped. In other words,
} // end of for loop
console.log(i);
0 and
} // end of for loop
console.log(i);
3 are also hoisted like var but they’re not initialized with a default value.

Vì vậy, sử dụng từ khóa

} // end of for loop
console.log(i);
0 liên kết một hàm gọi lại mới với giá trị chỉ mục trên mỗi lần lặp thay vì sử dụng cùng một tham chiếu nhiều lần.

Để khắc phục điều đó, thay đổi

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
7 thành
} // end of for loop
console.log(i);
0 từ mã gốc và nó hoạt động.

for (let i = 0; i < 5; i++) {
  const button = document.createElement("button");
  button.innerText = i;
  button.addEventListener("click", function() {
    console.log(i)
  })
  buttonsContainer.appendChild(button);
}

Đây là cách nhanh nhất để khắc phục sự kiện nhấp chuột trong một vòng lặp.

Nhưng, một vấn đề với phương pháp này là cẩn thận với khả năng tương thích ngược của trình duyệt vì nó là một phần của tính năng ES6.

✅recomendendsjavascript: Hiểu các phần kỳ lạ
JavaScript: Understanding the Weird Parts

Khai báo chức năng gọi lại bên ngoài vòng lặp

Đôi khi chúng tôi muốn khai báo một chức năng gọi lại một cách riêng biệt với một tên thay vì sử dụng hàm ẩn danh nội tuyến bên trong hàm tạo addEventListener.

Vì vậy, hãy khai báo một hàm gọi lại được gọi là hàm nút được () và gọi nó bên trong hàm tạo addEventListener mà không có dấu ngoặc đơn.

Theo mặc định, đối tượng

for (var i = 0; i < 5; i++) {
  var button = document.createElement("button");
  button.innerText = i;
  (function(index){
    button.addEventListener("click", function() {
      console.log(index)
    })
  })(i)
  buttonsContainer.appendChild(button);

}
console.log(i);
0 được chuyển vào hàm nút ().

Sau đó, tôi có thể dễ dàng truy cập vào bất kỳ thông tin nào về phần tử đã chọn bằng đối tượng

for (var i = 0; i < 5; i++) {
  var button = document.createElement("button");
  button.innerText = i;
  (function(index){
    button.addEventListener("click", function() {
      console.log(index)
    })
  })(i)
  buttonsContainer.appendChild(button);

}
console.log(i);
0.

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
0

Điều gì sẽ xảy ra nếu tôi muốn chuyển một giá trị trực tiếp đến hàm gọi lại như một đối số?

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
1

Điều này rất giống với giải pháp #2.

Khi chúng ta chuyển một giá trị cho

for (var i = 0; i < 5; i++) {
  var button = document.createElement("button");
  button.innerText = i;
  (function(index){
    button.addEventListener("click", function() {
      console.log(index)
    })
  })(i)
  buttonsContainer.appendChild(button);

}
console.log(i);
2, nó trở thành một đóng cửa (iife) là hàm bên ngoài và chạy trên mỗi lần lặp.

Hàm bên trong sẽ được trả về trên mỗi lần lặp và gắn vào sự kiện nhấp chuột với giá trị chỉ mục.

Và điều đó sẽ làm phép thuật!

Hướng dẫn MVC JavaScript được đề xuất bằng ES6 - Phần 01
MVC JavaScript Tutorial Using ES6 – Part 01

Sự kết luận

Trong bài viết này, bạn đã học cách khắc phục sự cố phát sinh khi bạn đính kèm các sự kiện nhấp vào vòng lặp

var buttons = document.querySelectorAll("td>button");
for(var button = 0; button < buttons.length; button++)
{
button.addEventListener("click", function() {
   document.getElementById("user-input").value += button.value;
   document.getElementById("user-input").focus();
});
}
});










Test


   
5 theo một vài cách.

Phạm vi trong JavaScript là một chủ đề lớn và tôi vẫn đang tìm hiểu về việc đóng cửa và các khái niệm khác trong JavaScript.

Nếu bạn có bất kỳ đề xuất, phản hồi hoặc nếu có bất cứ điều gì không rõ ràng trong bài viết này, xin vui lòng liên hệ với tôi bằng cách bình luận bên dưới.

Tôi rất mong nhận được phản hồi từ bạn và mã hóa hạnh phúc!

Làm thế nào Onclick hoạt động trong JavaScript?

Sự kiện Onclick thực hiện một chức năng nhất định khi nhấp vào nút. Điều này có thể là khi người dùng gửi biểu mẫu, khi bạn thay đổi một số nội dung nhất định trên trang web và những thứ khác như thế. Bạn đặt chức năng JavaScript bạn muốn thực thi bên trong thẻ mở của nút.executes a certain functionality when a button is clicked. This could be when a user submits a form, when you change certain content on the web page, and other things like that. You place the JavaScript function you want to execute inside the opening tag of the button.

Làm cách nào để thêm trình nghe sự kiện vào nhiều nút?

Làm cách nào để thêm trình nghe sự kiện vào tất cả các nút của cùng một lớp ?..
Sử dụng tài liệu.Phương thức QuerySelectorall () để chọn các thành phần theo lớp ..
Sử dụng phương thức foreach () để lặp lại trong bộ sưu tập các yếu tố ..
Sử dụng phương thức addEventListener () để thêm trình nghe sự kiện cho từng phần tử ..

Làm cách nào để mã hóa nút JavaScript?

JavaScript lập trình tạo nút HTML..
Đầu tiên, bạn gọi tài liệu.createdEuity ("nút") và gán phần tử được trả về cho một biến có tên BTN ..
Sau đó, gán chuỗi "Nhấp vào tôi" cho BTN.Thuộc tính bên trong ..
Cuối cùng, sử dụng tài liệu.thân hình.appendChild () để nối phần tử nút vào thẻ ..

Onclick html là gì?

HTML là một thuộc tính sự kiện, thực thi tập lệnh khi nhấp vào nút.Thuộc tính này được hỗ trợ bởi tất cả các trình duyệt.Nó cũng được sử dụng để gọi một chức năng khi nhấp vào nút.an event attribute, which executes a script when the button is clicked. This attribute is supported by all browsers. It is also used to call a function when the button is clicked.