为什么我的闭包在我使用 addEventListener 方法时有效,但没有使用 onclick HTML 属性
Why Is My Closure working when I use the addEventListener method, but not with the onclick HTML attribute
我尝试让一个按钮只被点击一次。
var user, sales, data;
function getBill(user, sales, data) {
window.alert("Here is your bill.");
//do the billing process
}
const once = fn => {
let finished = false;
return (...args) => {
if (!finished) {
finished = true;
fn(...args);
}
};
};
当我将此 HTML 与 onclick 一起使用时。每次我点击按钮时按钮都会提醒,因为它进入一次并将“完成”设置回 false。
<button id="billButton" onclick="once(getBill)(user,sales,data)">Pay Order</button>
但是,移除onclick属性并使用“addEventListener”方法使得该按钮只能点击一次。
document.getElementById("billButton").addEventListener('click' ,once(getBill)(user, sales, data));
它是怎么来的,如何使用“onclick”属性?我知道属性侦听器是不好的做法,但这不是术语。它应该可以正常工作。
我错过了什么?
您没有正确使用 addEventListener
,因为您没有添加事件。
另一个建议是做我所做的,所以点击按钮启动你的功能,然后用没有 EventListener
的新按钮替换旧按钮,比如:
const user = 'simon',
sales = '1',
data = 'today',
button = document.getElementById("billButton");
function getBill(user, sales, data) {
//tips add load here
window.alert("Here is your bill.");
//on finish stop loader
}
button.addEventListener('click', () => {
getBill(user, sales, data);
let buttonClone = button.cloneNode(true); // create clone html (don't clone the event)
button.parentNode.replaceChild(buttonClone, button); // replace it
buttonClone.disabled = true; //disable button
});
<button id="billButton">Pay Order</button>
首先,让我们看看HTML
中的onclick
属性是如何工作的:
- 它只会以纯文本形式存储函数调用语句。
- 当您单击该元素时,它会检查
onclick
属性中是否有任何内容。
- 如果
onclick
属性中有任何东西,它只会用eval
执行它。
回到你的代码,每当你点击按钮时,它总是会显示警报,因为它每次都会调用一个新函数,它不会存储 return 从 [=20] 编辑的函数=].
var user, sales, data;
function getBill(user, sales, data) {
window.alert("Here is your bill.");
}
const once = fn => {
let finished = false;
return (...args) => {
if (!finished) {
finished = true;
fn(...args);
}
};
};
<button id="billButton" onclick="once(getBill)(user,sales,data)">Pay Order</button>
现在,让我们看看 eventListener
是如何工作的:
- EventListeners 将函数引用绑定到事件。
- 因此,每当该特定事件发出时,它都会调用绑定到它的函数。
再次回到您的代码,您没有将函数绑定到 eventListener
,而是将函数的 return 值绑定到事件,在本例中为 undefined
.
绑定高阶函数响应的正确方法是,使用bind
,是:
document.getElementById("billButton").addEventListener('click' ,once(getBill).bind(this, user, sales, data));
var user, sales, data;
function getBill(user, sales, data) {
window.alert("Here is your bill.");
}
const once = fn => {
let finished = false;
return (...args) => {
if (!finished) {
finished = true;
fn(...args);
}
};
};
document.getElementById("billButton").addEventListener('click', once(getBill).bind(this, user, sales, data));
<button id="billButton">Pay Order</button>
我尝试让一个按钮只被点击一次。
var user, sales, data;
function getBill(user, sales, data) {
window.alert("Here is your bill.");
//do the billing process
}
const once = fn => {
let finished = false;
return (...args) => {
if (!finished) {
finished = true;
fn(...args);
}
};
};
当我将此 HTML 与 onclick 一起使用时。每次我点击按钮时按钮都会提醒,因为它进入一次并将“完成”设置回 false。
<button id="billButton" onclick="once(getBill)(user,sales,data)">Pay Order</button>
但是,移除onclick属性并使用“addEventListener”方法使得该按钮只能点击一次。
document.getElementById("billButton").addEventListener('click' ,once(getBill)(user, sales, data));
它是怎么来的,如何使用“onclick”属性?我知道属性侦听器是不好的做法,但这不是术语。它应该可以正常工作。
我错过了什么?
您没有正确使用 addEventListener
,因为您没有添加事件。
另一个建议是做我所做的,所以点击按钮启动你的功能,然后用没有 EventListener
的新按钮替换旧按钮,比如:
const user = 'simon',
sales = '1',
data = 'today',
button = document.getElementById("billButton");
function getBill(user, sales, data) {
//tips add load here
window.alert("Here is your bill.");
//on finish stop loader
}
button.addEventListener('click', () => {
getBill(user, sales, data);
let buttonClone = button.cloneNode(true); // create clone html (don't clone the event)
button.parentNode.replaceChild(buttonClone, button); // replace it
buttonClone.disabled = true; //disable button
});
<button id="billButton">Pay Order</button>
首先,让我们看看HTML
中的onclick
属性是如何工作的:
- 它只会以纯文本形式存储函数调用语句。
- 当您单击该元素时,它会检查
onclick
属性中是否有任何内容。 - 如果
onclick
属性中有任何东西,它只会用eval
执行它。
回到你的代码,每当你点击按钮时,它总是会显示警报,因为它每次都会调用一个新函数,它不会存储 return 从 [=20] 编辑的函数=].
var user, sales, data;
function getBill(user, sales, data) {
window.alert("Here is your bill.");
}
const once = fn => {
let finished = false;
return (...args) => {
if (!finished) {
finished = true;
fn(...args);
}
};
};
<button id="billButton" onclick="once(getBill)(user,sales,data)">Pay Order</button>
现在,让我们看看 eventListener
是如何工作的:
- EventListeners 将函数引用绑定到事件。
- 因此,每当该特定事件发出时,它都会调用绑定到它的函数。
再次回到您的代码,您没有将函数绑定到 eventListener
,而是将函数的 return 值绑定到事件,在本例中为 undefined
.
绑定高阶函数响应的正确方法是,使用bind
,是:
document.getElementById("billButton").addEventListener('click' ,once(getBill).bind(this, user, sales, data));
var user, sales, data;
function getBill(user, sales, data) {
window.alert("Here is your bill.");
}
const once = fn => {
let finished = false;
return (...args) => {
if (!finished) {
finished = true;
fn(...args);
}
};
};
document.getElementById("billButton").addEventListener('click', once(getBill).bind(this, user, sales, data));
<button id="billButton">Pay Order</button>