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:
>>
>> $('<div class="'+o.divClass+'"></div>').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" : "<h3>Some handy links to help you navigate
this page:</h3>",
"divClass" : "contentMenu",
"aClass" : "inPage",
"insertMethod" : "insertBefore",
"insertTarget" : this.eq(0) }, o || {});
$.cmCount = $.cmCount+1 || 0;
var $list = $("<ul>");
var lastInd = this.length-1;
var lis = '';
var menu = $('<div class="'+o.divClass+'"></div>').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 += '<li><a href="#'+this.id+'" class="'+o.aClass+'">Skip to
<em>'+$(this).text()+'</em></a></li>';
if (i==lastInd){ $list.append(lis); }
});
};
)(jQuery);
Cheers
Joel.
_______________________________________________
jQuery mailing list
[email protected]
http://jquery.com/discuss/