5

I am following a book to learn JavaScript, and it appears to have coding errors as what I am following does not appear to work. Here's what I have:

HTML:

<!DOCTYPE html>
<html>
<head>
    <title>Examples of moving around in the DOM using native JavaScript methods</title>
    <meta charset="UTF-8">

    <!-- CSS Stylesheet -->
    <link rel="stylesheet" href="css/show.css">
</head>
<body>

<!-- Let's get the parent element for the target node and add a class of "active" to it -->
<ul id="nav">
    <li><a href="/" id="home">Home</a></li>
    <li><a href="/about" id="about">About Us</a></li>
    <li><a href="/contact" id="contact">Contact Us</a></li>
</ul>
<input type="button" onclick="targetClass()" value="Target the Class"/>
<input type="button" onclick="prevNextSibling()" value="Target Next and Previous Sibling"/>

<script src="js/js.js"></script>
</body>
</html>

JavaScript:

// This block of JavaScript obtains the parent element
// target the "about" link and apply a class to its parent list item
function targetClass()
{
    document.getElementById("about").parentNode.setAttribute("class", "active");
}
// This block of code adds a Class to Previous and Next Sibling Nodes
function prevNextSibling()
{
    // get "about" parent, then its previous sibling and apply a class
    document.getElementById("about").parentNode.previousSibling.setAttribute("class", "previous");
    // get "about" parent, then its next sibling and apply a class
    document.getElementById("about").parentNode.nextSibling.setAttribute("class", "next");
}

As per the book the output of the generated HTML I should be getting is:

<ul id="nav">
<li class=" previous" ><a href="/" id="home">Home</a></li>
<li class=" active" ><a href="/about" id="about">About Us</a></li>
<li class=" next" ><a href="/contact" id="contact">Contact Us</a></li>
</ul>

But when I click on my text boxes nothing is happening.

How can I fix this problem?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JackSparrow123
  • 1,360
  • 2
  • 18
  • 23

2 Answers2

9

Some browsers insert white spaces in between DOM elements
Read the Notes section in the following link
https://developer.mozilla.org/en-US/docs/Web/API/Node.nextSibling

The solution is to use prevElementSibling and nextElementSibling. This selects the next sibling which is of the same type

This Works: http://jsfiddle.net/E2k6t/1/

function targetClass()
{
   document.getElementById("about").parentNode.setAttribute("class", "active");
}
function prevNextSibling()
{
  document.getElementById("about").parentNode.previousElementSibling.setAttribute("class", "previous");
  document.getElementById("about").parentNode.nextElementSibling.setAttribute("class", "next");
}

Note

It's not recommended to use inline javascript in your HTML code (onclick="targetClass()") while you are doing actual development - Discussions here and here. Use Event Listeners

Community
  • 1
  • 1
kaushikb9
  • 231
  • 2
  • 6
  • Hi Thanks But the textbook I am following mentions the usage of previousSibling and nextSibling only. Why can't this continue to be used instead? Even with previousElementSibling I am not seeing any change in the html code when observing from an actual html browser and not via jsfiddle. Is this expected? – JackSparrow123 Dec 25 '13 at 08:09
  • Actually I've added the CSS code as well and it does highlight on the local browsers as well, however still am curious as to why previousSibling and nextSibling do not work. I mean - why would the author of the book prescribe it in the first place if it did not work in the example given..? – JackSparrow123 Dec 25 '13 at 08:19
0

If you examine the DOM with an inspector, you will see there are empty text nodes between the li elements. To work around this:

// get "about" parent, then its previous sibling and apply a class
document.getElementById("about").parentNode.previousSibling.previousSibling.setAttribute("class", "previous");

// get "about" parent, then its next sibling and apply a class
document.getElementById("about").parentNode.nextSibling.nextSibling.setAttribute("class", "next");

Update: Actually, I only saw the empty text nodes using IE tools, not FF or Chrome.

Here's how they look in IE developer tools:

enter image description here

Steve Wellens
  • 20,506
  • 2
  • 28
  • 69