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

时间:2018-10-07 18:28:07

标签: javascript arrays function for-loop

所以我正在学习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(){}”(据说是匿名函数?)来做,但是显然有一种叫做IIFE使用javascript编写,因此您必须WRAP函数并传递一个唯一变量以使其在循环中每次运行,尽管我仍然不明白为什么我必须以“(paragraph)”结尾。

我一直在想是否可以通过为每个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')
    }
}

为什么第一个(由易卜拉欣·马赫里尔提供)起作用而第二个却不起作用?

2 个答案:

答案 0 :(得分:0)

在第一个代码示例中,循环内的IIFE完全没有用,因为您已经在使用let,它遵守了块范围,因此this problem不会发生。以下代码可以正常工作:

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(由closures提供),就像这样:

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>

答案 1 :(得分:0)

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

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

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

TypeError出现在这里。带有参数“ red”的已调用changeToColor函数的结果(返回值)是一个变量。这不是功能。分配的处理程序必须适合原型function(Event e){...},其中e是https://developer.mozilla.org/en-US/docs/Web/API/Event

中定义的Event类的对象
div2paragraphs[paragraph].onmouseout = changeBackWhite;

这行是正确的,因为您正在将已定义的 function 的ID分配给占位符,然后可以将其用作实际的处理函数。

您需要做的是,重写功能changeToColor并将其ID分配给放油灯

div2paragraphs[paragraph].onmouseover = changeToColor

或者,如果要立即调用该函数,则可以使用以下命令将其包装在另一个具有this引用的函数中,该引用引用了它所属的上下文(如果调用函数需要this),请使用callapply

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

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