Lỗi khó hiểu khi onclick với <tr>

Chào mọi người, tình hình là mình có đoạn code như thế này (phần … là có code khác không liên quan):

        for (var i = 0; i < data.length; i += 1) {
            ...
            var tr = document.createElement("tr");
            tbody.appendChild(tr);
            ...
            tr.onclick = () => console.log(tr);

Ý tưởng là bấm vào dòng nào thì sẽ xử lý dữ liệu của dòng đó. Nhưng mà mình chạy thì bấm vào dòng nào browser cũng tính là click vào dòng cuối cùng, giờ không biết xử lý ra sao.

Update: Mình thử thay var thành let thì hết, nhưng cũng chưa rõ vì sao :stuck_out_tongue:

1 Like
-tr.onclick = () => console.log(this);

:kissing_smiling_eyes:

4 Likes

code ít quá cũng không biết là do cái gì, chỉ đoán 2 chỗ document.createElement(‘tr’) với dòng onclick. Mình dùng thử thằng insertRow thì ok click từng dòng được. https://codepen.io/banhmisg9509/pen/wvwrvrQ?editors=1011

5 Likes

Bạn nên tạo một hệ thống nhỏ, rồi đưa code lên đây cho mọi người thử.

2 Likes

You dont know js
hoisting

3 Likes

Do bạn có “vô tình” khai báo một biến bên ngoài trùng tên với tr.
Thử chạy đoạn của bạn @banhmisg9509 và thêm biến cùng tên ở ngoài hàm thì xuất hiện lỗi (tính năng :roll_eyes:) này.

4 Likes

Cái này gọi là hoisting của js rồi. Khi dùng từ khoá var để khai báo biến thì sự tự động đưa về đầu function. Nên dẫn đến sử dụng chung 1 biến tr. Việc có biến cùng tên bên ngoài vòng for hay không không có sự khác biệt. Để tránh lỗi này cần dùng let thay cho var hoặc immediately invoked function

6 Likes

Đúng là có một biến tr bên ngoài, nhưng kể cả mình có đổi thành trx thì vẫn bị thôi. Mình quen code kiểu C# nên dùng var theo cách của C#, nhưng thực ra cái mình muốn nó là let, nên mình đổi hết thành let và đã ok.

Dòng này có dấu trừ có ý nghĩa gì vậy bạn ơi? Mình search không ra :sweat_smile:
Còn vụ this thì mình tưởng phải set kiểu này để khi click thì chính đối tượng mới được truyền chứ nhể, chứ this trong hàm này đâu phải là tr đâu.

tr.setAttribute("onclick", "console.log(this)");

Ăn nhau ở chữ let bác à :sweat_smile:

4 Likes

Dấu trừ là vì nó sai rồi :kissing_smiling_eyes:

3 Likes

code của mình đúng nhé, confirm code của bạn sai nè :))

4 Likes

Cái này là do cái onlick là một function nên khi bạn click nó mới thực thi, khi đó, cái “var tr” khi chạy hết vòng lặp for là nó lưu giữ giá trị cuối cùng của vòng lặp, nên luôn luôn ra ở cuối là đúng rồi. Giờ sửa lại dòng này vậy:

tr.onclick = (e) => {console.log(e.target)}
1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?