iT邦幫忙

0

javaScript 函數正常,但設定成變數後,無法綁定點及事件

更:本來的問題解決,想問另一個問題是,為什麼會產生那樣的結果,測試後問題是出在綁定點擊事件的時候,但原理不太明白,是因為 addEventListener 的機制嗎?

如題,函數設定成變數後導入參數的方式,會在一進頁面就啟動,而無法綁定點擊事件,請教我有什麼觀念漏掉了?

<body>
    <input id="btn" type="button" value="show-input">

    <script>
        const fileBtn = document.getElementById("btn");

        let showInput = function (input) {
            alert(input);
        };

        fileBtn.addEventListener("click", showInput("Hello World"));
    </script>
</body>
0
rogeryao
iT邦大師 1 級 ‧ 2021-05-21 23:52:55
<input id="btn" type="button" value="show-input" onclick="confirm()">
<script>
function confirm()
{
  alert("Hello World");
}
</script>

Demo

謝謝回答,後來有想到閉包,像下面那樣,我想要的是能輸入參數重複使用函數。

但仍然有問題,為什麼我第一個程式碼會產生那樣的結果,測試後問題是出在綁定點擊事件的時候,但原理不太明白,是因為 addEventListener 的機制嗎?

<body>
    <input id="en-btn" type="button" value="Hello">
    <input id="es-btn" type="button" value="Hola">

    <script>
        const enBtn = document.getElementById("en-btn"),
            esBtn = document.getElementById("es-btn");

        let showInput = function (input) {
            return function () {
                alert(input);
            }
        };

        enBtn.addEventListener("click", showInput("Hello"));
        esBtn.addEventListener("click", showInput("Hola"));
    </script>
</body>
rogeryao iT邦大師 1 級 ‧ 2021-05-22 10:14:50 檢舉

請參閱 : HTML DOM addEventListener() 方法
關鍵字:當傳遞參數值時,使用"匿名函數"調用帶參數的函數

謝謝你

2
Han
iT邦新手 1 級 ‧ 2021-05-22 09:58:57
const fileBtn = document.getElementById("btn");

let showInput = function (input) {
    alert(input);
};

fileBtn.addEventListener("click", showInput("Hello World"));

因為綁定事件,addEventListener 的第二個參數,要傳入 function
而你傳入的是showInput的執行結果

舉個簡單點的例子

function add(a, b) {
    return a+b;
}

// 這兩句等於一樣的意思
fileBtn.addEventListener("click", add(1,2));
fileBtn.addEventListener("click", 3);

所以你後來改成 showInput 回傳一個匿名 function 才會成功
你後來的結果會變成

fileBtn.addEventListener("click", function(input) {
    alert(input);
});

希望有解答到你的疑惑!

看更多先前的回應...收起先前的回應...

謝謝你,裡面要放函數點醒了我。
但我又想到alert本身不也是個函數嗎?所以測試了一下,猜測它是個 IIFE,而不是一般的匿名函數(總不會是具名函數吧@@);也蠻好奇會什麼是一進網頁就觸發的效果。

// 皆會在一進網頁便觸發
fileBtn.addEventListener("click", (function () {
    console.log("test");
    }()
)
);
fileBtn.addEventListener("click", alert("123"));
Han iT邦新手 1 級 ‧ 2021-05-23 21:43:58 檢舉

還是一樣那句話,你放的是執行過後的產物
你要傳入的是一個函數,這樣每次觸發才會被執行

let clickFunction = function() {
    alert("click");
    return true;
}
fileBtn.addEventListener("click", clickFunction);
// 等同於
fileBtn.addEventListener("click", function() {
    alert("click");
    return true;
});
fileBtn.addEventListener("click", clickFunction());
// 等同於
fileBtn.addEventListener("click", true);

這兩個的執行結果大不同,請好好消化

了解,我被另一個測試搞亂

let fileBtn = document.getElementById("btn");
var showInput = function () {
    return alert(123);
};
fileBtn.addEventListener("click", showInput);
// 我以為等同於
fileBtn.addEventListener("click", alert(123));
// 但其實是
fileBtn.addEventListener("click", function () {
    return alert(123);
});
// 還是一個匿名函數,所以能成功

謝謝你。/images/emoticon/emoticon41.gif

Han iT邦新手 1 級 ‧ 2021-05-23 23:56:43 檢舉
fileBtn.addEventListener("click", alert(123));
fileBtn.addEventListener("click", showInput());

相同
所以才會直接執行

0
貓虎皮
iT邦新手 5 級 ‧ 2021-05-23 14:11:20

錯誤點:addEventListener的第二參數

函式內的變數不得為函式,
若為函式會因錯誤而直接執行之。
在此可以用箭頭函式來編寫:

<body>
    <input id="btn" type="button" value="show-input">

    <script>
        const fileBtn = document.getElementById("btn");

        let showInput = function(input){
            alert(input);
        };

        fileBtn.addEventListener("click", () => {showInput("Hello World")});
    </script>
</body>

關於箭頭函示,
可以參考=>MDN-箭頭函式

「函式內的變數不得為函式,若為函式會因錯誤而直接執行之。」我消化一下@@

謝謝你,不過還好我沒忘老師有教到這個語法糖,雖然還不太熟悉/images/emoticon/emoticon16.gif

我要發表回答

立即登入回答