Reputation: 121
I have the HTML:
<div class="dropdown">
<button class="dropbtn">Game Design</button>
<div class="dropdown-content">
<a id="GameIdea" href="GameIdea.html">Link 1</a>
<a id="GameMechanics" href="GameMechanics.html">Link 2</a>
<a id="GameCharacters" href="GameCharacters.html">Link 3</a>
<a id="Inspiration" href="Inspiration.html">Link 3</a>
</div>
</div>
And the JavaScript:
var anchor = document.getElementById(pathShort); //e.g. pathShort == GameIdea
var anchorParent = anchor.parentNode;
var button = anchorParent.previousSibling;
button.classList.add("active");
The issue is this - I don't want the anchor element:document.getElementById(pathShort);
I want the button element, therefore as you can see I use anchor.parentNode;
to get the div
that the anchor is in, and then anchorParent.previousSibling;
to get the element beside the div
, before not after.
In my mind I thought this would work but in console I get the error Cannot read property 'add' of undefined
, therefore the variable button
must be effectively null
or empty
, meaning my method of DOM traversal prior to the 'add' call has not worked.
Upvotes: 1
Views: 165
Reputation: 872
The previousSibling
method was returning an empty text node (containing nothing but white space), which is not an element and does not have a classList
property. previousSibling
returns the previous node whether it is an element or not. You can change it to previousElementSibling
to get the button element, because it returns only the previous element, ignoring other types of nodes.
var pathShort = "GameIdea";
var anchor = document.getElementById(pathShort);
var anchorParent = anchor.parentNode;
var button = anchorParent.previousElementSibling;
button.classList.add("active");
<div class="dropdown">
<button class="dropbtn">Game Design</button>
<div class="dropdown-content">
<a id="GameIdea" href="GameIdea.html">Link 1</a>
<a id="GameMechanics" href="GameMechanics.html">Link 2</a>
<a id="GameCharacters" href="GameCharacters.html">Link 3</a>
<a id="Inspiration" href="Inspiration.html">Link 3</a>
</div>
</div>
Upvotes: 5
Reputation: 15442
Try this:
const pathShort = 'GameIdea';
const anchor = document.getElementById(pathShort);
const anchorParent = anchor.parentElement;
const button = anchorParent.previousElementSibling;
button.classList.add("active");
<div class="dropdown">
<button class="dropbtn">Game Design</button>
<div class="dropdown-content">
<a id="GameIdea" href="GameIdea.html">Link 1</a>
<a id="GameMechanics" href="GameMechanics.html">Link 2</a>
<a id="GameCharacters" href="GameCharacters.html">Link 3</a>
<a id="Inspiration" href="Inspiration.html">Link 3</a>
</div>
</div>
when you access HTML DOM node's properties like parentNode
or previousSibling
you will get also non HTML nodes like Text nodes, in your code each new line creates an empty Text node, thus you get it instead of desired element.
Upvotes: 0
Reputation: 114
You can use...
var button = document.querySelector(".dropbtn")
This will get the first element with the class dropbtn (The button element in this case).
If you're trying to add a class within the button element. I'd recommend you;
button.setAttribute("class", "dropbtn ANY-OTHER-CLASS")
Upvotes: 1