Addeventlistener is not a function как исправить

I’m getting an “.addEventListener is not a function” error. I am stuck on this:

var comment = document.getElementsByClassName("button");
function showComment() {
  var place = document.getElementById('textfield');
  var commentBox = document.createElement('textarea');
  place.appendChild(commentBox);
}
comment.addEventListener('click', showComment, false);
<input type="button" class="button" value="1">
<input type="button" class="button" value="2">
<div id="textfield">
</div>

agrm's user avatar

agrm

3,7044 gold badges26 silver badges36 bronze badges

asked Aug 15, 2015 at 18:28

leecarter's user avatar

3

The problem with your code is that the your script is executed prior to the html element being available. Because of the that var comment is an empty array.

So you should move your script after the html element is available.

Also, getElementsByClassName returns html collection, so if you need to add event Listener to an element, you will need to do something like following

comment[0].addEventListener('click' , showComment , false ) ; 

If you want to add event listener to all the elements, then you will need to loop through them

for (var i = 0 ; i < comment.length; i++) {
   comment[i].addEventListener('click' , showComment , false ) ; 
}

answered Aug 15, 2015 at 18:30

Nikhil Aggarwal's user avatar

Nikhil AggarwalNikhil Aggarwal

28.1k4 gold badges43 silver badges59 bronze badges

1

document.getElementsByClassName returns an array of elements. so may be you want to target a specific index of them: var comment = document.getElementsByClassName('button')[0]; should get you what you want.

Update #1:

var comments = document.getElementsByClassName('button');
var numComments = comments.length;

function showComment() {
  var place = document.getElementById('textfield');
  var commentBox = document.createElement('textarea');
  place.appendChild(commentBox);
}

for (var i = 0; i < numComments; i++) {
  comments[i].addEventListener('click', showComment, false);
}

Update #2: (with removeEventListener incorporated as well)

var comments = document.getElementsByClassName('button');
var numComments = comments.length;

function showComment(e) {
  var place = document.getElementById('textfield');
  var commentBox = document.createElement('textarea');
  place.appendChild(commentBox);
  for (var i = 0; i < numComments; i++) {
    comments[i].removeEventListener('click', showComment, false);
  }
}

for (var i = 0; i < numComments; i++) {
  comments[i].addEventListener('click', showComment, false);
}

Aldo D'Aquino's user avatar

answered Aug 15, 2015 at 18:30

Tahir Ahmed's user avatar

Tahir AhmedTahir Ahmed

5,6872 gold badges17 silver badges28 bronze badges

8

var comment = document.getElementsByClassName("button");

function showComment() {
  var place = document.getElementById('textfield');
  var commentBox = document.createElement('textarea');
  place.appendChild(commentBox);
}

for (var i in comment) {
  comment[i].onclick = function() {
    showComment();
  };
}
<input type="button" class="button" value="1">
<input type="button" class="button" value="2">
<div id="textfield"></div>

Zoe stands with Ukraine's user avatar

answered Dec 22, 2017 at 12:05

antelove's user avatar

anteloveantelove

3,10025 silver badges20 bronze badges

The first line of your code returns an array and assigns it to the var comment, when what you want is an element assigned to the var comment…

var comment = document.getElementsByClassName("button");

So you are trying to use the method addEventListener() on the array when you need to use the method addEventListener() on the actual element within the array. You need to return an element not an array by accessing the element within the array so the var comment itself is assigned an element not an array.

Change…

var comment = document.getElementsByClassName("button");

to…

var comment = document.getElementsByClassName("button")[0];

answered Jun 8, 2018 at 21:11

DreamBird's user avatar

DreamBirdDreamBird

511 silver badge2 bronze badges

Another important thing you need to note with “.addEventListener is not a function” error is that the error might be coming a result of assigning it a wrong object eg consider

let myImages = ['images/pic1.jpg','images/pic2.jpg','images/pic3.jpg','images/pic4.jpg','images/pic5.jpg'];
let i = 0;
while(i < myImages.length){
  const newImage = document.createElement('img');
  newImage.setAttribute('src',myImages[i]);
  thumbBar.appendChild(newImage);

 //Code just below will bring the said error 
 myImages[i].addEventListener('click',fullImage);

 //Code just below execute properly 
  newImage.addEventListener('click',fullImage);




  i++;
}

