Re: [jQuery] My basic navigation plugin

2007-03-06 Thread Joel Birch
On 06/03/2007, at 10:02 PM, Klaus Hartl wrote:
> with the if else
> statements, a test must be made for each "if" statement, whereas  
> switch
> blocks generate vector jump tables at compile time so NO test is
> actually required in the underlying code!

"vector jump tables"… nice. Thanks for the extra info – very  
interesting!

Joel.
___
jQuery mailing list
discuss@jquery.com
http://jquery.com/discuss/


Re: [jQuery] My basic navigation plugin

2007-03-06 Thread Klaus Hartl
Joel Birch schrieb:
> I thought the switch 'smelled' less that an eval would :) . Hey, this  
> could be a good place for Jörn to prove his point and suggest how  
> this could be refactored to avoid the switch :D


Some more about switch - I really think it's alright to use:

"Switch blocks should always be used where possible, as it's so much 
faster than an if—else series. This is because with the if else 
statements, a test must be made for each "if" statement, whereas switch 
blocks generate vector jump tables at compile time so NO test is 
actually required in the underlying code!"

http://www.devwebpro.com/devwebpro-39-20030514OptimizingJavaScriptforExecutionSpeed.html


-- Klaus


___
jQuery mailing list
discuss@jquery.com
http://jquery.com/discuss/


Re: [jQuery] My basic navigation plugin

2007-02-28 Thread Joel Birch

On 28/02/2007, at 11:06 PM, Klaus Hartl wrote:
>> On 28/02/2007, at 8:17 AM, Joel Birch wrote:
>>> Obviously the code has grown larger, mainly due to the switch  
>>> used to
>>> parse the insertMethod option. Can you think of a better way of  
>>> doing
>>> that whilst avoiding eval()?
>>>
>>> I have learnt a lot doing this so thanks for humouring me Klaus - I
>>> know you are very busy at the moment. Oh, here's the new code:
>
> I spotted a little optimization: in the default branch
> "menu.insertBefore(o.insertTarget);" is used. Thus you can remove the
> case for "insertBefore", that one will just use the default...
>
> I like the switch statement a lot and think it is very readable, but
> some people say switch smells (Hey Jörn ;-)) and that it is a sign  
> that
> something could be refactored. Just so you know! I'm not sure about
> that, the switch statement is considered very fast (google "duffs
> device") and for predictable cases its fine for me.
>
> -- Klaus

I repeated that line in the default branch because, whilst it is the  
default setting, I wanted it first in the switch because I thought  
that would be the most used method and therefore the switch statement  
could exit earlier (faster) if it was found first. It's probably  
negligible though, so you are right, I'll change that.

I thought the switch 'smelled' less that an eval would :) . Hey, this  
could be a good place for Jörn to prove his point and suggest how  
this could be refactored to avoid the switch :D

Joel.
___
jQuery mailing list
discuss@jquery.com
http://jquery.com/discuss/


Re: [jQuery] My basic navigation plugin

2007-02-28 Thread Klaus Hartl
Joel Birch schrieb:
> On 28/02/2007, at 8:17 AM, Joel Birch wrote:
>> On 28/02/2007, at 12:29 AM, Klaus Hartl wrote:
>>> Joel Birch schrieb:
 Hi jQuerivites,

 I'd like to offer up my humble plugin (humble is the key word here)
 to get a sense of if something this basic is of any worth to the
 community.
