SitePoint Sponsor

User Tag List

Results 1 to 22 of 22
  1. #1
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,278
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)

    hide/show, looking for Good Tuts

    Hallo all,
    I'm picking my way through what should be a simple hide/show page, except I found myself writing a bazillion for loops and then having trouble accessing the right groupsOfThingies...

    I have an HTML structure like so
    Code:
    <div id="beschrijflinks">
      <h2>Main header</h2>
        <div> <--I might not need this element-->
          <h3>Sub Header OVERALL</h3>
          <ul>A nameless list</ul>
          <h3>Sub Header</h3>
          <ul>A nameless list</ul>
    etc...
        </div>
    
      <h2>Main Header</h2>
        <div>
          <h3>Sub Header OVERALL</h3>
          <ul>A nameless list</ul>
          <h3>Sub Header</h3>
          <ul>A nameless list</ul>
    ..etc
        </div>  
    
      <h2>Main Header</h2>
        <div>
          <h3>Sub Header OVERALL</h3>
          <ul>A nameless list</ul>
          <h3>Sub Header</h3>
          <ul>A nameless list</ul>
    ...etc
        </div>
    </div>
    This is how I'd write that HTML as a static page, so that's what I'm starting with. This is not a pure <ul> setup like I found at Dynamic Drive.

    Now the guy managing the site wants only the h2 Main Headers to be seen on the page by default, and that when people click one of them, the h3 Sub Headers who come after them appear. So clicking on the first h2 should make the h3's inside the div that follows that h2 appear, but none of the others.

    If the users then click on the FIRST h3 Sub Header (called "overall"), everything else appears (the lists underneath ALL the h3 Sub Headers in that section). For this reason I added a nameless div to wrap all h3's who come after each h2, thinking that might be a way to separate the groupsOfThingies.

    Otherwise, if any of the other h3 Sub Headers are clicked, only the list that sits under them appears.

    I've decided to have everyone be on the page by default, and onLoad a class of "verberg" (hidden) is added dynamically to those who need to hide. This positions them absolutely and pulls them offscreen, meaning they are accessible to screen readers and Lynx users.

    The h2 Main Headers and the h3 Sub Headers are also given child anchors inside so keyboarders will be able to use onclick (but maybe a better event should be used?).

    However when trying to do all of this, I end up with a bunch of loops looping through getElementByTagNames, and going through teh Googles I find these are kinda like arrays but not really. Ok. So I found nodeList.nextNode but that's not quite what I need to do.

    I don't know how to say, when the "a" inside x is clicked, then the bunch-of-elements who come directly afterwards in the source get Stuff Done To Them. Instead, when I gave it a try, I got
    clicking on any h2 makes just the last set of h3's appear.

    I'm pretty sure I'm writing myself into a hole with all these nested for loops, but I'm not sure how to give names to these nodeLists without looping (I need to be able to reference them somehow and I thought, since the first h3 of the group always does something extra special, that it would be useful somewhere to be able to reference it like h3[0] or something), and I'm not sure how to do something like nextSibling (not nextNode) with these things.

    So, I'm looking for any online tutorials (written in this century cause I find plenty of one integrated into the HTML with LANGUAGE=JAVASCRIPT and a href="javascript(void)") that show how to reference groups of thingies who come after or in between other groups of thingies in source.

    I have been bouncing around https://developer.mozilla.org/en/DOM/ and trying to make sure I ignore all the gecko-specific stuff and flipping through the Javascript Anthology but I'm missing something important and not getting in the right area. Every time I try to start from the beginning and try to understand the basics, the manager of this site keeps asking me when the page will be finished. ARG. It'll be finished when I know what the heck I'm doing!! Which right now looks like next year!

    The half-assed code I have currently (directly in the HTML for now):
    Code:
        <script type="text/javascript">
        function addClass(target, classValue) {
            var pattern = new RegExp("(^| )" + classValue + "( |$)");
            if (!pattern.test(target.className)) {
                if (target.className == "") {
                    target.className = classValue;
                }
                else {
                    target.className =+ " " + classValue;
                }
            }
            return true;
        }
    
        function removeClass(target, classValue) {
            var removedClass = target.className;
            var pattern = new RegExp("(^| )" + classValue  + "( |$)");
            removedClass = removedClass.replace(pattern, "$1");
            removedClass = removedClass.replace(/ $/, "");
    
            target.className = removedClass;
    
            return true;
        }
    
        function createAnchor(text, href) {
            var anchor = document.createElement("a");
            anchor.appendChild(document.createTextNode(text));
            anchor.href = "#" + href;
            return anchor;
        }
    
    //MY CODE
            var parent = document.getElementById("beschrijflinks"),
                h2 = parent.getElementsByTagName("h2"),
                div = parent.getElementsByTagName("div");
            var h2Length = h2.length;
            var divLength = div.length;
            for (var i=0; i < h2Length; i++) {
                var a = createAnchor("+", "foo");
                h2[i].appendChild(a);
            }
            for (var j=0; j < divLength; j++) {
                var h3 = div[j].getElementsByTagName("h3");
                var h3Length = h3.length;
                for (var k=0; k < h3Length; k++) {
                    var a = createAnchor("+", "foo");
                    h3[k].appendChild(a);
                    h3[k].setAttribute("class", "verberg");
                }
                var lijst = div[j].getElementsByTagName("ul");
                var lijstLength = lijst.length;
                for (var l=0; l < lijstLength; l++) {
                    lijst[l].setAttribute("class", "verberg");  
                }
            }
        </script>
    The add and removeClass thingie are for when I can figure out how to just toggle the classes on and off. The class is already described in the CSS, it just needs to be dynamically added and removed when users Do Stuff. I don't have the onclick in there because it was failing horribly. Because everything gets defined inside those for loops my onclick stuff was ending up horribly nested inside just to access the variables I've made, and then nothing seems to work with nextSibling (h2.nextSibling isn't equaling the div, and I can't manually say div[0] div[1] div[2] etc but I think this is the direction I need to go to).

    I need a good kick in the head. I need to know where to search for how to do this.

  2. #2
    SitePoint Addict
    Join Date
    Apr 2007
    Posts
    300
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This can be done with using a js framework jQuery being my choice.

    When DOM is loaded you could measure the height of the div's that follow h2 and save them and then collapse the div to height 0. Then when the user clicks on h2 get the index which should help identify the following div and then animate it to height of child element h3. When the user clicks on h3 animate the height of the div to the height that was previously saved. Hope this helps.

  3. #3
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,278
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)
    Thanks for the response.

    Using a framework would pretty much completely negate the point (not mentioned above) of me learning JS while doing this. I might as well then just pay someone to write all this for me : )

    I really really really want to avoid animations. Unless they are smaller and quicker to run than simply swapping classes. Ultimately this is a simple toggle:
    something.onclick = function(toggle) {
    if (there's a class on the target) {
    remove it;
    }
    else {
    add it;
    }
    }
    except not, lawlz. I can haz a big problem in still not quite understanding syntax no matter how much I read it and do little exercises. Guess I'll only learn by doing, which is what I'm trying to do here (except with someone breathing down my neck at the same time).

    Most of the hide/shows I see play directly with element.style.display == "none" or "block" but I'd like to learn to make JS work with CSS as supposedly good JS does not directly change element styles, in the separation of CSS and JS.

  4. #4
    rajug.replace('Raju Gautam'); bronze trophy Raju Gautam's Avatar
    Join Date
    Oct 2006
    Location
    Kathmandu, Nepal
    Posts
    4,013
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don't know whether I understood your problem or not from your long descriptions above but I hope the following demostration to change the class of a DIV will help you to the right direction.
    Code html4strict:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
        <link rel="stylesheet" href="css/default.css" />
        <title>Test</title>
        <style type="text/css">
        .show{
        	display: block;
        }
        .hide{
        	display: none;
        }
        </style>
        <script type="text/javascript">
        function showHide(){
        	var ele = document.getElementById('divTest');
        	if(ele.className == 'show'){
        		ele.className = 'hide';
        	}
        	else{
        		ele.className = 'show';
        	}
        }
        </script>
    </head>
    <body>
    <div class="show" id="divTest">test</div>
    <a href="#" onclick="showHide();">click me</a>
    </body>
    </html>
    Mistakes are proof that you are trying.....
    ------------------------------------------------------------------------
    PSD to HTML - SlicingArt.com | Personal Blog | ZCE - PHP 5

  5. #5
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,278
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)
    Hi rageh,

    While it's not the main example I'm looking for (being able to state which of a nodeList have a change), it's the first toggle I've seen that dealt with changing classes that wasn't Dustin Diaz-level (which at this point I can't even read) so it's very good for my education. I thought in order to read className I had to first getAttribute, and one of my books mentions IE being different but didn't give an example exactly of where they were different (and without an example I have trouble).

    Supposing I have a list of h2's, and a list of h3's, and a list of ul's. They always come in groups:
    h2 <-- call this the first h2
    h3 <-- call this the "Everything" header
    ul
    h3, ul
    h3, ul
    h3, ul

    h2 <--this is the second h2
    h3 <-- "Everything" header
    ul
    h3, ul
    ...

    I'm using getElementsByTagName to get nodeLists of h2's, h3's, and lists. I'm having a problem saying something like
    "if I click on the First h2, how to I say ONLY change the class on the h3's who come afterwards"
    right now, I'm managing to make always the Last group of h3's to get the change in class, but not the group who directly follow that clicked-on h2 (or the anchor within the h2 actually).

  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)
    The problem with getAttribute is that IE7 and below don't support getAttribute or setAttribute properly (they fail with the class attribute and some others I think). This is why className is used instead.

    Code:
    var fooclass = foo.getAttribute('class');
    var fooclass = foo.className;
    For your setup, which seems pretty unique, I would build an object like so:
    Code javascript:
    var h2s = {}, h2els = document.getElementsByTagName('h2'), h2i;
    for (var i = 0, j = h2els.length; i < j; i++) {
      h2i = h2s['h2_'+i] = {};
      h2i.head = h2els[i];
      h2i.h3s = h2els[i].nextSibling.nextSibling.getElementsByTagName('h3'); // you have to be confident about the HTML structure here!
      h2i.head.onclick = function() {
        for (var k = 0, l = h2i.h3s.length; k < l; k++) {
          h3i = h2i.h3s[k];
          toggleClass(h3i, 'show');
        }
      }
    }
    You'll need a toggleClass function that adds the specified className if it's absent, or removes it if it's present. This'll mean you'll need a hasClass function too.

    The object would look a bit like this:
    Code javascript:
    var h2s = {
      h2_0 : {
        'head': (reference to the H2 itself),
        'h3s': (nodelist of H3s below this H2)
      },
      h2_1: {
        'head': (reference to the H2 itself),
        'h3s': (nodelist of H3s below this H2)
      }
      // etc.
    }
    It could be easier than this by just assuming that the first div is related to the first h2, but this makes it a little more robust I think.

    It is h2.nextSibling.nextSibling that targets the DIV because there is also a textNode of whitespace between them that counts as a sibling. A major PITA most of the time. Things like jQuery dispense with having to think about this sort of thing, which is why I think people that go from jQuery to pure JavaScript would not really feel very comfortable.

    So, from what I did up there, you should be able to now attach onclick events to the H3 elements in each h2i.h3s nodelist. The event handler should check whether the h3 in question is the first one in the list or not, and do its stuff accordingly.

    Note that, in the loop, h2i is just a temporary reference to the current iteration of the h2els.

    And BTW, don't use "parent" for the variable name, as in the global scope "parent" is the same as window.parent, which can be a reference to either an actual parent window if the document is loaded in an iframe or as part of a frameset, or otherwise just the window (same as window.self).

  7. #7
    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)
    Oops, I missed the bit where you were actually asking for the toggle function.
    Code javascript:
    function toggleClass(el, cls) {
      if (hasClass(el, cls)) removeClass(el, cls);
      else addClass(el, cls);
    }
    Pretty easy, now all you need is the hasClass function, which is actually a part of the addClass function already (so you can abstract it from there anyway).

    Always useful to have hasClass along with the others.

  8. #8
    padawan silver trophybronze trophy markbrown4's Avatar
    Join Date
    Jul 2006
    Location
    Victoria, Australia
    Posts
    4,108
    Mentioned
    28 Post(s)
    Tagged
    2 Thread(s)
    Quote Originally Posted by Stomme poes View Post
    Using a framework would pretty much completely negate the point (not mentioned above) of me learning JS while doing this. I might as well then just pay someone to write all this for me
    I disagree. Learning jQuery isn't an escape - It's just making it easier to do all the common things with js. jQuery is still javascript and you will still need to know about things like strings, dom, events, loops etc.. I agree that there's value in learning first without a library - Simply Javascript is an excellent book for this - even though at the end of the book - you pretty much end up writing the basics of a js library anyways. You should never be expected to start from scratch every time.

    The code would look something like..
    Code:
    $('#beschrijflinks h2').click(function() {
      $(this).next().toggle();
    })
    Unless you're wanting to re-invent the wheel for a learning experience why not make use of all the tools at your disposal?

  9. #9
    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)
    I disagree, Mark. I think it's very valuable to learn proper javascript first, but only if you are going to actually work with javascript in the future and if you have a vested interest in it. If you're just making a website for your little carpentry enterprise and you have no further interest in the language, then jQuery is for you. If you're a web developer like Stomme Poes, then is seems sensible.

    A DOM element object is very different to an object that's been created with $(). The latter doesn't have properties/methods like nodeName or hasChildNodes(). While jQuery has most of the equivalents, you can't mix and match, and that's a distinction that's important when you try to do things that jQuery isn't able to do.

    jQuery makes this exercise of Stomme Poes' so much easier, but it's a great way to practice learning how to do things with JavaScript and the DOM. There is no way jQuery is "the end" for real JS.

  10. #10
    padawan silver trophybronze trophy markbrown4's Avatar
    Join Date
    Jul 2006
    Location
    Victoria, Australia
    Posts
    4,108
    Mentioned
    28 Post(s)
    Tagged
    2 Thread(s)
    My point is, if I have one.. everyone uses a framework. You are suggesting to roll your own so you understand exactly how it works. I'm not disagreeing that it would be beneficial to learning the language - without a doubt it would.

    But, even while using jQuery you still need to learn all the basics of Javascript and the important concepts like DOM, loops, objects etc..
    Sure, you may not easily be able to see at first which things are native and which things are added by jQuery, I think you'll pick that up with time.

    For me, I know I will never go back to back to writing DOM manipulation like above with native javascript - it's just far too long winded and a simple thing like getting the class attribute needs to cater for browser differences. I believe it's appropriate to ask the question 'Why learn something you will never need to use?'
    Javascript is also being developed to have a lot of the things that libraries like jQuery have introduced - like getting elements by css selector.
    If you're just making a website for your little carpentry enterprise and you have no further interest in the language, then jQuery is for you. If you're a web developer like Stomme Poes, then is seems sensible.
    This sounds pretty elitist to me. I know many very experience javascript developers who praise jQuery and use it heavily.
    A DOM element object is very different to an object that's been created with $(). The latter doesn't have properties/methods like nodeName or hasChildNodes(). While jQuery has most of the equivalents, you can't mix and match, and that's a distinction that's important when you try to do things that jQuery isn't able to do.
    You're right, however any jQuery object has a context property which is the DOM element before jQuery was added - so you can mix and match.
    There is no way jQuery is "the end" for real JS.
    I completely agree - I'm not saying learn jQuery syntax and stop learning.

    After doing an example like the above it would be beneficial to accomplish the same thing using a js framework so you can appreciate exactly what jQuery is and why people love it.
    You seem to be proposing that jQuery exists for people who can't write real javascript - I wholeheartedly disagree if that's your position.

  11. #11
    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)
    This sounds pretty elitist to me. I know many very experience javascript developers who praise jQuery and use it heavily.
    Yes, jQuery is pretty great. It provides absolutely brilliant shortcuts - they couldn't be shorter.

    Elitism is not my position at all. All I'm saying is that, for a web developer, it is worthwhile learning the actual language as well as using a framework. For someone who has no vested interest in the process for creating a website, it is not useful to learn vanilla javascript, and just using jQuery is OK.

  12. #12
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,278
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)
    If I knew jQuery, I wouldn't know Prototype. If I knew jQuery and Prototype, then I wouldn't know MooTools. If I know Javascript, it doesn't matter.

    Raffles, I'm slowly trying to read your code but in the meantime (with my husband also trying to help me) I'd ended up with a hasClass function already (yay) though I was trying to get it to work (without needless repetition) with the addClass and removeClass from the Javascript Anthology. Specifically they both made a new RegExp() which checked for the className and I figured if I'm not using addClass and removeClass alone (and no, I couldn't get the suckers to work as-is unless I first setAttribute("class", "hide") somewhere first, is that right?) then the hasClass could have the regex, name whatever's matched to some variable and have addclass/removeclass used in the toggle to just check if the strings are absolutely the same (since, they should be, I'm only using the same class).

    Quote Originally Posted by Raffles
    For your setup, which seems pretty unique, I would build an object like so:
    I didn't think it was all that unique, except that I didn't build this entirely in one big list. I've seen a lot of examples of the same behaviour I want, except they were all basically like a dropdown menu except here they were expanding/collapsing.

    However my code semantically made way more sense with headers and lists, instead of one big list. Maybe for learning How To Do An Expansion List I should use a list, but this is also work (I'm trying to learn on the job) so I want to use the right markup.

    Building objects is way beyond where I'm at right now. I can't read anything on Dustin's page (though I did steal his toggle which was a lot like rageh's). It kinda sucks that I need to learn while doing but the stuff I need to do is running while I'm crawling.

    The problem with getAttribute is that IE7 and below don't support getAttribute or setAttribute properly (they fail with the class attribute and some others I think). This is why className is used instead.
    I thought this was still present in IE8 too?
    So anyway, is the point that I can always use element.className for all browsers? The same part of the book that warned me about class also warned about label.for and label.htmlfor or something... again, do I need to detect these or does one way work with all browsers?

    Code:
    var h2s = {
      h2_0 : {
        'head': (reference to the H2 itself),
        'h3s': (nodelist of H3s below this H2)
      },
      h2_1: {
        'head': (reference to the H2 itself),
        'h3s': (nodelist of H3s below this H2)
      }
      // etc.
    }
    This might be what I need to study, because it also looks like I can use this to make h2_x[h3s][0] or something similar to make a special case for the First h3 of every chunk of h3's (that one is called "overall" and the manager guy wants that when someone clicks "overall" that just all the other links appear).
    Someone sent me the JS version of Perl's Data Dumper (http://www.javascripttoolbox.com/lib/datadumper/) and if I'm going to build things like this maybe I can at the same time learn how to use and read DataDumper. That'll help me later when I can get back to Perl. : )

    Quote Originally Posted by Raffles
    And BTW, don't use "parent" for the variable name, as in the global scope "parent" is the same as window.parent, which can be a reference to either an actual parent window if the document is loaded in an iframe or as part of a frameset, or otherwise just the window (same as window.self).
    Damn, why wasn't this mentioned in the Javascript Anthology? I used "parent" mostly because that's what every example uses, and it made sense to me. Maybe my tendency to use Dutch words for stuff should be encouraged until I'm sure which words might be interpreted differently and which won't.

    It is h2.nextSibling.nextSibling that targets the DIV because there is also a textNode of whitespace between them that counts as a sibling. A major PITA most of the time. Things like jQuery dispense with having to think about this sort of thing, which is why I think people that go from jQuery to pure JavaScript would not really feel very comfortable.
    What do you think of the solution presented in Javascript Anthology? They add a while loop that says so long as the nodetype is 3 then do another nextSibling.

    Quote Originally Posted by mark
    My point is, if I have one.. everyone uses a framework. You are suggesting to roll your own so you understand exactly how it works. I'm not disagreeing that it would be beneficial to learning the language - without a doubt it would.
    I would never, ever, ever hire a front-ender who could only work with CSS frameworks, who had no idea what was bloated in that code and what was necessary, and could write nothing on their own. Better that they know how to do it themselves and then also, as an add-on, learned a framework. If you're a newb relying on a black box to fix all your problems for you you're so reliant on that black box, it's no different than only being able to program in DreamBeaver design view and totally lost in a real text editor.

    I have to fight extra hard for this because I was one of those kids who just wanted to jump to using the calculator because while I always screwed up and was off by 1 when I did it long hand on paper, the calculator was never wrong. I know me. I'm lazy.

    This sounds pretty elitist to me. I know many very experience javascript developers who praise jQuery and use it heavily.
    Many Very Experienced Javascript Developers are probably not tied to one specific framework. Because they actually speak the language and not just the phrases out of the phrasebook, they can go from framework to framework as they go from employer to employer and not miss a beat.

    So anyway I'm only at page 90 in the Rhino book which is totally lagging the other books and the sites I'm trying to grab from. I have major syntax issues still. So I'm going to have to play with this for a while and see if I can get myself to understand any of it. Everyone is telling me I should be able to, so I guess I'm wondering why it's taking so long.

    Then again, stomme poes, niet een slimme poes.

  13. #13
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,278
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)
    Hm, I have an issue:
    Code:
    var h2s = {
      h2_0 : {
        'head': (reference to the H2 itself),
        'h3s': (nodelist of H3s below this H2)
      },
      h2_1: {
        'head': (reference to the H2 itself),
        'h3s': (nodelist of H3s below this H2)
      }
      // etc.
    }
    Such a code relies on very static HTML. This is not the case. One reason I hoped to figure out how to set things with nodeLists by having it, I dunno, watch for the next (other thing) was because h2's, h3's and lists might be added or removed. The basic structure will not change, and the first h3 of the list of h3's under any h2 will always do the same behaviour, but manually stating that index [x] does y will not adapt unless I rewrite it every time Dennis adds or removes a link (unless he keeps the number of elements the same).

    So I might need to do something else... maybe after I know objects better I'll know how to make it more generic.

  14. #14
    SitePoint Enthusiast Dharma's Avatar
    Join Date
    Aug 2008
    Location
    The Netherlands
    Posts
    60
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm not sure if I agree with that; Since this data structure is being built on page load by using methods like getElementsByTagName, the struct will be accurate.

    The reason for creating a struct like this is that it makes it easier to do The Right Thing with your data- it makes it into easily accessible chunks.

    The only line that is tricky is, as Raffles writes:

    Code:
      h2i.h3s = h2els[i].nextSibling.nextSibling.getElementsByTagName('h3'); // you have to be confident about the HTML structure here!
    But as long as that baser html structure doesn't change, you're good. If Dennis adds or removes a link, that only influences where the link should be added, but that's another matter.
    <samsara>You are here.</samsara>

  15. #15
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,278
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)
    *edit nevermind I see that was an example of want the obj structure would be... what I would see in DataDumper. ok

  16. #16
    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)
    However my code semantically made way more sense with headers and lists, instead of one big list. Maybe for learning How To Do An Expansion List I should use a list, but this is also work (I'm trying to learn on the job) so I want to use the right markup.
    I see. I was imagining this as the actual document content, with collapsing sections. It didn't occur to me this would be more of a navigation device.

    What do you think of the solution presented in Javascript Anthology? They add a while loop that says so long as the nodetype is 3 then do another nextSibling.
    It's fine, a standard solution to this minor niggle.

    As for getAttribute, I believe IE8 has sorted that out. Before, getAttribute would work, but you'd have to do getAttribute('className') for IE, which was a waste of effort, as all browsers support element.className.

    "for" and "class" are reserved words in javascript (scroll to the bottom). Hence the use of htmlFor and className instead as Element properties. But when using getAttribute, you're just passing strings, so you can just use 'class' and 'for' (but not with browsers pre-IE8).

  17. #17
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,278
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)
    Hm, IE doesn't like the code (there's something that works in all other browsers... haven't checked IE8 yet). I've heard it's not terribly reliable in telling you where the real error is.

    I see. I was imagining this as the actual document content, with collapsing sections. It didn't occur to me this would be more of a navigation device.
    It's somewhere in between. And now that there's a somewhat working version, I just realised that while I added anchors so keyboarders would have something to click on, and I was hiding things by making them pos: absolute so screen readers still have access, sighted keyboarders with CSS and JS on still have to tab through everything, meaning they get no real benefit to the JS (I guess the manager just liked the look of another site where they hid and showed chunks of data). Display: none instead of pos: abso, left: -9999em would fix that, but then hide the content from screen readers (unless they have a newer reader AND realised they needed to click on something). Hm...

    Anyway, still if anyone knows of good tutorials for the struggling javascripter regarding nodeLIsts, arrays and objects (with code to play with and exercises to go through) that would be great. Right now I'm just making some dummy HTML on a page and just trying to practice with examples from pages like http://www.javascriptkit.com/jsref/looping.shtml but those are examples and not exactly the same as an exercise ("make a list of foos and when the user bar's, make every other one baz) or whatever.

  18. #18
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,278
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)
    I want to keep this thread ontrack re tuts and other ways of learning thse basis. I'm going to start a different thread with specific questions about code and IE and className. Thanks everyone!

  19. #19
    padawan silver trophybronze trophy markbrown4's Avatar
    Join Date
    Jul 2006
    Location
    Victoria, Australia
    Posts
    4,108
    Mentioned
    28 Post(s)
    Tagged
    2 Thread(s)
    On the topic of tutorials I'd suggest taking a look at Simply Javascript. It's excellent - AND doesn't use a framework
    The section on the Accordian in particular might help you simplify things a bit. Essentially they group each 'fold' in the accordian with a div and give it a class of "expanded" to the open ones. This class can hide/show the various parts in the folds. It's pretty normal to make the whole heading clickable also - so i'm not sure it's necessary to add the new + links. Just a couple of thoughts.

    Hm, IE doesn't like the code
    Have you tried what Raffles was describing above - getAttribute and setAttribute with class is handled differently in IE - so most people use the element property className instead.
    Code:
    lijst[l].setAttribute("class", "verberg");
    lijst[l].className = "verberg";
    If that's not it can you post the whole page code.

  20. #20
    SitePoint Wizard bronze trophy
    Join Date
    Jul 2006
    Location
    Augusta, Georgia, United States
    Posts
    4,147
    Mentioned
    16 Post(s)
    Tagged
    3 Thread(s)
    Maybe I'm misunderstanding something but the below seems to provide the desired effects.

    HTML Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
            "http://www.w3.org/TR/html4/strict.dtd">
    <html lang="en">
    <head>
    	<meta http-equiv="content-type" content="text/html; charset=utf-8">
    	<title>Untitled</title>
    	
    	<script type="text/javascript">
    	window.onload = function() {
    	
    		(function(strRootDiv) {
    			
    			/*
    			* Get root element node
    			*/
    			var objRootDiv = document.getElementById(strRootDiv);
    			if(!objRootDiv) return;
    			
    			objRootDiv['onclick'] = function(objEvt) {
    				
    				var objEvt = objEvt || window.event;
    				var objTarget = objEvt.target || objEvt.srcElement;
    				
    				if(objTarget.nodeName == 'H2' || objTarget.nodeName == 'H3') {
    					
    					var strChildNodeType = objTarget.nodeName == 'H2'?'DIV':'UL';
    					var objSibling = objTarget.nextSibling;
    					
    					while(objSibling && objSibling.nodeName != strChildNodeType) {
    						objSibling = objSibling.nextSibling;
    					}
    					
    					objSibling.style.display = objSibling.style.display == 'block'?'none':'block';
    					
    				}
    				
    			}
    			
    		})('beschrijflinks');
    		
    	}
    	</script>
    	
    	<style type="text/css">
    		#beschrijflinks div {
    			display: none;
    		}
    		#beschrijflinks div ul {
    			display: none;
    		}
    	</style>
    	
    </head>
    <body>
    
    
    <div id="beschrijflinks">
      <h2>Main header</h2>
        <div>
          <h3>Sub Header OVERALL</h3>
          <ul>
          	<li>One</li>
          	<li>Two</li>
          	<li>Three</li>
          </ul>
          <h3>Sub Header</h3>
          <ul>
          	<li>One</li>
          	<li>Two</li>
          	<li>Three</li>
          </ul>
        </div>
      <h2>Main Header</h2>
        <div>
          <h3>Sub Header OVERALL</h3>
          <ul>
          	<li>One</li>
          	<li>Two</li>
          	<li>Three</li>
          </ul>
          <h3>Sub Header</h3>
          <ul>
          	<li>One</li>
          	<li>Two</li>
          	<li>Three</li>
          </ul>
        </div>  
      <h2>Main Header</h2>
        <div>
          <h3>Sub Header OVERALL</h3>
          <ul>
          	<li>One</li>
          	<li>Two</li>
          	<li>Three</li>
          </ul>
          <h3>Sub Header</h3>
          <ul>
          	<li>One</li>
          	<li>Two</li>
          	<li>Three</li>
          </ul>
        </div>
    </div>
    
    </body>
    </html>

  21. #21
    SitePoint Wizard Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,278
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)
    oddz:
    I've got something that mostly works, and I was specifically trying to avoid display: none (but I'm going to talk to Tommy about that... I've got a conflict between screen reader users who cant have display: none and sighted keyboarders who prolly would be better off with display: none) but I will look at your code anyway because it's good to learn.

    Quote Originally Posted by mark
    On the topic of tutorials I'd suggest taking a look at Simply Javascript. It's excellent - AND doesn't use a framework
    Actually I have that one and I had abandoned it until I had other things better under my belt, so I had stopped at the stripey tables and inteded to get back to it later...
    my problem totally was that I needed to use Core.js to get anything started and I know that if you eventually get through the book you will have basically built Core but I'm a linear person. I can't use a black box to start, it's like walking backwards down a path you've never been on, and then being asked to walk forward... you've seen where you were while walking backwards, so you should know the way back, but my personal retardation doesn't deal with that well.

    However maybe now is the time to get back to that.

    Have you tried what Raffles was describing above - getAttribute and setAttribute with class is handled differently in IE - so most people use the element property className instead.
    I'm still not sure if that's the problem or not... I've also got a problem with the nodes being wrong in IE and today I had planned to try out the while staement that set nextSiblings until the next node wasn't whitespace.

    Since what I ended up with (which I'm still in the process of trying to "get") has those statements often wrapped in conditionals I'll have to see how to add the IE-versions without conflicting with other browsers:
    lijst[l].setAttribute("class", "verberg");
    lijst[l].className = "verberg";

    If I could just do that then why am I not just using the second line in the first place? Is it safe to just repeat the second line (instead of something like testing for "class" first and feeding className to IE when "class" isn't supported?
    target.setAttribute('class', target.className + classValue);

    Actually I started another thread because I didn't want this one to be too focussed on my particular code. Maybe that was a dumb thing to do : )

  22. #22
    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)
    All browsers support element.className. So it is safer and less painful than faffing about with setAttribute and doing some sort of browser detection, which should be avoided at all costs (since object detection here would be useless).

    When you do your while statement to check the nodeType, I would check for a nodeType of 1 instead of 3, as you are not interested in textNodes (3), but you are interested in locating the element node (1):
    Code:
    var el = someDOMElement.nextSibling;
    while (el.nodeType !== 1) el = el.nextSibling;


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
  •