In the code Above I am basically assigning images to a div element in my html dynamically using javascript. I’ve done this by writing the images in an array and looping them through a while loop and adding all of them to the div element.

I’ve then added a click event listener for all images.

The code “myImages[i].addEventListener(‘click’,fullImage);” will give you an error of “addEventListener is not a function” because I am chaining an addEventListener to an array object which does not have the addEventListener() function.

However for the code “newImage.addEventListener(‘click’,fullImage);” it executes properly because the newImage object has access the function addEventListener() while the array object does not.

For more clarification follow the link: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Not_a_function

answered Apr 9, 2020 at 5:33

MosesK's user avatar

MosesKMosesK

3493 silver badges7 bronze badges

The main reason of this error is this line

document.getElementsByClassName("button")

Cause the getElementsByClassName returns an array-like object of all child elements or a collection of elements.

There are two possible solutions AFAIK –

  1. Treat the variable containing document.getElementsByClassName("button") as an array and be specific when using an event listener.
    Example –

    comment[0].addEventListener('click' , showComment , false )

  2. Use id for selecting that specific element.
    Example-

    document.getElementById('button')

answered Oct 23, 2022 at 13:59

Mohammad Mustak Absar Khan's user avatar

Try this one:

var comment = document.querySelector("button");
function showComment() {
  var place = document.querySelector('#textfield');
  var commentBox = document.createElement('textarea');
  place.appendChild(commentBox);
}
comment.addEventListener('click', showComment, false);

Use querySelector instead of className

Nick's user avatar

Nick

137k22 gold badges57 silver badges95 bronze badges

answered May 19, 2018 at 12:38

midnightgamer's user avatar

midnightgamermidnightgamer

4441 gold badge5 silver badges18 bronze badges

If you want to target multiple buttons and add a event listener to all you need to first target all buttons and after use loop for each button

const buttons = document.querySelectorAll(".btn");

buttons.forEach((button)=>{

button.addEventListener("click",()=>{
    console.log("clicked")
})

})

answered Apr 26 at 14:47

ankit jha's user avatar

<script src="main.js" defer></script>

which makes execute your code after the document fully loaded hence the javascript has complete reference

answered Oct 14, 2022 at 9:51

Marimuthu's user avatar

1

var skin1 = document.getElementsByClassName("skin_1");
skin1.addEventListener("click", function(){
        console.log("hi");
});


  • Вопрос задан

    более трёх лет назад

  • 2244 просмотра

Потому что skin1 в данном случаем возвращает массив.

Делайте так:

var skin1 = document.getElementsByClassName("skin_1");
for (var i=0 ; i<skin1.length; i++) {
  skin1[i].addEventListener("click", function(){
          console.log("hi");
  });
}

Вероятно потому, что getElementsByClassName возвращает список элементов, а не одиночный элемент?

Пригласить эксперта

Присоединюсь.
getElementsByClassName – возвращает коллекцию (массив).
Ознакомьтесь с пруфами 1, 2

Дополню.
Возможно addEventListener лучше не использовать, т.к. может повесится несколько обработчиков делающих одно и то же. Если заметите, что клик срабатывает несколько раз, перепишите на onclick

Мне помогла замена на такой код:

$(document).ready(function() {
    document.addEventListener( 'wpcf7submit', function( event ) {
        if ( '148' == event.detail.contactFormId ) { // Замените id на свою форму
            alert( "Опачки, меня пытаются отправить... в Магадан!" );
        }
    }, false );
});


  • Показать ещё
    Загружается…

18 мая 2023, в 23:42

1800 руб./за проект

18 мая 2023, в 22:57

500 руб./за проект

18 мая 2023, в 19:39

5000 руб./за проект

Минуточку внимания

Solution 1

getElementsByClassName returns an array of elements, addEventListener exists on elements.

The fix would be to iterate over the result set from getElementsByClassName and call addEventListener on each item:

var closeIcons=document.getElementsByClassName('.monique-close-icon');  

function closeBigImgAndContainer()
{
    MoniqueDiv.style.display= "none";
    currentBigImageToDisplay.style.display="none";
};

for (i = 0; i < closeIcons.length; i++) {
    closeIcons[i].addEventListener("click", closeBigImgAndContainer);
}

Solution 2

It looks like the closeIcon variable has undefined value.
It is because getElementsByClassName(..) method takes the class name as its parameter.

You can try to fix it as below:

