26

I'm trying to add a class to a div in pure JS once a link is clicked (In this case, the link has id #switchlogin). When I console.log my element, I am able to click through the object and see that it currently has two names in its classList. However, when I console.log element.classList, I receive an "undefined". I am unsure why I'm receiving undefined, and why I cannot add my new class name.

The issue is recreated here: https://jsfiddle.net/swf5zc74/

Here is a portion of my HTML:

   <div class="sign_in modal">

      <h1>Get Started!</h1>

      <form action="" method="get">

        <input type="text" name="fname" placeholder="Name" required>
        <input type="text" name="email" placeholder="Email" required>
        <input type="password" name="password" placeholder="Password" required>
        <input type="submit" value="Submit" class="submit">

      </form>

      <h3><a href="#" id="switchLogin">Been Here Before?</a></h3>
    </div>

My JS:

var body = document.getElementsByTagName('body'),
    signIn = document.getElementsByClassName('sign_in modal'),
    logIn = document.getElementsByClassName('log_in'),
    switchLogIn = document.getElementById('switchLogin'),
    switchSignIn = document.getElementById('switchSignin'),
    link = document.querySelector('a');

link.addEventListener("click", function(e){
    if ((e.target || e.srcElement).id == 'switchLogin'){
        console.log(signIn);
        console.log(signIn.classList);
        signIn.classList += ' slideOut';
    }else{
        console.log("nope");
    }
})
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Angelina Bethoney
  • 363
  • 1
  • 3
  • 4
  • If you're using `addEventListener()`, there's no reason for `(e.target || e.srcElement)`. Just use `e.target`. –  Oct 14 '15 at 18:20
  • Okay, awesome. I used e.srcElement because I read IE doesn't support e.target. Thanks for the tip – Angelina Bethoney Oct 14 '15 at 18:23
  • Does this answer your question? [document.getElementsByClassName().innerHTML always returns "undefined"](https://stackoverflow.com/questions/17896746/document-getelementsbyclassname-innerhtml-always-returns-undefined) – ggorlen Mar 14 '22 at 22:34
  • Not OP's problem, but I've wound up at this thread [trying to access `.classList` on a `element.nodeType === Node.TEXT_NODE`](https://stackoverflow.com/a/71474999/6243352) which is undefined. Beware! – ggorlen Mar 14 '22 at 22:46

2 Answers2

29

signIn is the result of document.getElementsByClassName('sign_in modal') - getElementsByClassName returns a collection - so you have to reference the index you want:

console.log(signIn[0].classList);

Demo: https://jsfiddle.net/swf5zc74/1/

tymeJV
  • 103,943
  • 14
  • 161
  • 157
  • Oh okay. But now when I try to add my new class using .push, I receive an error that says it's not a function ` var classes = signIn[0].classList; classes.push("slideOut");` Results in `Uncaught TypeError: classes.push is not a function(…)` ? – Angelina Bethoney Oct 14 '15 at 18:16
  • 1
    @AngelinaBethoney Read more on classList here: https://developer.mozilla.org/en-US/docs/Web/API/Element/classList – Steve Hansell Oct 14 '15 at 18:35
4

document.getElementsByClassName returns an "array-like" collection of elements, even if there is only one element with that class name. To access elements with document.getElementsByClassName, you can use array syntax.

for exampe logIn = document.getElementsByClassName('log_in')[0]

want to add a class to that element?

document.getElementsByClassName('log_in')[0].className += " foo";

Jake
  • 251
  • 4
  • 4