Javascript .map()不是一个函数。

34

我是新手(也是JavaScript新手),请原谅我的超级基础问题。 我有一个HTML页面,其中有不同的图片,它们都共享一个类。使用getElementsByClassName,我可以获得一个数组。我想通过使用.map()函数将事件监听器添加到数组中的每个单元格。

这是我拥有的:

window.onload = function(){
var allImgs = document.getElementsByClassName("pft");

var newImgs = allImgs.map(
        function(arrayCell){
            return arrayCell.addEventListener("mouseover, functionName");
        }
    );
}; 

即使我将内部函数更改为不包含事件监听器的内容,它仍然显示错误"allImgs.map不是一个函数"。

我有另一个版本的代码,在window.onload中只需循环遍历数组单元格并以这种方式向每个单元格添加事件侦听器即可正常工作。为什么.map()函数不起作用? 它不能在window.onload中使用吗?

5个回答

48

getElementsByClassName() 返回的是一个 HTMLCollection 而不是一个 Array。你需要先将其转换为 JavaScript 数组:

allImgs = Array.prototype.slice.call(allImgs);

// or
allImgs = [].slice.call(allImgs);

// or (thanks @athari)
allImgs = Array.from(allImgs);

// or (thanks @eliaz-bobadilla)
allImgs = [...allImgs]

https://dev59.com/h3VC5IYBdhLWcg3wpi98 - baao
@ Flawyte Eek,对我来说还没有起作用。我可能忽略了一些非常基本的东西。这是我的代码:`window.onload = function(){ var allImgs = document.getElementsByClassName("pft"); var newImgs = [].slice.call(allImgs); console.log(newImgs.typeof); newImgs.map( function(arrayCell){ return arrayCell.addEventListener("mouseover, flipOver"); } ); };` - JSn00b
@Flawyte 抱歉,上面评论中的控制台日志只显示为“未定义”。它似乎没有转换成数组? - JSn00b
@Flawyte 啊啊啊,我自己找到了,抱歉;我的addEventListener括号里的内容搞错了(引号用错了)。谢谢! - JSn00b
1
现代浏览器支持Array.from,它比Array.prototype.slice.call更简洁。 - Athari
我使用 Object.entries(document.getElementsByTagName('button')),从那里你就拥有了全部的能力。 - Stephan Ahlf

9
使用 getElementsByClassName 方法,你会得到一个数组。但实际上不是这样的。
你得到的是一个实时的 HTMLCollection,它类似于数组,但并不是真正的数组。
由于它足够类似于数组,所以你可以在它上面应用真正数组的 map 方法。

    var text_content = [].map.call(
      document.getElementsByClassName("sdf"),
      function (currentValue, index, collection) {
        return currentValue.innerHTML;
      }
    );
    console.log(text_content);
  <p class="sdf">foo</p>
  <p class="sdf"></p>
  <p class="sdf">bar</p>
  <p class="sdf"></p>
  <p class="sdf"></p>
          


1
哦,我明白了,谢谢你澄清。所以我不能在它上面使用.map(),因为它不是真正的数组?但我仍然可以像从数组中获取一样访问它的单元格(例如htmlColls[i].addEventListener等)吗? - JSn00b

6
另一个选择是直接使用map
[].map.call(allImages, function() { ... });

然而,你正在做的最好使用Array.prototype.forEach实现。

4

紧凑语法:

[...document.getElementsByClassName("pft")].map(arrayCell => arrayCell.addEventListener("mouseover", "functionName"))

0

var elms = document.querySelectorAll('.demo');
for(var i = 0; i < elms.length; i++) {
  var elm = elms[i];
  elm.onmouseleave = function() {
    this.style.color = "#000";
  }
  elm.onmouseover = function() {
    this.style.color = 'red';
  }
  
  
}
.demo {
  cursor:pointer;
}
<div>
  <p class="demo">paragraph one</p>
  <p class="demo">paragraph two</p>
  <p class="demo">paragraph three</p>
  <p class="demo">paragraph four</p>
  <p class="demo">paragraph five</p>
  <p class="demo">paragraph six</p>
</div>


querySelectorAll在IE中不受支持。 - Abhinav Kumar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接