Here's a slightly better version, as it crawls the tree itself instead of
grabbing and filtering all of the element's nextSiblings(). Since it avoids
the call to recursivelyCollect() it's a bit faster (with 10 siblings after
the requested node, it's about 20% faster - when I upped it to about 40
elements after the node, it ran well over 250% faster). If you have a lot of
nodes to filter for the accordion, I'd definitely use this version.

function fasterSameTagSiblings(element) {
element = $(element);
var results = [], node = element.nextSibling, tag;
while (node = node.nextSibling) {
if (node.nodeType === 1) {
tag = tag || node.tagName.toLowerCase();
if (node.tagName.toLowerCase() === tag)
results.push(node)
else
break;
}
}
return results;
}

Cheers,
Alex

Micro-optimization for sure, but it was bugging me. :)

function fasterSameTagSiblings(element) {
element = $(element);
var results = [], node = element.nextSibling, tag;
while (node = node.nextSibling) {
if (node.nodeType === 1) {
tag = tag || node.tagName.toLowerCase();
if (node.tagName.toLowerCase() === tag)
results.push(node)
else
break;
}
}
return results;
}


On Mon, Feb 22, 2010 at 8:24 PM, Walter Lee Davis <wa...@wdstudio.com>wrote:

> The heads and the paragraphs are all at the same level, and I don't want
> all the paragraphs, just the ones between "this" head and the next head.
> (It's for an accordion effect.) So while up('div').select('p') would do
> exactly what you say, it would leave me where I started.
>
> Thanks,
>
> Walter
>
>
> On Feb 22, 2010, at 5:46 PM, Matt Foster wrote:
>
>  This is probably too obvious to be right but if you're simply looking
>> for all of the paragraph tags at that level could you simply go up to
>> the parent and select down from there?
>>
>>
>>
>>
>> On Feb 22, 12:57 pm, Paul Kim <kimba...@gmail.com> wrote:
>>
>>> Hi Alex, thanks for the tip. I've modified the function based on your tip
>>> and your example function:
>>>
>>>    function consecutiveSameTagSiblings(element) {
>>>        var element = $(element);
>>>        var nextSiblings = element.nextSiblings();
>>>        var similarElements = [];
>>>        similarElements.push(element);
>>>        for (var i=0; i< nextSiblings.length; i++) {
>>>            if (element.tagName == nextSiblings[i].tagName) {
>>>                similarElements.push(nextSiblings[i]);
>>>            }
>>>            else {
>>>                break;
>>>            }
>>>        }
>>>        return similarElements;
>>>    }
>>>
>>> On Mon, Feb 22, 2010 at 9:50 AM, Alex Wallace <alexmlwall...@gmail.com
>>> >wrote:
>>>
>>>
>>>
>>>  Paul, one recommendation: store the results of element.nextSiblings() in
>>>> a
>>>> local variable outside of the loop. DOM traversals are pretty slow.
>>>>
>>>
>>>  Best,
>>>> Alex
>>>>
>>>
>>>  On Mon, Feb 22, 2010 at 12:28 PM, Paul Kim <kimba...@gmail.com> wrote:
>>>>
>>>
>>>  Hi Walter, if you want to get all similar elements up to but not
>>>>> including
>>>>> the next head, I would use Prototype's Element.nextSiblings() to loop
>>>>> through all elements with the same tagName and break when the tagName
>>>>> is
>>>>> different. Here is a function I created just now that would hopefully
>>>>> do
>>>>> what you want:
>>>>>
>>>>
>>>  function getSimilarElements(element) {
>>>>>    var element = $(element);
>>>>>    var similarElements = new Array();
>>>>>    for (var i=0; i< element.nextSiblings().length; i++) {
>>>>>        if (element.tagName == element.nextSiblings()[i].tagName) {
>>>>>            similarElements[i] = element.nextSiblings()[i];
>>>>>        }
>>>>>        else {
>>>>>            break;
>>>>>        }
>>>>>    }
>>>>>    return similarElements;
>>>>> }
>>>>>
>>>>
>>>  Here is the entire example as well:
>>>>>
>>>>
>>>  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
>>>>>     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
>>>>> <html xmlns="http://www.w3.org/1999/xhtml";>
>>>>> <head>
>>>>> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
>>>>> <title>Demo</title>
>>>>> <script type="text/javascript" src="
>>>>> http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js
>>>>> "></script>
>>>>> <script type="text/javascript" src="
>>>>> http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.3/scriptaculou
>>>>> ...
>>>>> "></script>
>>>>> <script type="text/javascript">
>>>>> document.observe("dom:loaded", function() {
>>>>>    function getSimilarElements(element) {
>>>>>        var element = $(element);
>>>>>        var similarElements = new Array();
>>>>>        for (var i=0; i< element.nextSiblings().length; i++) {
>>>>>            if (element.tagName == element.nextSiblings()[i].tagName) {
>>>>>                similarElements[i] = element.nextSiblings()[i];
>>>>>            }
>>>>>            else {
>>>>>                break;
>>>>>            }
>>>>>        }
>>>>>        return similarElements;
>>>>>    }
>>>>>
>>>>
>>>     console.log(getSimilarElements('foo'));
>>>>> });
>>>>> </script>
>>>>> <style type="text/css">
>>>>> body {margin:0; padding:0;}
>>>>> </style>
>>>>> </head>
>>>>> <body>
>>>>> <div>
>>>>> <h3>first header</h3>
>>>>> <p id="foo">first paragraph</p>
>>>>> <p>second paragraph</p>
>>>>> <h3>second header</h3>
>>>>> <p>third paragraph</p>
>>>>> <p>fourth paragraph</p>
>>>>> <p>fifth paragraph</p>
>>>>> <h3>third header</h3>
>>>>> <p>sixth paragraph</p>
>>>>> <p>seventh paragraph</p>
>>>>> </div>
>>>>> </body>
>>>>> </html>
>>>>>
>>>>
>>>  On Mon, Feb 22, 2010 at 8:22 AM, Walter Lee Davis <wa...@wdstudio.com
>>>>> >wrote:
>>>>>
>>>>
>>>  Thanks very much. I was looking in the wrong place for the functionality
>>>>>> I need. You've given me the bones I need to build on.
>>>>>>
>>>>>
>>>  Walter
>>>>>>
>>>>>
>>>  On Feb 22, 2010, at 11:07 AM, Alex Wallace wrote:
>>>>>>
>>>>>
>>>   I whipped up something that should handle the task, although I'm sure
>>>>>>
>>>>>>> this could be optimized using the nextElementSibling. This version
>>>>>>> grabs
>>>>>>> nextSiblings() and then filters them, but the faster way would be to
>>>>>>> iterate
>>>>>>> over the `element.nextSibling` and break when it encounters a
>>>>>>> different tag
>>>>>>> name (instead of finding them all, which is bound to be slower).
>>>>>>>
>>>>>>
>>>  But here goes:
>>>>>>>
>>>>>>
>>>        function consecutiveSameTagSiblings(element) {
>>>>>>>               element = $(element);
>>>>>>>               var siblings = element.nextSiblings(), results = [];
>>>>>>>               if (!siblings[0]) return results;
>>>>>>>               var tagName = siblings[0].tagName.toLowerCase();
>>>>>>>               for (var i = 0, sibling; sibling = siblings[i]; ++i) {
>>>>>>>                       if (sibling.tagName.toLowerCase() === tagName)
>>>>>>>                               results.push(sibling);
>>>>>>>                       else
>>>>>>>                               break;
>>>>>>>               }
>>>>>>>               return results;
>>>>>>>       }
>>>>>>>
>>>>>>
>>>  Best,
>>>>>>> Alex
>>>>>>>
>>>>>>
>>>  On Mon, Feb 22, 2010 at 10:38 AM, Walter Lee Davis <wa...@wdstudio.com>
>>>>>>> wrote:
>>>>>>> Hmmm. That's not a documented function. I had a look at the source,
>>>>>>> and
>>>>>>> I can't see how it works. It accepts a node as its only argument, and
>>>>>>> it
>>>>>>> doesn't seem to perform any comparison as it executes. How then would
>>>>>>> I get
>>>>>>> it to stick to just the one type of sibling, and how would I get it
>>>>>>> to stop
>>>>>>> when it ran out of similar siblings?
>>>>>>>
>>>>>>
>>>  Thanks as always for any pointers.
>>>>>>>
>>>>>>
>>>  Walter
>>>>>>>
>>>>>>
>>>  On Feb 22, 2010, at 10:29 AM, Alex Wallace wrote:
>>>>>>>
>>>>>>
>>>  You'll want to leverage Prototype's nextElementSibling function. That
>>>>>>> function grabs element.nextSibling and traverses until it finds an an
>>>>>>> actual
>>>>>>> element (by checking nodeType).
>>>>>>>
>>>>>>
>>>  You could wrap a function around that which stores the tagName of the
>>>>>>> first element it matches, and then continues to find
>>>>>>> nextElementSibling
>>>>>>> until it either returns null, or break when the tagName doesn't match
>>>>>>> the
>>>>>>> original tagName.
>>>>>>>
>>>>>>
>>>  Take a look at the innards of Element.adjacent and
>>>>>>> Element.nextElementSibling for an idea of what I mean.
>>>>>>>
>>>>>>
>>>  Best,
>>>>>>> Alex
>>>>>>>
>>>>>>
>>>  On Mon, Feb 22, 2010 at 12:00 AM, Walter Lee Davis <wa...@wdstudio.com>
>>>>>>> wrote:
>>>>>>> I have a structure like this inside a parent DIV:
>>>>>>>
>>>>>>
>>>  H3
>>>>>>> P
>>>>>>> P
>>>>>>> H3
>>>>>>> P
>>>>>>> P
>>>>>>> P
>>>>>>> H3
>>>>>>> P
>>>>>>> P
>>>>>>>
>>>>>>
>>>  And I'd like to be able to get the paragraphs between two heads, or
>>>>>>> between the last head and the end of the parent DIV.
>>>>>>> Element.adjacent('p')
>>>>>>> doesn't do what I need -- it returns all the p tags in the entire
>>>>>>> DIV, since
>>>>>>> everything is at the same level. If I get a reference to the first
>>>>>>> element
>>>>>>> following the head, how could I get all similar elements up to but
>>>>>>> not
>>>>>>> including the next head? I'm trying to find a purely structure based
>>>>>>> way to
>>>>>>> do this, rather than adding classnames to the elements.
>>>>>>>
>>>>>>
>>>  Thanks,
>>>>>>>
>>>>>>
>>>  Walter
>>>>>>>
>>>>>>
>>>  --
>>>>>>> You received this message because you are subscribed to the Google
>>>>>>> Groups "Prototype & script.aculo.us" group.
>>>>>>> To post to this group, send email to
>>>>>>> prototype-scriptacul...@googlegroups.com.
>>>>>>> To unsubscribe from this group, send email to
>>>>>>> prototype-scriptaculous+unsubscr...@googlegroups.com<prototype-scriptaculous%2bunsubscr...@googlegroups.com><prototype-scriptaculou
>>>>>>> s%2bunsubscr...@googlegroups.com<s%252bunsubscr...@googlegroups.com>
>>>>>>> >
>>>>>>> .
>>>>>>> For more options, visit this group at
>>>>>>> http://groups.google.com/group/prototype-scriptaculous?hl=en.
>>>>>>>
>>>>>>
>>>  --
>>>>>>> You received this message because you are subscribed to the Google
>>>>>>> Groups "Prototype & script.aculo.us" group.
>>>>>>> To post to this group, send email to
>>>>>>> prototype-scriptacul...@googlegroups.com.
>>>>>>> To unsubscribe from this group, send email to
>>>>>>> prototype-scriptaculous+unsubscr...@googlegroups.com<prototype-scriptaculous%2bunsubscr...@googlegroups.com><prototype-scriptaculou
>>>>>>> s%2bunsubscr...@googlegroups.com<s%252bunsubscr...@googlegroups.com>
>>>>>>> >
>>>>>>> .
>>>>>>> For more options, visit this group at
>>>>>>> http://groups.google.com/group/prototype-scriptaculous?hl=en.
>>>>>>>
>>>>>>
>>>  --
>>>>>>> You received this message because you are subscribed to the Google
>>>>>>> Groups "Prototype & script.aculo.us" group.
>>>>>>> To post to this group, send email to
>>>>>>> prototype-scriptacul...@googlegroups.com.
>>>>>>> To unsubscribe from this group, send email to
>>>>>>> prototype-scriptaculous+unsubscr...@googlegroups.com<prototype-scriptaculous%2bunsubscr...@googlegroups.com><prototype-scriptaculou
>>>>>>> s%2bunsubscr...@googlegroups.com<s%252bunsubscr...@googlegroups.com>
>>>>>>> >
>>>>>>> .
>>>>>>> For more options, visit this group at
>>>>>>> http://groups.google.com/group/prototype-scriptaculous?hl=en.
>>>>>>>
>>>>>>
>>>  --
>>>>>>> You received this message because you are subscribed to the Google
>>>>>>> Groups "Prototype & script.aculo.us" group.
>>>>>>> To post to this group, send email to
>>>>>>> prototype-scriptacul...@googlegroups.com.
>>>>>>> To unsubscribe from this group, send email to
>>>>>>> prototype-scriptaculous+unsubscr...@googlegroups.com<prototype-scriptaculous%2bunsubscr...@googlegroups.com><prototype-scriptaculou
>>>>>>> s%2bunsubscr...@googlegroups.com<s%252bunsubscr...@googlegroups.com>
>>>>>>> >
>>>>>>> .
>>>>>>> For more options, visit this group at
>>>>>>> http://groups.google.com/group/prototype-scriptaculous?hl=en.
>>>>>>>
>>>>>>
>>>  --
>>>>>> You received this message because you are subscribed to the Google
>>>>>> Groups
>>>>>> "Prototype & script.aculo.us" group.
>>>>>> To post to this group, send email to
>>>>>> prototype-scriptacul...@googlegroups.com.
>>>>>> To unsubscribe from this group, send email to
>>>>>> prototype-scriptaculous+unsubscr...@googlegroups.com<prototype-scriptaculous%2bunsubscr...@googlegroups.com><prototype-scriptaculou
>>>>>> s%2bunsubscr...@googlegroups.com <s%252bunsubscr...@googlegroups.com>
>>>>>> >
>>>>>> .
>>>>>> For more options, visit this group at
>>>>>> http://groups.google.com/group/prototype-scriptaculous?hl=en.
>>>>>>
>>>>>
>>>   --
>>>>> You received this message because you are subscribed to the Google
>>>>> Groups
>>>>> "Prototype & script.aculo.us" group.
>>>>> To post to this group, send email to
>>>>> prototype-scriptacul...@googlegroups.com.
>>>>> To unsubscribe from this group, send email to
>>>>> prototype-scriptaculous+unsubscr...@googlegroups.com<prototype-scriptaculous%2bunsubscr...@googlegroups.com><prototype-scriptaculou
>>>>> s%2bunsubscr...@googlegroups.com <s%252bunsubscr...@googlegroups.com>>
>>>>> .
>>>>> For more options, visit this group at
>>>>> http://groups.google.com/group/prototype-scriptaculous?hl=en.
>>>>>
>>>>
>>>   --
>>>> You received this message because you are subscribed to the Google
>>>> Groups
>>>> "Prototype & script.aculo.us" group.
>>>> To post to this group, send email to
>>>> prototype-scriptacul...@googlegroups.com.
>>>> To unsubscribe from this group, send email to
>>>>
>>>
>>> ...
>>>
>>> read more ยป
>>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "Prototype & script.aculo.us" group.
>> To post to this group, send email to
>> prototype-scriptacul...@googlegroups.com.
>> To unsubscribe from this group, send email to
>> prototype-scriptaculous+unsubscr...@googlegroups.com<prototype-scriptaculous%2bunsubscr...@googlegroups.com>
>> .
>> For more options, visit this group at
>> http://groups.google.com/group/prototype-scriptaculous?hl=en.
>>
>>
> --
> You received this message because you are subscribed to the Google Groups
> "Prototype & script.aculo.us" group.
> To post to this group, send email to
> prototype-scriptacul...@googlegroups.com.
> To unsubscribe from this group, send email to
> prototype-scriptaculous+unsubscr...@googlegroups.com<prototype-scriptaculous%2bunsubscr...@googlegroups.com>
> .
> For more options, visit this group at
> http://groups.google.com/group/prototype-scriptaculous?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Prototype & script.aculo.us" group.
To post to this group, send email to prototype-scriptacul...@googlegroups.com.
To unsubscribe from this group, send email to 
prototype-scriptaculous+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.

Reply via email to