redacted
redacted

Reputation: 463

JavaScript get child element

Why this does not work in firefox i try to select the category and then make subcategory visible.

<script type="text/javascript">
    function show_sub(cat) {
      var cat = document.getElementById("cat");
      var sub = cat.getElementsByName("sub");
      sub[0].style.display='inline'; 
}

</script>

-

<ul>
    <li id="cat" onclick="show_sub(this)">
        Top 1
        <ul style="display:none" name="sub">
            <li>Sub 1</li>
            <li>Sub 2</li>
            <li>Sub 3</li>
        </ul>
    </li>
    <li>Top 2</li>
    <li>Top 3</li>
    <li>Top 4</li>
</ul>

EDIT Answer is:

<script type="text/javascript">
   function show_sub(cat) {
      cat.getElementsByTagName("ul")[0].style.display = (cat.getElementsByTagName("ul")[0].style.display == "none") ? "inline" : "none";
   }
</script>

Upvotes: 38

Views: 172025

Answers (3)

David Thomas
David Thomas

Reputation: 253496

I'd suggest doing something similar to:

function show_sub(cat) {
    if (!cat) {
        return false;
    }
    else if (document.getElementById(cat)) {
        var parent = document.getElementById(cat),
            sub = parent.getElementsByClassName('sub');
        if (sub[0].style.display == 'inline'){
            sub[0].style.display = 'none';
        }
        else {
            sub[0].style.display = 'inline';
        }
    }
}

document.getElementById('cat').onclick = function(){
    show_sub(this.id);
};​​​​

JS Fiddle demo.

Though the above relies on the use of a class rather than a name attribute equal to sub.

As to why your original version "didn't work" (not, I must add, a particularly useful description of the problem), all I can suggest is that, in Chromium, the JavaScript console reported that:

Uncaught TypeError: Object # has no method 'getElementsByName'.

One approach to working around the older-IE family's limitations is to use a custom function to emulate getElementsByClassName(), albeit crudely:

function eBCN(elem,classN){
    if (!elem || !classN){
        return false;
    }
    else {
        var children = elem.childNodes;
        for (var i=0,len=children.length;i<len;i++){
            if (children[i].nodeType == 1
                &&
                children[i].className == classN){
                    var sub = children[i];
            }
        }
        return sub;
    }
}

function show_sub(cat) {
    if (!cat) {
        return false;
    }
    else if (document.getElementById(cat)) {
        var parent = document.getElementById(cat),
            sub = eBCN(parent,'sub');
        if (sub.style.display == 'inline'){
            sub.style.display = 'none';
        }
        else {
            sub.style.display = 'inline';
        }
    }
}

var D = document,
    listElems = D.getElementsByTagName('li');
for (var i=0,len=listElems.length;i<len;i++){
    listElems[i].onclick = function(){
        show_sub(this.id);
    };
}​

JS Fiddle demo.

Upvotes: 3

mkruzil
mkruzil

Reputation: 760

ULs don't have a name attribute, but you can reference the ul by tag name.

Try replacing line 3 in your script with this:

var sub = cat.getElementsByTagName("UL");

Upvotes: 48

glarkou
glarkou

Reputation: 7101

Try this one:

function show_sub(cat) {
    var parent = cat,
    sub = parent.getElementsByClassName('sub');
    if (sub[0].style.display == 'inline'){
        sub[0].style.display = 'none';
    }
    else {
        sub[0].style.display = 'inline';
    }
}

document.getElementById('cat').onclick = function(){
    show_sub(this);
};​

and use this for IE6 & 7

if (typeof document.getElementsByClassName!='function') {
    document.getElementsByClassName = function() {
        var elms = document.getElementsByTagName('*');
        var ei = new Array();
        for (i=0;i<elms.length;i++) {
            if (elms[i].getAttribute('class')) {
               ecl = elms[i].getAttribute('class').split(' ');
                for (j=0;j<ecl.length;j++) {
                    if (ecl[j].toLowerCase() == arguments[0].toLowerCase()) {
                        ei.push(elms[i]);
                    }
                }
            } else if (elms[i].className) {
                ecl = elms[i].className.split(' ');
                for (j=0;j<ecl.length;j++) {
                    if (ecl[j].toLowerCase() == arguments[0].toLowerCase()) {
                        ei.push(elms[i]);
                    }
                }
            }
        }
        return ei;
    }
}

Upvotes: 0

Related Questions