SitePoint Sponsor

User Tag List

Results 1 to 8 of 8

Hybrid View

  1. #1
    SitePoint Addict
    Join Date
    Aug 2005
    Posts
    254
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Using JS to apply classes to list items

    Hi I want to use JS to apply a class to the last list element in a list with a class list-items. I cobbled together something but I can't get it to work


    Code:
    function removeUnderline () {
    	
    	  // get all ul elements
              var List = document.getElementsByTagName("ul");	
    	   
             // if element has a class list-links
             if (List.className == "list-links") {		
    	         
                     // loop through list items
                     for (i=0; i<List.childNodes.length; i++) {
    				 
                               // for the last list item give it a class of no-underline
                               if (List.lastChild) {					  
                                       List.lastChild.className= "no-underline";			 
    				 }			 
    		}	
    		
    	}	
    }
    any ideas?

    Steven

  2. #2
    SitePoint Guru Ize's Avatar
    Join Date
    Nov 2005
    Location
    The Netherlands
    Posts
    808
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Take note that document.getElementsByTagName returns an array of elements, not a single element. Therefore, you cannot check for a className on that collection.

    You have to either figure out at what position in the collection your list exists, or target the list by id:

    Code JavaScript:
    var List = document.getElementsByTagName('ul')[0];
    // or...
    var List = document.getElementById('myList');

    Furthermore, there's no need to loop through its childNodes, because you know exactly which childnode you want to manipulate:

    Code JavaScript:
    function removeUnderline () {
              var List = document.getElementsByTagName("ul")[0];	
     
             // if element has a class list-links
             if (List.className == "list-links") {		
         	 // for the last list item give it a class of no-underline
                  if (List.lastChild) {					  
                    List.lastChild.className= "no-underline";			
    	      }
    	}	
    }

  3. #3
    CSS & JS/DOM Adept bronze trophy
    Join Date
    Mar 2005
    Location
    USA
    Posts
    5,482
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, it doesn't work because it doesn't make sense.

    document.getElementsByTagName() returns a NodeList (acts like an Array), so you need to loop through it.

    lastChild is a reference to the last child node of the element. The last node might be a text node, comment node, or an element node.

    Another issue is that an element can belong to more than one class.

    Try this.
    Code:
    function removeUnderline () {
    
      // get all ul elements
      var item,Lists = document.getElementsByTagName("ul");
      for(var i=0; i<Lists.length; i++) {
        if(hasClassName(Lists[i], "list-links")) {
          // for the last list item give it a class of no-underline         
          item = Lists[i].lastChild;
          while((item.nodeType != 1) && item.previousSibling) {
            item = item.previousSibling;
          }
          if(item.nodeName.toLowerCase() == 'li') {
            addClassName(item,"no-underline");
          }
        }
      }  
    }
    function hasClassName(el,c){
      c=c.replace(/\-/g,'\\-');
      return (new RegExp('(^|\\s)'+c+'(\\s|$)')).test(el.className);
    }
    function addClassName(el,c){
      if(hasClassName(el,c)) return;
      var curClass=el.className;
      el.className=curClass+((curClass.length>0)?' ':'')+c;
    }
    function removeClassName(el,c){
      var re=new RegExp(c.replace(/\-/g,'\\-')+'\\s*');
      el.className=el.className.replace(re,'').replace(/^\s*|\s*$/g,'');
    }
    We miss you, Dan Schulz.
    Learn CSS. | X/HTML Validator | CSS validator
    Dynamic Site Solutions
    Code for Firefox, Chrome, Safari, & Opera, then add fixes for IE, not vice versa.

  4. #4
    SitePoint Addict
    Join Date
    Aug 2005
    Posts
    254
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Brilliant, thanks for this - it works great in IE, FF and Safari


    Steven

  5. #5
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It might be interesting for you to see what this would look like with Prototype framework:
    Code:
    $$('ul.list-links').each(function(e) {
    	e.immediateDescendants().last().addClassName("no-underline");
    })
    Looks a bit simpler, IMO

  6. #6
    SitePoint Guru
    Join Date
    Mar 2004
    Location
    Earth
    Posts
    406
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Simpler yes, if you don't mind a glut of external dependency just to perform a simple task

  7. #7
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    My point was to show OP that his wheel is already invented.

  8. #8
    SitePoint Guru
    Join Date
    Mar 2004
    Location
    Earth
    Posts
    406
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Assuming that all he wanted was a functional wheel - maybe he'd like to learn how to make wheels himself, and who knows, maybe make a better wheel


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •