Reputation: 333
Im struggling to figure out why my code is not working. Here is part of the JS:
function init() {
var showMenu = document.getElementsByClassName('showMenu'),
perspectiveWrapper = document.getElementById( 'perspective' ),
container = perspectiveWrapper.querySelector( '.container' ),
contentWrapper = container.querySelector( '.wrapper' );
showMenu.addEventListener( clickevent, function( ev ) {
ev.stopPropagation();
ev.preventDefault();
docscroll = scrollY();
// change top of contentWrapper
contentWrapper.style.top = docscroll * -1 + 'px';
// mac chrome issue:
document.body.scrollTop = document.documentElement.scrollTop = 0;
// add modalview class
classie.add( perspectiveWrapper, 'modalview' );
// animate..
setTimeout( function() { classie.add( perspectiveWrapper, 'animate' ); }, 25 );
});
}
Here is part of the HTML:
<div id="topBar">
<h1>Company</h1>
<a href="#" class="entypo-menu showMenu"></a>
</div>
<div class="line"></div>
<div id="fixedBar">
<h1>Company</h1>
<a href="#" class="entypo-menu showMenu"></a>
</div>
For some reason when I load the page, I get this error:
TypeError: undefined is not a function (evaluating 'showMenu.addEventListener')
I don't understand this because if I change this line:
var showMenu = document.getElementsByClassName('showMenu'),
to:
var showMenu = document.getElementById( 'showMenu' ),
It does work!
Why won't the class selector work but the id one will? I'm trying to get both links with the class showMenu
to perform the JS.
Upvotes: 4
Views: 9843
Reputation: 10489
document.getElementsByClassName
returns an array-like list (an HTMLCollection
, to be exact) of all elements that match the class name. You probably care about the first element, so try using the following instead:
var showMenu = document.getElementsByClassName( 'showMenu' )[0],
If you care about all of the elements, you'll need to loop through the elements:
var showMenu = document.getElementsByClassName( 'showMenu' ),
// ...
for ( var i = 0; i < showMenu.length; ++i ) {
showMenu[i].addEventListener( clickevt, function( ev ) {
// Your code here
});
}
Upvotes: 5
Reputation: 240938
It's because getElementsByClassName
return an array-like object of DOM elements.
You need to access each element and attach the event listener individually:
for (var i = 0; i < showmenu.length; i++ ) {
showMenu[i].addEventListener( clickevent, function( ev ) {
// ...
});
}
..or:
Array.prototype.forEach.call(showMenu, function(el, i) {
el.addEventListener( clickevent, function( ev ) {
// ...
});
});
Upvotes: 2
Reputation: 2175
That's because document.getElementsByClassName()
returns a node list, which is similar to an array.
So if you have multiple elements you wish to target, you'll have to loop through them with a for loop or .forEach()
but if you're only looking for the nth element with this class then you can specify it's index with bracket notation:
var showMenu = document.getElementsByClassName('showMenu')[0],
Upvotes: 3