为什么这段代码不起作用的答案是因为:这个方法的问题是你没有提供一个函数作为第二个参数。你正在调用一个函数 - 该函数使事情变成蓝色。它没有返回使事情变成蓝色的功能。因此,您可以立即将事情变成蓝色,当点击发生时,没有什么可以调用的,因为您调用的函数没有返回任何内容。
但是我在第一句话后输了。有人可能会愚蠢吗?也许对代码的直观解释会有所帮助!
代码:https://jsfiddle.net/2yfj89af/1/
var submitSOBox = document.getElementsByClassName("submitSOBox");
for (i = 0; i < submitSOBox.length; i++) {
submitSOBox[i].addEventListener('click', SOBoxColor(i));
}
function SOBoxColor(i) {
submitSOBox[i].style.backgroundColor = "blue";
}
答案 0 :(得分:2)
原因解释:你有这一行:
submitSOBox[i].addEventListener('click', SOBoxColor(i));
这会调用addEventListener
,它将函数作为最后一个参数。您提供的SOBoxColor(i)
不是函数,而是函数返回的值 - 您可以调用它。要传递函数,您需要传递类似SOBoxColor
的内容,因此无需调用它。这是必需的,因为您的浏览器需要知道单击事件发生时要调用的内容。
现在,仅传递SOBoxColor
将无法满足您的需求。是的,它会在点击发生时调用SOBoxColor
,但您不会传递i
值。
要实现这一点,您需要修改一个函数版本,以某种方式预先填充i
值作为参数。幸运的是,有一种方法可以使用bind
方法创建这样一个修改过的函数,该方法返回相同的函数,但是它绑定了一些东西:
submitSOBox[i].addEventListener('click', SOBoxColor.bind(submitSOBox[i], i));
bind
的第一个参数确定在调用SOBoxColor
时特殊this
对象将代表什么,第二个参数是i
将是什么。
现在,这将有效。
但是如果你在this
函数中使用SOBoxColor
关键字,你可以做得更好,因为那时你甚至不需要i
参数:
function SOBoxColor() {
this.style.backgroundColor = "blue";
}
...你的绑定也可以没有i
参数:
submitSOBox[i].addEventListener('click', SOBoxColor.bind(submitSOBox[i]));
它仍然可以更简洁地完成,因为当点击发生时,浏览器已经为我们提供了一个很好的服务:它将this
关键字设置为您添加事件处理程序的元素,因此最后,甚至不必明确地将submitSOBox[i]
绑定到它。这也可以:
submitSOBox[i].addEventListener('click', SOBoxColor);
...前提是您更改了SOBoxColor
功能以使用this
。
答案 1 :(得分:0)
当您添加事件监听器时:
submitSOBox[i].addEventListener('click', SOBoxColor(i));
调用函数SOBoxColor()
,期望它返回一个在触发事件监听器时调用的函数。
通过返回一个函数,我的意思是这样的:
function SOBoxColor(){
return function(){
alert("hello")
//Do stuff
}
}
如果您将当前函数替换为上面的函数,则只要触发了单击侦听器,它就会发出“hello”警告。
你会如何解决这个问题?
只需将函数名称放入其中,而无需调用它:
submitSOBox[i].addEventListener('click', SOBoxColor);
现在您将遇到的问题是SOBoxColor
:
function SOBoxColor(i) {
submitSOBox[i].style.backgroundColor = "blue";
}
您要将数字作为参数发送,以选择相应的元素,您不能再这样做了。
但是,这不是问题,因为您首先选择的元素不正确。
不要在HTMLCollection
submitSOBox
中使用它的索引选择它,只需使用this
关键字引用当前元素:
function SOBoxColor() {
this.style.backgroundColor = "blue";
}
因此,您的完整代码现在应该如下所示:
var submitSOBox = document.getElementsByClassName("submitSOBox");
for (var i = 0; i < submitSOBox.length; i++) {
submitSOBox[i].addEventListener('click', SOBoxColor);
}
function SOBoxColor() {
this.style.backgroundColor = "blue";
}
答案 2 :(得分:0)
你假设必须通过
来调用函数functionName();
但这并不是调用函数的唯一方法。您可以输入函数作为参数,使用调用方法:functionName.call(null,args)
等。
functionName();
做的是让Javascript去,“嘿,我需要找出该函数返回的内容。”所以如果functionName就像
function functionName(){
console.log("hello!");
return undefined;
};
Javascript会尝试简化一切。它会运行你的函数,控制台日志“你好!”当它忙于工作时,最后会弄清楚你的函数返回的内容:
undefined;
把它想象成在代数类或其他东西中简化数学表达式。
在你的情况下,你告诉点击事件要调用 SOBoxColor(i)返回的任何内容。所以如果SOBoxColor看起来像这样:
function SOBoxColor(i) {
submitSOBox[i].style.backgroundColor = "blue";
return 9000;
}
您的点击事件如下所示:
for (i = 0; i < submitSOBox.length; i++) {
submitSOBox[i].addEventListener('click', 9000);
}
addEventListener是一个函数,它希望函数作为第二个参数,而不是数字。所以什么都不会发生。
答案 3 :(得分:0)
正如你所说,该函数什么都不返回。实际上它根本不是一个功能。闭包的想法是返回函数,它使用外部作用域中的值。
var submitSOBox = document.getElementsByClassName("submitSOBox");
for (i = 0; i < submitSOBox.length; i++) {
//changes are possible here but we'll do it later
submitSOBox[i].addEventListener('click', SOBoxColor(i));
//in your initial code SOBoxColor(i) returned undefined (no return)
//and event listener must be a function. Yours was not.
}
//change your function like this:
function SOBoxColor(i) {
//get the element from collection.
//both collection and i are available at this point
var elem = submitSOBox[i];
return function(){
//function knows elem from parent scope
elem.style.backgroundColor = "blue";
};
}
我希望这些解释很有帮助。
这是关闭的练习。如果不是那么它将是更简单的解决方案:
var submitSOBox = document.getElementsByClassName("submitSOBox");
for (i = 0; i < submitSOBox.length; i++) {
submitSOBox[i].addEventListener('click', function(){
this.style.backgroundColor = "blue";
//in this context **this** is clicked element
});
}
答案 4 :(得分:0)
基本上
submitSOBox[i].addEventListener('click', SOBoxColor(i));
他正在使用函数SOBoxColor,其当前值为i作为参数。 此外,当您向元素添加事件侦听器时,您已经具有指向DOM元素的隐式值。所以只需更改代码:
function SOBoxColor() {
this.style.backgroundColor = "blue";
}
var submitSOBox = document.getElementsByClassName("submitSOBox");
for (i = 0; i < submitSOBox.length; i++) {
submitSOBox[i].addEventListener('click', SOBoxColor);//your passing the function
}
使用jQuery也很简单:
$(".submitSOBox").click(function(){ $(this).css("background-color","blue"); });