views:

81

answers:

6

I have a element which contains 3 child. let says

<div class="parent">

<div class="firstChild">firstChild</div> 
SecondChild
<ul><li>thrid child</li></ul>

</div>

In the example I need to select first 2 childs and not the UL. how to do through jquery.

A: 

This selector should do it.

$(".parent *").not("ul")
Jose Basilio
A: 

Try this:

$(".parent").children();
VinTem
+2  A: 

You can use the :lt selector. http://api.jquery.com/lt-selector/ and the * selector.

$('div.parent > *:lt(2)')

BIllium
Should probably read $(".parent>:lt(2)") to make sure you are selecting the nodes directly below parent. Doesn't matter in this example, but given firstchild has other contents like <div class="firstChild">first<b>Child</b></div> it won't work as expected.
Mads Mobæk
Yeah, for sure. I also just realized this won't select the text nodes. I missed that little detail. I never have text out like that and honestly never knew you could select them if they're like that. I did come across this which seems like it can be very useful.http://refactormycode.com/codes/341-jquery-all-descendent-text-nodes-within-a-node#refactor_12159
BIllium
A: 

If you want the text node included, .clone() it and remove what you don't want like this:

var children = $(".parent").clone();
children.find("ul").remove(); //or: children.find(":gt(1)").remove();
//children now contains everything by the <ul>
Nick Craver
A: 

I commented some in the original post about what nodes there really are in the poster's example markup.
Here is a little something to print out the "real" structure if anyone is interested. I just added an id to the parent element to get ahold of it a little easier when about to start walking the DOM:

<body>

<div id="parent" class="parent">

<div class="firstChild">firstChild</div> 
SecondChild
<ul><li>thrid child</li></ul>

</div>

<script type="text/javascript">
    (function (startNode) {
        // Recursively walking the structure from the supplied node
        function walk(node, indent) {
            indent = (typeof indent==='undefined') ? '' : indent;
            var children = node.childNodes;
            var child, info;
            // For each child of node...
            for (var idx=0, len=children.length; idx<len; ++idx) {
                child = children.item(idx);
                // ..print it.
                printNodeInfo(child, indent);
                // If it was an element (tag) we try to display any children it might have
                if (child.nodeType===1) {
                    arguments.callee(child, indentAdd+indent);
                }
            }
        }
        function printNodeInfo(node, indent) {
            indent = (typeof indent==='undefined') ? '' : indent;
            console.log(indent+getNodePrintString(node));
        }
        function getNodePrintString(node) {
            var info = '';
            // Check type and extract what info to display
            if (node.nodeType===1) {info = node.nodeName;} // element nodes, show name
            else if (node.nodeType===3) {info = trim(node.nodeValue);} // text nodes, show value
            // If it was an empty textnode, return special string
            if (!info) {return '[empty '+nodeTypes[node.nodeType]+' node]';}
            else {return nodeTypes[node.nodeType]+': '+info+(node.id?'#'+node.id:'');}
        }
        // Just a utility function to trim values of textnodes
        function trim(str) {
            return str.replace(/^\s+/, '').replace(/\s+$/, '');
        }
        // Amount of indentation to add each level
        var indentAdd = '    ';
        // Mappings for nodeType => name of nodetype
        var nodeTypes = {
            1: '@Element'
            , 2: '@Attribute' // not used right now
            , 3: '@Text'
        };
        // Print info in start node
        printNodeInfo(startNode);
        // Start walking
        walk(startNode, indentAdd);
    })(document.getElementById('parent')); // Supply a start node

</script>
</body>

And here's the output:

@Element: DIV#parent
    [empty @Text node]
    @Element: DIV
        @Text: firstChild
    @Text: SecondChild
    @Element: UL
        @Element: LI
            @Text: thrid child
    [empty @Text node]
npup
A: 

Here's how you can grab childnodes of an element, including "pure" text nodes (text not inside tags).

// Returns child nodes (including text nodes, if not empty) of 'node',
// but no more than 'limit' nodes.
// If limit given is not a number >= 0, it harvests as many as it can find.
function npupNodes(node, limit) {
    // not a number or < 0 means 'no limit'
    limit = (typeof limit!=='number' || limit<0) ? -1 : limit;
    var result = [];
    var children = node.childNodes;
    var child, nodeType, captureCount=0;
    // Loop over children...
    for (var idx=0, len=children.length; idx<len && (limit<0 || captureCount<limit); ++idx) {
        child = children.item(idx);
        nodeType = child.nodeType;
        // If it is an element or a textnode...
        if (nodeType===1 || nodeType===3) {
            if (nodeType===3 && !child.nodeValue.replace(/^\s+/, '').replace(/\s+$/, '')) {
                // ..if it is a textnode that is logically empty, ignore it
                continue;
            }
            // ..otherwise add it to the harvest, and increase counter
            result.push(child);
            captureCount += 1;
        }
    }
    return result;
}

As you can see in the code, logically blank (all whitespace) textnodes are not returned.

Calling it like this with the markup in the poster's question, it does the job asked for (except for not using jQuery - sue me :)

var someChildren = npupNodes(document.getElementsByClassName('parent')[0], 2);
npup