0

need some help here. I am using bootstrap CSS for designing my website.

This is my first code snippet:

<ul class="nav nav-pills nav-stacked border-right" id="clearFilter"   style="display:none">
<li class="text-uppercase bold-text" onclick="showChild(event)"><a href="#" class="li-head-color">Clear Filter<span class="glyphicon glyphicon-plus float-right" aria-hidden="true"></a></li>
</ul>

If I check the length of this ul element. It shows 3. Where are there is only 1 li inside the ul.

Then when I try to add a li to this ul using javascript, the length is increased by just 1.

This is the javascript code:

var ul = document.getElementById("clearFilter");
var li = document.createElement("li");
var anchor = document.createElement("a");   
var span = document.createElement("span");
span.setAttribute("class","glyphicon glyphicon-remove-circle float-right");
anchor.appendChild(document.createTextNode(str));
anchor.appendChild(span);
anchor.setAttribute("href","#");
li.appendChild(anchor);
li.setAttribute("onclick","removeFilter(event)");
li.setAttribute("style","display:none");
ul.appendChild(li);

So what might be the reason for this. I have 3 more such ul element in my code. The length of the ul is greater than the li elements actually present. What might be the reason for this? Am I doing something wrong here?

9
  • The clearFilter code is here: <ul class="nav nav-pills nav-stacked border-right" id="clearFilter" style="display:none"> <li class="text-uppercase bold-text" onclick="showChild(event)"><a href="#" class="li-head-color">Clear Filter<span class="glyphicon glyphicon-plus float-right" aria-hidden="true"></a></li> </ul> Commented Jul 30, 2015 at 18:56
  • I really don't know why the code appears to be a mess.. :P Commented Jul 30, 2015 at 19:00
  • 1
    edit the question and post your code there Commented Jul 30, 2015 at 19:04
  • Could not be your issue, but your <span> element has no closing tag Commented Jul 30, 2015 at 19:06
  • I'll suggest try build your code in jsfiddle, and include the link to your question. cause the question is somewhat confusing now (at least for me) Commented Jul 30, 2015 at 19:08

3 Answers 3

3

You're getting text nodes (text between <ul>,<li> and </ul>) along with <li> nodes.

If you're using childNodes property, use the code below to filter out text nodes from it, if needed (IE9+).

var children = ul.childNodes;
children = Array.prototype.slice.call(children).filter(function(element) { return element.nodeType == 1; });

See this jsFiddle for code and demonstration and this SO discussion for more information.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot...!! Perfectly what I was looking for. :)
1

I think your issue is that when you are getting the "length" of the <ul> element, the result returns the 3 children elements - the <li>, <a> and <span> elements.

The following JavaScript returns an array of length 1 - is this what you're after?

document.getElementById('clearFilter').getElementsByTagName('li').length;

Comments

1

Are you using childNodes or children?

Documentation for childNodes` return value:

A NodeList object, representing a collection of nodes. The nodes in the returned collection are sorted as they appear in the source code

Documentation for children return value:

A live HTMLCollection object, representing a collection of element nodes. The elements in the returned collection are sorted as they appear in the source code

To me this seems about as clear as mud. But just trying it out, children property ignores white space as "text nodes" while childNodes includes extra nodes when which space is found. This basically means that the difference, in your case, was that when you write code, you include white space which means that the DOM parser is creating extra text nodes. When you create the nodes in javascript, no whitespace is added.

Example illustrating my point that if there was NO white space, you are getting the same result whether you use the childNodes or children property.

function childLengthDemo(id){
  console.log(document.getElementById(id).children.length); // 1, 1
  console.log(document.getElementById(id).childNodes.length); // 1, 3
  
  var ul = document.getElementById(id);
  var li = document.createElement("li");
  var anchor = document.createElement("a");   
  var span = document.createElement("span");
  span.setAttribute("class","glyphicon glyphicon-remove-circle float-right");
  anchor.appendChild(document.createTextNode("Another Clear Filter")); // your variable, str, was undefined
  anchor.appendChild(span);
  anchor.setAttribute("href","#");
  li.appendChild(anchor);
  li.setAttribute("onclick","removeFilter(event)");
  li.setAttribute("style","display:none");
  ul.appendChild(li);
  
  console.log(document.getElementById(id).children.length); // 2, 2
  console.log(document.getElementById(id).childNodes.length); // 2, 4
}

childLengthDemo('clearFilter-nowhitespace'); // same for both children and childNodes property
childLengthDemo('clearFilter-whitespace'); // different for children and childNodes property
<ul class="nav nav-pills nav-stacked border-right" id="clearFilter-nowhitespace" style="display:none"><li class="text-uppercase bold-text" onclick="showChild(event)"><a href="#" class="li-head-color">Clear Filter<span class="glyphicon glyphicon-plus float-right" aria-hidden="true"></span></a></li></ul>

<ul class="nav nav-pills nav-stacked border-right" id="clearFilter-whitespace" style="display:none">
  <li class="text-uppercase bold-text" onclick="showChild(event)">
    <a href="#" class="li-head-color">
      Clear Filter
      <span class="glyphicon glyphicon-plus float-right" aria-hidden="true" style="display:none"></span>
    </a>
  </li>
</ul>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.