var closeIcons = document.getElementsByClassName('monique-close-icon');
var i = closeIcons.length;
while (i--)
  closeIcons[i].addEventListener("click", closeBigImgAndContainer);

Also the method getElementsByClassName(..) returns a collection of nodes, not a single element. To assign an event listener we need to loop that collection and assign event to each DOM element in it.

Solution 3

Firstly, your selector is wrong. It should look like this:

var closeIcon = document.getElementsByClassName('monique-close-icon');  

Then you need to append the event handlers as if you were dealing with an Array, as the .getElementsByClassName() method returns a collection of elements.

var closeIcon = document.getElementsByClassName('monique-close-icon'); 
function closeBigImgAndContainer(e)
{
    MoniqueDiv.style.display= "none";
    currentBigImageToDisplay.style.display="none";
};

for (var i = 0; i < closeIcon.length; i++) {
   closeIcon[i].addEventListener('click', closeBigImgAndContainer); 
}

Here’s a working example:
http://jsfiddle.net/vhe17shd/

Comments

  • hi i am trying to close the divs using the close click..
    here is the code

    var closeIcon=document.getElementsByClassName('.monique-close-icon');  
    
        function closeBigImgAndContainer()
    {
        MoniqueDiv.style.display= "none";
        currentBigImageToDisplay.style.display="none";
    };
    
    closeIcon.addEventListener("click", closeBigImgAndContainer);
    

    But in console there is an error
    Uncaught TypeError: closeIcon.addEventListener is not a function(anonymous function) @ main.js:14
    Please tell me where i am doing it wrong…Thanks.

  • You’re right that the selector is wrong, but the issue is that you cannot call the addEventListener on a collection of elements.

  • In addition to your answer, the selector is also wrong.

  • @Syadani I added and id and it worked. Thanks.,

  • Technically it returns a collection, which is array-like.

  • What if he wanted to attach event handlers to all of the elements?

  • I believe he was attempting to add the same event listener to all the elements with one method, which is not possible, seeing as how the collection does not have a method with that name.

Recents

Related

Expected Behavior

I should be able to use window.addEventListener as normal.

Current Behavior

Chart.JS overrides window.addEventListener() with a completely different implementation with a different method signature!

Possible Solution

Wrap Chart.JS (and all sub-files!) in a SEAF (self-executing anonymous function) to avoid polluting the global scope.

Steps to Reproduce (for bugs)

An ‘live demo’ is not useful here. Instead, I can provide detailed steps to reproduce, and a link tot he commit in the source tree of my open-source project: https://github.com/ConnectedHumber/Air-Quality-Web/tree/4a9d67e2924edc511bca1b0530a3370a3b20af5d (note that there may be probably are additional commits after this, so if you git clone you’ll want to git checkout the exact commit).

  • I’m using rollup as my JS build system, with the ES6 module syntax.
  • I’m installing packages from NPM – including Chart.JS

I’ve got an index.mjs like this:

“use strict”;

import '../css/main.css';

import MyProjectClass from './MyProjectClass.mjs';

window.addEventListener("load", function(_event) {
	window.project = new MyProjectClass();
	window.map.setup();
});

…the Chart.JS import is buried in the application. It looks like this (in one of the sub-files):

import Chart from 'chart.js';

I get the following output from rollup on the command-line:

