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
3,7044 gold badges26 silver badges36 bronze badges
asked Aug 15, 2015 at 18:28
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 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);
}
answered Aug 15, 2015 at 18:30
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>
answered Dec 22, 2017 at 12:05
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
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
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 –
-
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 )
-
Use id for selecting that specific element.
Example-document.getElementById('button')
answered Oct 23, 2022 at 13:59
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
137k22 gold badges57 silver badges95 bronze badges
answered May 19, 2018 at 12:38
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
<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
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 codevar 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.