【问题标题】:how to pass argument in function for this.setattribute?如何在 this.setattribute 的函数中传递参数?
【发布时间】:2018-10-07 18:28:07
【问题描述】:

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

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

为什么第一个(由 ibrahim mahrir 提供)有效而第二个无效?

【问题讨论】:

  • 顺便说一句,您不需要循环内的内部 IIFE,因为您已经在使用 let。它尊重块范围。
  • 所以它不知道this 是什么? Yessssss :) this - JavaScript | MDN
  • 因为您的template literal 不正确。它应该是 `background-color: ${colors[paragraph]}` 而不是 `background-color: $(colors[paragraph]`。我的解决方案根本不使用模板文字,这就是我之前没有注意到它的原因。
  • 哦,谢天谢地,这只是一个错字,不是我发疯。非常感谢先生!

标签: javascript arrays function for-loop


【解决方案1】:

在第一个代码示例中,循环内的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>

【讨论】:

  • hmmm,有趣的是你的第一个例子是如何工作的,我最初写它的方式是 for (let paragraph = 0; paragraph &lt; div2paragraphs.length; paragraph++) { div2paragraphs[paragraph].onmouseover = function(){ this.setAttribute('style', background-color: $(colors[paragraph]) } div2paragraphs[paragraph].onmouseout = function(){ this.setAttribute('style', 'background-color: white') } } 但它仍然没有工作。这与尝试使用“setAttribute”有关吗?
  • @user3696118 不。我敢打赌你用的是var 而不是let,这就是它不起作用的原因。 var 不尊重块范围,因此需要 IIFE。但是let 解决了这个问题,所以不需要 IIFE。
  • 不,我确实使用了let,就像我在 cmets 中写的一样,仍然没有工作
  • 这在原帖 cmets 中得到了回答,但这是因为我的“模板文字”写得不正确......
  • @user3696118 是的,我知道。我写了那个原始的帖子评论;-)
【解决方案2】:

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

在分配事件处理程序时,您必须将处理程序 functions 分配给占位符。

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;

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

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

div2paragraphs[paragraph].onmouseover = changeToColor

或者,如果您想立即调用该函数,您可以使用 call 将其包装在另一个函数中,该函数具有 this 对其所属上下文的引用(如果调用函数需要 this)或apply

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

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

【讨论】:

  • 您好,谢谢您的回复,我实际上尝试在您键入的最后一个示例中编写它,但它仍然给了我相同的 TypeError.... 也带有“div2paragraphs[paragraph] .onmouseover = changeToColor" 示例,如何将自定义颜色传递给函数?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-03
  • 1970-01-01
  • 2022-01-12
相关资源
最近更新 更多