[Proto-Scripty] Re: How would I get a closer set of siblings?

2010-04-28 Thread Matt Foster
This would be an ideal use case for XPath.



On Mar 5, 10:35 am, Walter Lee Davis wa...@wdstudio.com wrote:
 Thanks, yes that might work. But I am trying to write something which  
 is structure-agnostic, since it goes in a plug-in for a Web design  
 application, and I have no idea how people will want to use it. Alex's  
 suggestion allows me to do the very least (and therefore resist the  
 urge to screw up) while still offering an unsurprising result in a  
 wide range of layout situations.

 Walter

 On Mar 5, 2010, at 8:08 AM, Eric wrote:



  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.comwrote:

  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++) {
  

Re: [Proto-Scripty] Re: How would I get a closer set of siblings?

2010-03-05 Thread Walter Lee Davis
Thanks, yes that might work. But I am trying to write something which  
is structure-agnostic, since it goes in a plug-in for a Web design  
application, and I have no idea how people will want to use it. Alex's  
suggestion allows me to do the very least (and therefore resist the  
urge to screw up) while still offering an unsurprising result in a  
wide range of layout situations.


Walter

On Mar 5, 2010, at 8:08 AM, Eric wrote:


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.comwrote:



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 

Re: [Proto-Scripty] Re: How would I get a closer set of siblings?

2010-02-23 Thread Alex Wallace
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.comwrote:

 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 /
 titleDemo/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
 h3first header/h3
 p id=foofirst paragraph/p
 psecond paragraph/p
 h3second header/h3
 pthird paragraph/p
 pfourth paragraph/p
 pfifth paragraph/p
 h3third header/h3
 psixth paragraph/p
 pseventh 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 

Re: [Proto-Scripty] Re: How would I get a closer set of siblings?

2010-02-23 Thread Walter Lee Davis

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.comwrote:




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 /
titleDemo/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 

Re: [Proto-Scripty] Re: How would I get a closer set of siblings?

2010-02-22 Thread Walter Lee Davis
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.comwrote:




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 /

titleDemo/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
h3first header/h3
p id=foofirst paragraph/p
psecond paragraph/p
h3second header/h3
pthird paragraph/p
pfourth paragraph/p
pfifth paragraph/p
h3third header/h3
psixth paragraph/p
pseventh paragraph/p
/div
/body
/html


On Mon, Feb 22, 2010 at 8:22 AM, Walter Lee Davis  
wa...@wdstudio.comwrote:


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