client_src/js/index.mjs → app/app.js...
(!) postcss plugin: The onwrite hook used by plugin postcss is deprecated. The generateBundle hook should be used instead.
(!) Circular dependency: node_modules/moment/src/lib/create/from-anything.js -> node_modules/moment/src/lib/create/valid.js -> node_modules/moment/src/lib/create/utc.js -> node_modules/moment/src/lib/create/from-anything.js
(!) Circular dependency: node_modules/moment/src/lib/units/month.js -> node_modules/moment/src/lib/moment/get-set.js -> node_modules/moment/src/lib/units/month.js
(!) Circular dependency: node_modules/moment/src/lib/moment/get-set.js -> node_modules/moment/src/lib/units/year.js -> node_modules/moment/src/lib/moment/get-set.js
(!) Circular dependency: node_modules/moment/src/lib/create/local.js -> node_modules/moment/src/lib/create/from-anything.js -> node_modules/moment/src/lib/locale/locales.js -> node_modules/moment/src/lib/locale/base-config.js -> node_modules/moment/src/lib/units/week.js -> node_modules/moment/src/lib/create/local.js
(!) Circular dependency: node_modules/moment/src/lib/create/local.js -> node_modules/moment/src/lib/create/from-anything.js -> node_modules/moment/src/lib/locale/locales.js -> node_modules/moment/src/lib/locale/base-config.js -> node_modules/moment/src/lib/units/week.js -> node_modules/moment/src/lib/units/week-calendar-utils.js -> node_modules/moment/src/lib/create/local.js
(!) Circular dependency: node_modules/moment/src/lib/create/from-string-and-format.js -> node_modules/moment/src/lib/create/from-string.js -> node_modules/moment/src/lib/create/from-string-and-format.js
(!) Circular dependency: node_modules/moment/src/lib/create/local.js -> node_modules/moment/src/lib/create/from-anything.js -> node_modules/moment/src/lib/create/from-string-and-array.js -> node_modules/moment/src/lib/create/from-string-and-format.js -> node_modules/moment/src/lib/create/from-string.js -> node_modules/moment/src/lib/create/from-array.js -> node_modules/moment/src/lib/create/local.js
(!) Circular dependency: node_modules/moment/src/lib/duration/constructor.js -> node_modules/moment/src/lib/duration/valid.js -> node_modules/moment/src/lib/duration/constructor.js
(!) Circular dependency: node_modules/moment/src/lib/duration/create.js -> node_modules/moment/src/lib/duration/constructor.js -> node_modules/moment/src/lib/duration/valid.js -> node_modules/moment/src/lib/duration/create.js
(!) Circular dependency: node_modules/moment/src/lib/duration/create.js -> node_modules/moment/src/lib/units/offset.js -> node_modules/moment/src/lib/duration/create.js
(!) Circular dependency: node_modules/moment/src/lib/moment/add-subtract.js -> node_modules/moment/src/lib/duration/create.js -> node_modules/moment/src/lib/units/offset.js -> node_modules/moment/src/lib/moment/add-subtract.js
created app/app.js in 2.5s

The error in the Firefox Developer Tools comes with a stack trace. Here it is:

TypeError: node.addEventListener is not a function[Learn More] platform.dom.js:127:1

    addEventListener platform.dom.js:127
    <anonymous> index.mjs:9 

…..that platform.dom.js is part of Chart.JS. As I have source maps enabled, it tells me where that file is located: http://[::1]:40482/node_modules/chart.js/src/platforms/platform.dom.js

Context

I’m using Rollup as my build system to create a dynamic map (with LeafletJS) of some data. Line graphs are a part of this – so, after a quick search of npm, I decided to bring in Chart.JS to do the heavy lifting with respect to displaying the graphs etc. Unfortunately, this had an adverse affect on the rest of my application because Chart.JS pollutes the global scope.

Environment

  • Chart.js version: 2.7.3
  • Browser name and version: Firefox 65.0 beta
  • Link to your project: https://github.com/ConnectedHumber/Air-Quality-Web/tree/4a9d67e2924edc511bca1b0530a3370a3b20af5d
  • Build system: Rollup

Did you run into the .addEventListener is not a function error? Well this is a very common mistake. The most common cause for this error is when the user attempts to use the .addEventListener function on an array of items, usually from using the .getElementsByClassName function. The .addEventListener function can only be used on a single element, therefore if you are attempting to use .addEventListener function on an array of items it will cause an error. Make sure that you change your item to have an index.

Example Error:

var someObject = document.getElementsByClassName("someClassName");

function showObject() {
    // function code
}

someObject.addEventListener('click', showObject, false);

someObject.addEventListener(‘click’, showObject, false);

The Solution:

someObject is a list of items because .getElementsByClassName returns a list of all the elements it finds with the class name that is passed to it. To fix this error, we need to give someObject an index like so:

Add the event listener to the first item in the array.

var someObject = document.getElementsByClassName("someClassName");

function showObject() {
    // function code
}

someObject[0].addEventListener('click', showObject, false);

Or you may add the even listener to all of the items in the array.

var someObject = document.getElementsByClassName("someClassName");

function showObject() {
    // function code
}

for (var i = 0 ; i < someObject.length; i++) {
   someObject[i].addEventListener('click' , showObject , false ) ; 
}

Hopefully this fixes the error you received, if this was not the reason you came across this error then please leave a comment with more details on your error and I will find a solution and add it here.

Добавить комментарий