SitePoint Sponsor

User Tag List

Results 1 to 6 of 6
  1. #1
    SitePoint Member
    Join Date
    Jul 2007
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Simply JavaScript - Question on hasClass

    I am trying to work some of the illustrated examples to get a better feel on how they function. Presently I am having trouble with a portion of the hasClass from page 88.

    I retyped the code to be a simple function:

    function has(target, theClass) {
    alert(target.className);

    var pattern = new RegExp("(^| )" + theClass + "( |$)");

    if (pattern.test(target.className)) {
    return true;
    }

    return false;
    }

    then in a html doc I have this:

    <body onload='has("h3", "red");'>

    <p class="red">I should be white background black text</p>
    <h7>no class</h7>
    <h3 class="red">Some class</h3>


    </body>
    </html>

    If I understand correctly I thought target.className would get the class name of the element passed to it, thus I expected to have the function return True, but I consistently get False. I got False whether I put in an element with the class or without it. I then put the alert(target.className) in to see what the value was showing has and I get "Undefined". So presently I am not sure if I am doing something incorrect or it maybe that I don't have a proper understanding of className. Any help would be appreciated.
    Thank you.

  2. #2
    SitePoint Evangelist
    Join Date
    Jul 2007
    Posts
    345
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think you are confusing tag names for element references.

    You have 'has("h3", "red")' but "h3" is not the variable name of a reference to an element. "h3" is the type of element but not a particular element.

    <h3 class="red" id="myH3">Find Me</h3>

    First create a reference to the element you want:

    var el = document.getElementById("myH3");

    Now, use your function to check its class:

    alert(has(el, "red")); // should give true

    (Also, I don't think <h7> elements exist.)

  3. #3
    SitePoint Member
    Join Date
    Jul 2007
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I see my mistake must be due to me misunderstanding... I will have to reread the chapter. I think I must have missed something, because it confuses me why a classname function would require an id.

    <h3 class="red" id="myH3">Find Me</h3>

    It seems that usually I would have either a class or an id, not both.

    Thank you for your help...I think I must have missed something in my reading.

    Also:
    (Also, I don't think <h7> elements exist.)
    Your right...that was a mistake on my part and not due to anything from the book. Thanks again.

  4. #4
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Yes, <h7> doesn't exist, it only goes up to 6.

    And it doesn't have to be an ID. It could be any way of walking the DOM. Suppose you have this HTML:
    HTML Code:
    <div id="item">
      <p>Some text here</p>
      <p>This is a block of text with a <a href="http://example.com" class="external">link</a> in it</p>
    </div>
    And you want to check if the link in the second P has the class external.
    Code Javascript:
    var a = document.getElementById('item').getElementsByTagName('p')[1].getElementsByTagName('a')[0];
    var h = has(a, 'external');
    alert(h); // will alert true
    Another route:
    Code Javascript:
    var d = document.getElementById('item');
    var p1 = d.getElementsByTagName('p');
    var a = p1.nextSibling.nextSibling.getElementsByTagName('a')[0];
    var h = has(a, 'external');
    alert(h); // will alert true

  5. #5
    SitePoint Member
    Join Date
    Jul 2007
    Posts
    4
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks Raffles...the further explaination made me realize how my thinking was wrong. In some murky thought I wanted to somehow go thru the dom tree and gather all the nodes with the class specified. By pointing out the various ways to walk the DOM it made me realize I had to collect all the element nodes into an array then test them to get the results I was imagining.

    So with help from the code in the book I rewrote the function to:

    function has(theClass) {
    var elementArray = [];

    if (document.all) {
    elementArray = document.all;
    }
    else {
    elementArray = document.getElementsByTagName("*");
    }

    var matchedArray = [];
    var pattern = new RegExp("(^| )" + theClass + "( |$)");

    for (var i = 0; i < elementArray.length; i++) {
    if (pattern.test(elementArray[i].className)) {
    matchedArray[matchedArray.length] = elementArray[i];
    }
    }

    for (var i = 0; i < matchedArray.length; i++) {
    alert(matchedArray[i].nodeName + " " + matchedArray[i].firstChild.nodeValue);
    }

    }

    Then in my html:

    <body onload=has("red");>

    <p class="red">I should be white background black text</p>
    <h6>no class</h6>
    <h3 class="red">Some class</h3>

    </body>
    </html>

    Thus I now get the results I was looking for.
    Thanks to both you and r51!

  6. #6
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    In the future, please use code blocks, preferably with the appropriate syntax highlighting. As you can no doubt see, it makes reading the code a hell of a lot easier.

    In your code, there is no point checking for document.all. If you need to use document.all, then you're catering for browsers that practically don't support CSS and for pages that most likely do not use CSS either, and also probably don't use the class attribute either. Ditch it.

    Incidentally, here's my throw at a hasClass function, along with a getElementsByClassName that returns the actual elements with that class name:
    Code Javascript:
    function getElementsByClassName(c) {
        var children = document.getElementsByTagName('*');
        var els = [];
        for (var i = 0, j = children.length; i < j; i++) if (hasClass(children[i], c)) els.push(children[i]);
        return els;
    }
    function hasClass(el, c) {
      var has = false;
      if (!el || !el.className.length) return;
      var bits = el.className.split(' ');
      for (var j = 0; j < bits.length; j++) if (bits[j] === c) has = true;
      return has;
    }


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
  •