如何在函数中为 this.setattribute 传递参数?



所以我正在学习javascript(?(,我遇到了这种情况,我真的找不到一个直接的答案。

所以我在一个 HTML 页面中有这些段落,我想更改其背景颜色,我工作的代码是这样的:

var colors=['red','pink','blue'];
var div2paragraphs = document.querySelectorAll('#div2 p')
for (let paragraph = 0; paragraph < div2paragraphs.length; paragraph++) {
(function(paragraph) {
div2paragraphs[paragraph].onmouseover = function(){
this.setAttribute('style', `background-color: ${colors[paragraph]}`)}
div2paragraphs[paragraph].onmouseout = function(){
this.setAttribute('style', 'background-color: white')}
})(paragraph);
}

我也不太明白这里发生了什么,我只是想用整个"function(({}"的东西(据说称为匿名函数?(来做到这一点,但显然在 javascript 中有一种叫做 IIFE 的东西,所以你必须包装函数并传递一个唯一的变量,让它每次在循环中运行, 虽然我仍然不明白为什么我必须用"(段落("结束它。

我在想是否可以通过为每个 setAttribute 操作创建一个函数来做同样的事情,所以我尝试这样写:

var colors=['red','pink','blue'];
var div2paragraphs = document.querySelectorAll('#div2 p')
function changeToColor(color) {
this.setAttribute('style', 'background-color: ' + color);
}
function changeBackWhite() {
this.setAttribute('style', 'background-color: white');
}
for (let paragraph = 0; paragraph < div2paragraphs.length; paragraph++) {
div2paragraphs[paragraph].onmouseover = changeToColor('red');
div2paragraphs[paragraph].onmouseout = changeBackWhite;
}

但无论我做什么,它总是会出现错误:

Uncaught TypeError: this.setAttribute is not a function

或类似的东西。 我认为它与这些情况有关,如果您添加括号,它会在执行其他任何操作之前调用该函数? 所以它不知道"这"是什么? 我不太明白,但无论如何,我对如何用单独的功能编写我上面所做的同样的事情一无所知。 有人能够对此有所了解吗?

我更习惯于Python,所以显然有一些基本概念是不同的......

PS:下面这两个例子有什么区别?

for (let paragraph = 0; paragraph < div2paragraphs.length; paragraph++) {
div2paragraphs[paragraph].onmouseover = function() {
this.style['background-color'] = colors[paragraph];
}
div2paragraphs[paragraph].onmouseout = function() {
this.style['background-color'] = 'white';
}
}

而这个

for (let paragraph = 0; paragraph < div2paragraphs.length; paragraph++) {
div2paragraphs[paragraph].onmouseover = function(){
this.setAttribute('style', `background-color: $(colors[paragraph]`)
}
div2paragraphs[paragraph].onmouseout = function(){
this.setAttribute('style', 'background-color: white')
}
}

为什么第一个(由易卜拉欣·马格里尔提供(有效,而第二个不起作用?

在第一个代码示例中,循环中的 IIFE 完全没用,因为您已经在使用尊重块范围的let,因此不会发生此问题。以下代码可以正常工作:

for (let paragraph = 0; paragraph < div2paragraphs.length; paragraph++) {
div2paragraphs[paragraph].onmouseover = function() {
this.style['background-color'] = colors[paragraph];
};
div2paragraphs[paragraph].onmouseout = function() {
this.style['background-color'] = 'white';
};
}

注意:您无需使用setAttribute即可设置style属性。直接做就行了。

演示:

var colors=['red','pink','blue'];
var div2paragraphs = document.querySelectorAll('#div2 p');
for (let paragraph = 0; paragraph < div2paragraphs.length; paragraph++) {
div2paragraphs[paragraph].onmouseover = function() {
this.style['background-color'] = colors[paragraph];
};
div2paragraphs[paragraph].onmouseout = function() {
this.style['background-color'] = 'white';
};
}
<div id="div2">
<p>AAAA</p>
<p>BBBB</p>
<p>CCCC</p>
</div>


至于第二个代码示例,您的函数需要返回其他函数以分配为事件侦听器。例如,changeColor应按如下定义:

function changeToColor(color) {
return function() {
this.style['background-color'] = color;
}
}

changeColor返回的匿名函数将分配给事件侦听器。在您的代码中,changeColor未返回任何内容,因此undefined附加到事件侦听器。此外,changeColor不是事件侦听器本身(它只是一个创建事件侦听器并返回它的函数(,因此this里面将是全局对象windowwindow没有一个名为setAttribute的方法,因此会出现错误。

此外,您不需要changeBackWhite,您可以将changeColor用于两者(由闭包提供(,如下所示:

for (let paragraph = 0; paragraph < div2paragraphs.length; paragraph++) {
div2paragraphs[paragraph].onmouseover = changeToColor(colors[paragraph]);
div2paragraphs[paragraph].onmouseout = changeToColor('white');;
}

演示:

var colors=['red','pink','blue'];
var div2paragraphs = document.querySelectorAll('#div2 p');
function changeToColor(color) {
return function() {
this.style['background-color'] = color;
}
}
for (let paragraph = 0; paragraph < div2paragraphs.length; paragraph++) {
div2paragraphs[paragraph].onmouseover = changeToColor(colors[paragraph]);
div2paragraphs[paragraph].onmouseout = changeToColor('white');;
}
<div id="div2">
<p>AAAA</p>
<p>BBBB</p>
<p>CCCC</p>
</div>

https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Event_handlers

分配事件处理程序时,必须将处理程序函数分配给占位符。

div2paragraphs[paragraph].onmouseover = changeToColor('red');

TypeError发生在这里。参数为"red"的调用changeToColor函数的结果(返回值(是一个变量。这不是一个函数。分配的处理程序必须适合原型function(Event e){...}其中 e 是 Event 类的对象,如 https://developer.mozilla.org/en-US/docs/Web/API/Event

div2paragraphs[paragraph].onmouseout = changeBackWhite;

但是,此行是正确的,因为您将已定义函数的 ID 分配给占位符,然后该占位符可用作真正的处理程序函数。

您需要做的是,重写函数 changeToColor 并将其 ID 分配给占位器

div2paragraphs[paragraph].onmouseover = changeToColor

或者,如果要立即调用该函数,可以使用callapply将其包装在另一个this引用其所属上下文的函数中(如果调用函数需要this(。

div2paragraphs[paragraph].onmouseover = function () {
changeToColor.call(this, 'red');
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

最新更新