Dùng event onload để gán event listener không được

Em đang muốn làm một cái dropdown list khi người dùng chọn một item bất kỳ thì sẽ hiện ra giá ở bên cạnh. Em có thử được một cách là sử dụng event listener ở bên html còn function thì đặt bên Javascript
code HTML:

<!DOCTYPE html>
<head>
<script src="test.js"></script>

</head>
<html>
<body>

<p>Select an item from the list.</p>

<select id="mySelect" onchange="myFunction()">
<option value="item1">item1
<option value="item2">item2
<option value="item3">item3
<option value="item4">item4
</select>

<p>Price: <span id="demo"></span></p>

</body>
</html>

code Js:

"use strict";
function myFunction() {
    var x = document.getElementById("mySelect").value;
    var price = document.getElementById("demo");
    switch(x) {
        case "item1":
        price.innerHTML = "300,000";
        break;
        case "item2":
        price.innerHTML = "500,000";
        break;
        case "item3":
        price.innerHTML = "800,000";
        break;
        case "item4":
        price.innerHTML = "900,000";
        break;
        }
      }
      function init() {
      }
      window.onload = init;

Nhưng khi em mang cái event listener “onchange” từ HTML sang bỏ vào trong init() của Js thì nó lại không hoạt động

"use strict";

function myFunction() {
    var x = document.getElementById("mySelect").value;
    var price = document.getElementById("demo");
    switch(x) {
        case "item1":
        price.innerHTML = "300,000";
        break;
        case "item2":
        price.innerHTML = "500,000";
        break;
        case "item3":
        price.innerHTML = "800,000";
        break;
        case "item4":
        price.innerHTML = "900,000";
        break;
    }
    }
    function init() {
    document.getElementById("mySelect").onchange = myFunction();
    }
    window.onload = init;

Mọi người có thể giải thích cho em đc ko ạ. Em cảm ơn
P/s: Em có nghĩ đến lý do là tại vì cái init() nó chỉ call 1 lần khi window load thôi nhưng mà em thử với lại .onclick thì lại làm được nhiều lần…

Bạn code dư dấu ngoặc rồi :penguin:

Trong JS, thuộc tính onchange sẽ nhận một hàm (event listener). Khi bạn thêm ngoặc đơn vào thì bạn gọi hàm đó, cụ thể là myFunction. myFunction vì không trả về cái gì nên kết quả trả về của nó sẽ được tính là undefined, onchange mặc định cũng là undefined nên dòng trên vô dụng.

5 Likes

Viết lại như vầy sẽ đúng phải không bạn Gà Coder @HR16 ? Trong JavaScript thì hàm cũng là Object nên rất gây bối rối khi nào gọi hàm, khi nào xem nó như là một “biến” Object.

3 Likes

Dòng trên thì sai, dòng dưới lại đúng. 2 dòng này cơ bản là giống nhau về cách gán sự kiện.

3 Likes

Mình xóa cái ngoặc đi thì nó lại hoạt động được :sweat_smile:. @HR16 Bạn giải thích kỹ hơn phần khi nào cần có ngoặc khi nào không được không nhỉ…

em chưa hiểu kỹ về cái gán sự kiện này lắm, anh giải thích kỹ hơn được không ạ…

Sự kiện nhận tên hàm hay có thể hiểu là 1 biến trỏ đến hàm đó.
init là biến trỏ đến hàm init. Bạn làm đúng.
Với myFunction thì tương tự, bạn chỉ cần gán bằng tên thôi.
Còn bạn dùng myFunction()cặp ngoặc tròn tức là bạn gọi hàm và gán giá trị trả về của hàm cho sự kiện.
Kiểu như này:

var res = myFucntion();
...onchange = res;

Mà hàm myFucntion của bạn đâu có trả về cái gì (undefined).

JS

Ờ mà, đây là Javascript, nó rất khùng theo 1 cách khó hiểu. Nhưng nếu hiểu nó thì bạn sẽ bị điên. :smiling_imp:

var s = "SITUVN";
isNaN(s); // true
Number.isNaN(s); // false

Có lý do cả: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN

Hiểu nó rất khó, vì có những quy tắc rất khó nhớ.
Cứ tìm hiểu toán tử == thôi là có 1 bầu trời kiến thức rồi.

4 Likes

thế còn khi em gọi hàm bằng cách đặt onchange ở trong HTML thì nó lại không dùng cái quy tắc này ạ ?..

Bạn có thể hiểu đơn giản thế này. Giá trị của thuộc tính onchange trong HTML là một đoạn code Javascript, đoạn code đó sẽ được bọc trong một cái hàm, hàm đó chính là event listener của event onchange. Ví dụ:

onchange ở trên tương đương với:

document.getElementById("mySelect").onchange = function(){
     myFunction()
}
//Không tương đương với arrow function

Khi bạn viết myFunction(có thể có tham số gì đó) thì bạn đang gọi hàm đó, còn khi viết myFunction thì bạn đang chỉ tới hàm đó, chứ không phải là gọi nó. Khi bạn gán một biến, hoặc thuộc tính là một (biến kiểu) hàm, bạn đang gán giá trị của hàm (bao gồm cái đoạn code viết bên trong) cho biến, hoặc thuộc tính đó. Ví dụ:

function myFunction() {
    var x = document.getElementById("mySelect").value;
    var price = document.getElementById("demo");
    switch(x) {
        case "item1":
        price.innerHTML = "300,000";
        break;
        case "item2":
        price.innerHTML = "500,000";
        break;
        case "item3":
        price.innerHTML = "800,000";
        break;
        case "item4":
        price.innerHTML = "900,000";
        break;
        }
      }
document.getElementById("mySelect").onchange = myFunction

Tương đương với:

document.getElementById("mySelect").onchange = function() {
var x = document.getElementById("mySelect").value;
    var price = document.getElementById("demo");
    switch(x) {
        case "item1":
        price.innerHTML = "300,000";
        break;
        case "item2":
        price.innerHTML = "500,000";
        break;
        case "item3":
        price.innerHTML = "800,000";
        break;
        case "item4":
        price.innerHTML = "900,000";
        break;
        }
      
}
3 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?