>>> I think its useful! Here's some work for you ;-)
>>>
>>> * Instead of doing two appends you could do:
>>>
>>> $('').append([o.head,
>>> $list]).insertBefore(this.eq(0));
>>>
>>> * Instead of using this.innerHtml you should use $(this).text() to
>>> avoid
>>> nested links for example. Imagine article headlines that are links as
>>> well but should also serve as content navigation hook.
>>>
>>> Another useful option would be to specify where to append the created
>>> navigation. I could imagine appending it to the body and apply a  
>>> fixed
>>> positioning, so that it is always in the viewport...
>>>
> 
> Hi Klaus, I've done my homework :D
> 
> Firstly, I reduced those two appends to one. I found that .append 
> (o.head,$list) works - you must have made a typo with the square  
> brackets but that was easy to figure out anyway.
> 
> Secondly, inspired by your prompt to reduce function calls, I rewrote  
> how the list was compiled by creating a string of the whole list  
> before appending that to the list. This made the whole plugin run  
> more than twice as fast as before (~30ms for 19 list items instead of  
> ~80ms).
> 
> Finally, I made it so you can target where the list is inserted as  
> you suggested. There is a new option called "insertMethod" that takes  
> one of "insertBefore", "insertAfter", "append" or "prepend", and  
> another new option called "insertTarget" which takes a jQuery object.
> 
> So now if you want to append the list to the body you can do:
> $("h2").contentMenu({"insertMethod":"append","insertTarget":$("body")});
> 
> The default is to .insertBefore(this.eq(0));
> 
> Obviously the code has grown larger, mainly due to the switch used to  
> parse the insertMethod option. Can you think of a better way of doing  
> that whilst avoiding eval()?
> 
> I have learnt a lot doing this so thanks for humouring me Klaus - I  
> know you are very busy at the moment. Oh, here's the new code:
> 
> (function($) {
> $.fn.contentMenu = function(o){
>   o = $.extend({  "head" : "Some handy links to help you navigate  
> this page:",
>   "divClass" : "contentMenu",
>   "aClass": "inPage",
>   "insertMethod" : "insertBefore",
>   "insertTarget" : this.eq(0) }, o || {});
>   $.cmCount = $.cmCount+1 || 0;
>   var $list = $("");
>   var lastInd = this.length-1;
>   var lis = '';
>   var menu = $('').append(o.head, 
> $list);
>   switch (o.insertMethod){
>   case "insertBefore":
>   menu.insertBefore(o.insertTarget);
>   break;
>   case "insertAfter":
>   menu.insertAfter(o.insertTarget);
>   break;
>   case "append":
>   o.insertTarget.append(menu);
>   break;
>   case "prepend":
>   o.insertTarget.prepend(menu);
>   break;
>   default :
>   menu.insertBefore(o.insertTarget);
>   }
>   return this.each(function(i){
>   this.id = this.id || "menu"+$.cmCount+"-el"+i;
>   lis += 'Skip to 
>  
> '+$(this).text()+'';
>   if (i==lastInd){ $list.append(lis); }
>   });
> };
> )(jQuery);
> 
> Cheers
> Joel.

I spotted a little optimization: in the default branch 
"menu.insertBefore(o.insertTarget);" is used. Thus you can remove the 
case for "insertBefore", that one will just use the default...

I like the switch statement a lot and think it is very readable, but 
some people say switch smells (Hey Jörn ;-)) and that it is a sign that 
something could be refactored. Just so you know! I'm not sure about 
that, the switch statement is considered very fast (google "duffs 
device") and for predictable cases its fine for me.


-- Klaus



___
jQuery mailing list
discuss@jquery.com
http://jquery.com/discuss/


Re: [jQuery] My basic navigation plugin

2007-02-28 Thread Joel Birch
On 28/02/2007, at 8:17 AM, Joel Birch wrote:
> On 28/02/2007, at 12:29 AM, Klaus Hartl wrote:
>> Joel Birch schrieb:
>>> Hi jQuerivites,
>>>
>>> I'd like to offer up my humble plugin (humble is the key word here)
>>> to get a sense of if something this basic is of any worth to the
>>> community.
>>
>> I think its useful! Here's some work for you ;-)
>>
>> * Instead of doing two appends you could do:
>>
>> $('').append([o.head,
>> $list]).insertBefore(this.eq(0));
>>
>> * Instead of using this.innerHtml you should use $(this).text() to
>> avoid
>> nested links for example. Imagine article headlines that are links as
>> well but should also serve as content navigation hook.
>>
>> Another useful option would be to specify where to append the created
>> navigation. I could imagine appending it to the body and apply a  
>> fixed
>> positioning, so that it is always in the viewport...
>>

Hi Klaus, I've done my homework :D

Firstly, I reduced those two appends to one. I found that .append 
(o.head,$list) works - you must have made a typo with the square  
brackets but that was easy to figure out anyway.

Secondly, inspired by your prompt to reduce function calls, I rewrote  
how the list was compiled by creating a string of the whole list  
before appending that to the list. This made the whole plugin run  
more than twice as fast as before (~30ms for 19 list items instead of  
~80ms).

Finally, I made it so you can target where the list is inserted as  
you suggested. There is a new option called "insertMethod" that takes  
one of "insertBefore", "insertAfter", "append" or "prepend", and  
another new option called "insertTarget" which takes a jQuery object.

So now if you want to append the list to the body you can do:
$("h2").contentMenu({"insertMethod":"append","insertTarget":$("body")});

The default is to .insertBefore(this.eq(0));

Obviously the code has grown larger, mainly due to the switch used to  
parse the insertMethod option. Can you think of a better way of doing  
that whilst avoiding eval()?

I have learnt a lot doing this so thanks for humouring me Klaus - I  
know you are very busy at the moment. Oh, here's the new code:

(function($) {
$.fn.contentMenu = function(o){
o = $.extend({  "head" : "Some handy links to help you navigate  
this page:",
"divClass" : "contentMenu",
"aClass": "inPage",
"insertMethod" : "insertBefore",
"insertTarget" : this.eq(0) }, o || {});
$.cmCount = $.cmCount+1 || 0;
var $list = $("");
var lastInd = this.length-1;
var lis = '';
var menu = $('').append(o.head, 
$list);
switch (o.insertMethod){
case "insertBefore":
menu.insertBefore(o.insertTarget);
break;
case "insertAfter":
menu.insertAfter(o.insertTarget);
break;
case "append":
o.insertTarget.append(menu);
break;
case "prepend":
o.insertTarget.prepend(menu);
break;
default :
menu.insertBefore(o.insertTarget);
}
return this.each(function(i){
this.id = this.id || "menu"+$.cmCount+"-el"+i;
lis += 'Skip to 
 
'+$(this).text()+'';
if (i==lastInd){ $list.append(lis); }
});
};
)(jQuery);

Cheers
Joel.


___
jQuery mailing list
discuss@jquery.com
http://jquery.com/discuss/


Re: [jQuery] My basic navigation plugin

2007-02-27 Thread Joel Birch
On 28/02/2007, at 12:29 AM, Klaus Hartl wrote:
> Joel Birch schrieb:
>> Hi jQuerivites,
>>
>> I'd like to offer up my humble plugin (humble is the key word here)
>> to get a sense of if something this basic is of any worth to the
>> community. I discussed an earlier version of the plugin briefly on a
>> previous thread (Sites Powered by jQuery) and there is an
>> implementation of it on my Preshil site (I don't want to post a link
>> here as I don't want to seem like I'm spamming it around) which is in
>> the Sites Using jQuery list at jquery.com
>>
>> To summarise, it takes your jQuery object and creates an unordered
>> list of links to the elements within the object. If the elements do
>> not have an id (needed to provide the links with a href target), a
>> unique id is created for it, otherwise it uses the existing id. Get
>> something, do something. ;)
>>
>> An options object can be passed as the only parameter. The options  
>> are:
>> - "head" : this is a string of html to appear above the list of
>> links, can be used as a heading for the list, for example.
>> - "divClass" : this is a space separated string of classes to be
>> applied on the div that wraps the entire list and head.
>> - "aClass" : this is a space separated string of classes to be
>> applied to each of the links created.
>>
>> These options have defaults of course - you can see what they are in
>> the code. The whole thing can be styled with CSS as you see fit
>> (hence the extra class hooks in the options object) and enhanced
>> further with JavaScript. I attached scrolling to the links using the
>> aClass as a hook, for example.
>>
>> I think the (possibly only one) redeeming feature of this plugin over
>> the far better and more elaborate navigation aids is that it is so
>> simple (at least how I have it styled on the Preshil site) that
>> anyone can understand the menu's purpose regardless of how tech-savy
>> they are. It's also very lightweight and, as far as CSS styling goes,
>> you only really need a background or border on the main div.
>>
>> The code:
>>
>> (function($){
>> $.fn.contentMenu = function(o){
>>  o = $.extend({  "head" : "Some handy links to help you navigate
>> this page:",
>>  "divClass" : "contentMenu",
>>  "aClass" : "inPage" }, o || {});
>>  $.cmCount = $.cmCount+1 || 0;
>>  var $list = $("");
>>  $('').append(o.head).append
>> ($list).insertBefore(this.eq(0));
>>  return this.each(function(i){
>>  this.id = this.id || "menu"+$.cmCount+"-el"+i;
>>  $list.append('> class="'+o.aClass+'">Skip
>> to '+this.innerHTML+'');
>>  });
>> };
>> )(jQuery);
>>
>> Example of calling the plugin:
>> $("#main h2").contentMenu({
>>  "head" : "Page navigation:",
>>  "aClass":"scrolls",
>>  "divClass":"alert"});
>>
>> or just using the defaults:
>> $("#main h2").contentMenu();
>>
>> I understand this is basic stuff but it's my first plugin and I'd
>> love to hear any feedback even if it's "this plugin is not really
>> interesting/useful/well made enough". I guess my question is: whilst
>> many people could create something like this easily and quickly
>> enough, should there be plugins that cover such light tasks anyway?
>>
>> Thanks and sorry for the long post.
>> Joel Birch.
>
> I think its useful! Here's some work for you ;-)
>
> * Instead of doing two appends you could do:
>
> $('').append([o.head,
> $list]).insertBefore(this.eq(0));
>
> * Instead of using this.innerHtml you should use $(this).text() to  
> avoid
> nested links for example. Imagine article headlines that are links as
> well but should also serve as content navigation hook.
>
> Another useful option would be to specify where to append the created
> navigation. I could imagine appending it to the body and apply a fixed
> positioning, so that it is always in the viewport...
>
> And how cool would it be if the headline is computed from the elements
> that are used to create the navigation? E.g. if the navigation is  
> build
> from  elements the created headline would become a  or at  
> least
> a  as well... Just an idea, doesn't make sense for all cases  
> maybe.
>
>
> -- Klaus
>
Thanks for the great feedback Klaus! I didn't realise you could  
append an array of elements. Also, great point about using $ 
(this).text() to avoid nested links. There's two new things you've  
taught me.

I did consider the option of specifying where to append the  
navigation - I'll definitely do that now. With the computed headline  
idea - it would indeed be cool, but I think I'll keep it more  
flexible for now and see if my usage of the plugin warrants it.  
Currently, the head can be any amount of HTML not just one heading,  
which I may find useful for intro paragraphs etc.

Thanks for the encouragement :)

Joel.

___
jQuery mailing list
discuss@jquery.com
http://jquery.com/discuss/


Re: [jQuery] My basic navigation plugin

2007-02-27 Thread Klaus Hartl
Joel Birch schrieb:
> Hi jQuerivites,
> 
> I'd like to offer up my humble plugin (humble is the key word here)  
> to get a sense of if something this basic is of any worth to the  
> community. I discussed an earlier version of the plugin briefly on a  
> previous thread (Sites Powered by jQuery) and there is an  
> implementation of it on my Preshil site (I don't want to post a link  
> here as I don't want to seem like I'm spamming it around) which is in  
> the Sites Using jQuery list at jquery.com
> 
> To summarise, it takes your jQuery object and creates an unordered  
> list of links to the elements within the object. If the elements do  
> not have an id (needed to provide the links with a href target), a  
> unique id is created for it, otherwise it uses the existing id. Get  
> something, do something. ;)
> 
> An options object can be passed as the only parameter. The options are:
> - "head" : this is a string of html to appear above the list of  
> links, can be used as a heading for the list, for example.
> - "divClass" : this is a space separated string of classes to be  
> applied on the div that wraps the entire list and head.
> - "aClass" : this is a space separated string of classes to be  
> applied to each of the links created.
> 
> These options have defaults of course - you can see what they are in  
> the code. The whole thing can be styled with CSS as you see fit  
> (hence the extra class hooks in the options object) and enhanced  
> further with JavaScript. I attached scrolling to the links using the  
> aClass as a hook, for example.
> 
> I think the (possibly only one) redeeming feature of this plugin over  
> the far better and more elaborate navigation aids is that it is so  
> simple (at least how I have it styled on the Preshil site) that  
> anyone can understand the menu's purpose regardless of how tech-savy  
> they are. It's also very lightweight and, as far as CSS styling goes,  
> you only really need a background or border on the main div.
> 
> The code:
> 
> (function($){
> $.fn.contentMenu = function(o){
>   o = $.extend({  "head" : "Some handy links to help you navigate  
> this page:",
>   "divClass" : "contentMenu",
>   "aClass" : "inPage" }, o || {});
>   $.cmCount = $.cmCount+1 || 0;
>   var $list = $("");
>   $('').append(o.head).append 
> ($list).insertBefore(this.eq(0));
>   return this.each(function(i){
>   this.id = this.id || "menu"+$.cmCount+"-el"+i;
>   $list.append(' class="'+o.aClass+'">Skip  
> to '+this.innerHTML+'');
>   });
> };
> )(jQuery);
> 
> Example of calling the plugin:
> $("#main h2").contentMenu({
>   "head" : "Page navigation:",
>   "aClass":"scrolls",
>   "divClass":"alert"});
> 
> or just using the defaults:
> $("#main h2").contentMenu();
> 
> I understand this is basic stuff but it's my first plugin and I'd  
> love to hear any feedback even if it's "this plugin is not really  
> interesting/useful/well made enough". I guess my question is: whilst  
> many people could create something like this easily and quickly  
> enough, should there be plugins that cover such light tasks anyway?
> 
> Thanks and sorry for the long post.
> Joel Birch.


I think its useful! Here's some work for you ;-)

* Instead of doing two appends you could do:

$('').append([o.head, 
$list]).insertBefore(this.eq(0));

* Instead of using this.innerHtml you should use $(this).text() to avoid 
nested links for example. Imagine article headlines that are links as 
well but should also serve as content navigation hook.

Another useful option would be to specify where to append the created 
navigation. I could imagine appending it to the body and apply a fixed 
positioning, so that it is always in the viewport...

And how cool would it be if the headline is computed from the elements 
that are used to create the navigation? E.g. if the navigation is build 
from  elements the created headline would become a  or at least 
a  as well... Just an idea, doesn't make sense for all cases maybe.


-- Klaus





___
jQuery mailing list
discuss@jquery.com
http://jquery.com/discuss/


Re: [jQuery] My basic navigation plugin

2007-02-27 Thread Joel Birch
On 27/02/2007, at 9:10 PM, Yehuda Katz wrote:
> So the basic idea is that you can create a table of contents based  
> on a series of links selected by a jQuery selector?
>
> Could be useful...
>
>
> -- Yehuda

You can create a table of contents based on the elements you collect  
in a jQuery object. For example, $("h2").contentMenu(); will create a  
list of links that will take you to each of the h2 heading in the  
page. The text in the link is whatever text was in the h2 tags but  
with "skip to" added before it. The menu gets inserted before the  
first of those h2 elements.

Thanks for the reply Yehuda.

___
jQuery mailing list
discuss@jquery.com
http://jquery.com/discuss/


Re: [jQuery] My basic navigation plugin

2007-02-27 Thread Yehuda Katz

So the basic idea is that you can create a table of contents based on a
series of links selected by a jQuery selector?

Could be useful...


-- Yehuda

On 2/27/07, Joel Birch <[EMAIL PROTECTED]> wrote:


Hi jQuerivites,

I'd like to offer up my humble plugin (humble is the key word here)
to get a sense of if something this basic is of any worth to the
community. I discussed an earlier version of the plugin briefly on a
previous thread (Sites Powered by jQuery) and there is an
implementation of it on my Preshil site (I don't want to post a link
here as I don't want to seem like I'm spamming it around) which is in
the Sites Using jQuery list at jquery.com

To summarise, it takes your jQuery object and creates an unordered
list of links to the elements within the object. If the elements do
not have an id (needed to provide the links with a href target), a
unique id is created for it, otherwise it uses the existing id. Get
something, do something. ;)

An options object can be passed as the only parameter. The options are:
- "head" : this is a string of html to appear above the list of
links, can be used as a heading for the list, for example.
- "divClass" : this is a space separated string of classes to be
applied on the div that wraps the entire list and head.
- "aClass" : this is a space separated string of classes to be
applied to each of the links created.

These options have defaults of course - you can see what they are in
the code. The whole thing can be styled with CSS as you see fit
(hence the extra class hooks in the options object) and enhanced
further with JavaScript. I attached scrolling to the links using the
aClass as a hook, for example.

I think the (possibly only one) redeeming feature of this plugin over
the far better and more elaborate navigation aids is that it is so
simple (at least how I have it styled on the Preshil site) that
anyone can understand the menu's purpose regardless of how tech-savy
they are. It's also very lightweight and, as far as CSS styling goes,
you only really need a background or border on the main div.

The code:

(function($){
$.fn.contentMenu = function(o){
o = $.extend({  "head" : "Some handy links to help you
navigate
this page:",
"divClass" : "contentMenu",
"aClass" : "inPage" }, o || {});
$.cmCount = $.cmCount+1 || 0;
var $list = $("");
$('').append(o.head).append
($list).insertBefore(this.eq(0));
return this.each(function(i){
this.id = this.id || "menu"+$.cmCount+"-el"+i;
$list.append('Skip
to '+this.innerHTML+'');
});
};
)(jQuery);

Example of calling the plugin:
$("#main h2").contentMenu({
"head" : "Page navigation:",
"aClass":"scrolls",
"divClass":"alert"});

or just using the defaults:
$("#main h2").contentMenu();

I understand this is basic stuff but it's my first plugin and I'd
love to hear any feedback even if it's "this plugin is not really
interesting/useful/well made enough". I guess my question is: whilst
many people could create something like this easily and quickly
enough, should there be plugins that cover such light tasks anyway?

Thanks and sorry for the long post.
Joel Birch.


___
jQuery mailing list
discuss@jquery.com
http://jquery.com/discuss/





--
Yehuda Katz
Web Developer | Wycats Designs
(ph)  718.877.1325
___
jQuery mailing list
discuss@jquery.com
http://jquery.com/discuss/


[jQuery] My basic navigation plugin

2007-02-27 Thread Joel Birch
Hi jQuerivites,

I'd like to offer up my humble plugin (humble is the key word here)  
to get a sense of if something this basic is of any worth to the  
community. I discussed an earlier version of the plugin briefly on a  
previous thread (Sites Powered by jQuery) and there is an  
implementation of it on my Preshil site (I don't want to post a link  
here as I don't want to seem like I'm spamming it around) which is in  
the Sites Using jQuery list at jquery.com

To summarise, it takes your jQuery object and creates an unordered  
list of links to the elements within the object. If the elements do  
not have an id (needed to provide the links with a href target), a  
unique id is created for it, otherwise it uses the existing id. Get  
something, do something. ;)

An options object can be passed as the only parameter. The options are:
- "head" : this is a string of html to appear above the list of  
links, can be used as a heading for the list, for example.
- "divClass" : this is a space separated string of classes to be  
applied on the div that wraps the entire list and head.
- "aClass" : this is a space separated string of classes to be  
applied to each of the links created.

These options have defaults of course - you can see what they are in  
the code. The whole thing can be styled with CSS as you see fit  
(hence the extra class hooks in the options object) and enhanced  
further with JavaScript. I attached scrolling to the links using the  
aClass as a hook, for example.

I think the (possibly only one) redeeming feature of this plugin over  
the far better and more elaborate navigation aids is that it is so  
simple (at least how I have it styled on the Preshil site) that  
anyone can understand the menu's purpose regardless of how tech-savy  
they are. It's also very lightweight and, as far as CSS styling goes,  
you only really need a background or border on the main div.

The code:

(function($){
$.fn.contentMenu = function(o){
o = $.extend({  "head" : "Some handy links to help you navigate  
this page:",
"divClass" : "contentMenu",
"aClass" : "inPage" }, o || {});
$.cmCount = $.cmCount+1 || 0;
var $list = $("");
$('').append(o.head).append 
($list).insertBefore(this.eq(0));
return this.each(function(i){
this.id = this.id || "menu"+$.cmCount+"-el"+i;
$list.append('Skip  
to '+this.innerHTML+'');
});
};
)(jQuery);

Example of calling the plugin:
$("#main h2").contentMenu({
"head" : "Page navigation:",
"aClass":"scrolls",
"divClass":"alert"});

or just using the defaults:
$("#main h2").contentMenu();

I understand this is basic stuff but it's my first plugin and I'd  
love to hear any feedback even if it's "this plugin is not really  
interesting/useful/well made enough". I guess my question is: whilst  
many people could create something like this easily and quickly  
enough, should there be plugins that cover such light tasks anyway?

Thanks and sorry for the long post.
Joel Birch.


___
jQuery mailing list
discuss@jquery.com
http://jquery.com/discuss/