Hi,

All the proposed solutions are very nice example of coding, but
however you may ask yourself this question:
"If there is no easy way to do the processing I want with my data
structure, am I sure I am using the right data structure?"

In other words, instead of coding heavy processing functions couldn't
you just change your DOM structure to optimize whatever processing you
need to do with them.

In your case, adding a DIV around each "H3-P-P-P..." sequence would do
the trick.

Alex: Very nice implementation!

Eric

On Feb 23, 6:20 pm, Walter Lee Davis <wa...@wdstudio.com> wrote:
> Wow, thanks very much Alex!
>
> Walter
>
> On Feb 23, 2010, at 11:28 AM, Alex Wallace wrote:
>
> > 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-
> > scriptaculou s%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-
> > scriptaculou s%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-
> > scriptaculou s%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
>
> ...
>
> 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.
For more options, visit this group at 
http://groups.google.com/group/prototype-scriptaculous?hl=en.

Reply via email to