By the way, here was the "nicer" patch I ended up with for the Toggle
function:

return this.click( jQuery.event.proxy( fn, function( event ) {
       // Figure out which function to execute
       var lastToggle = ( $(this).data( 'lastToggle' + fn.guid ) ||
0 ) % i;
       $(this).data( 'lastToggle' + fn.guid, lastToggle + 1 );

       // Make sure that clicks stop
       event.preventDefault();

       // and execute the function
       return args[ lastToggle ].apply( this, arguments ) || false;
}));

A call to unbind("click") will remove all toggle events.

Earle


On Sep 20, 12:58 pm, Mr Speaker <mrspea...@gmail.com> wrote:
> Hey Michael,
>
> Are you saying that the Toggle functionality isn't broken? I thought
> that Toggle was supposed to work the way your bindsequence and my
> dodgy patch worked?
>
> I like your namespaced event handler approach, and agree about saving
> state in the DOM (I updated my patch to use .data functionality, which
> is a bit nicer) but that's how it's done in Toggle in the core now. I
> was just trying to leave the code as similar to the original as
> possible.
>
> If Toggle is working correctly then I'll happily add my own custom
> functions to work how I need it, but perhaps the documentation should
> be updated to say "adding multiple toggle events to one element
> does..." Actually, if it's working as intended then I'm not sure what
> it does ;)
>
> Earle
>
> On Sep 20, 3:54 am, Michael Geary <m...@mg.to> wrote:
>
> > You know, this is the kind of thing you can write yourself in just a few
> > lines of code, without having to save state in the DOM (which I find
> > distasteful). Here's a standalone version that doesn't do anything tricky
> > like that. The only state it keeps is right there in the function itself.
>
> > While we're at it, we'll make it more general so it can sequence callbacks
> > for any event, and we'll give it a better name. (toggle specifically implies
> > *two* states, not many.)
>
> > $.fn.bindSequence = function( name ) {
> >     var args = arguments, i = 1;
> >     this.bind( name, function( event ) {
> >         args[i].call( this, event );
> >         if( ++i >= args.length ) i = 1;
> >     });
> >     return this;
>
> > };
>
> > You can use it like this:
>
> > $('.testClass').bindSequence( 'click',
> >     function() { console.log( this.className + ' X' ); },
> >     function() { console.log( this.className + ' Y' ); },
> >     function() { console.log( this.className + ' Z' ); }
> > );
>
> > Looking at the toggle() source code, I see that it does some extra work
> > having to do with unbinding. But you don't really need that either. Since
> > bindSequence() lets you pass in the event name, you can bind and unbind like
> > this:
>
> > $('.testClass').bindSequence( 'click.mysequence',
> >     ...
> > );
>
> > $('.testClass').unbind( 'click.mysequence' );
>
> > Here's a test page:
>
> >http://mg.to/jquery/bindsequence.html
>
> > Try the "click me" button several times, and then click the "unbind" button
> > and go back and click the "click me" button again.
>
> > Now you don't have to patch jQuery! :-)
>
> > -Mike
>
> > On Fri, Sep 18, 2009 at 6:40 PM, Mr Speaker <mrspea...@gmail.com> wrote:
>
> > > I recently deadline forced me to make a change to the jQuery core to
> > > fix an issue I was having. Now that I'm refactoring the code, I'd like
> > > to know if I've missed something obvious, or if there's a better way
> > > to do it. I couldn't find any reference to this issue on the forums or
> > > bug tracker.
>
> > > <div id="btnClose" class="icon">Close</div>
>
> > > $(".icon").toggle(
> > >        function(){ $(this).removeClass('two2').addClass('two1') },
> > >        function(){ $(this).removeClass('two1').addClass('two2') }
> > > );
>
> > > $("#btnClose").toggle(
> > >        function(){ $(this).removeClass('one2 one3').addClass('one1'); },
> > >        function(){ $(this).removeClass('one1 one3').addClass('one2'); },
> > >        function(){ $(this).removeClass('one1 one2').addClass('one3'); }
> > > );
>
> > > This doesn't work with jQuery (stable or nightly), as internally the
> > > current toggle state is stored on the DOM node itself as "lastToggle"
> > > and so increments multiple times per click.
>
> > > I had to modify the return statement of the toggle function so that I
> > > could use the proxy guid as part of the counter identifier:
>
> > > var proxy = jQuery.event.proxy( fn, function(event) {
> > >        // Figure out which function to execute
> > >        this[ 'lastToggle' + proxy.guid ] = ( this[ 'lastToggle' +
> > > proxy.guid ] || 0 ) % i;
>
> > >        // Make sure that clicks stop
> > >        event.preventDefault();
>
> > >        // and execute the function
> > >        return args[ this[ 'lastToggle' + proxy.guid ]++ ].apply( this,
> > > arguments ) || false;
> > > })
> > > return this.click( proxy );
>
> > > Which appears to work perfectly (and got me through my deadline ;) but
> > > I'm sure isn't the most elegant way to do it. Am I even supposed to be
> > > able to add multiple toggle event handlers?
>
> > > Thanks!
>
> > > Earle
>
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"jQuery Development" group.
To post to this group, send email to jquery-dev@googlegroups.com
To unsubscribe from this group, send email to 
jquery-dev+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/jquery-dev?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to