tags:

views:

217

answers:

2

Given the following jquery code..

jQuery.fn.sliding = function () {

    return this.each(function () {

        $(this).bind('ON_CONTENT_CHANGING', function (e) {
            $(this).block({
                overlayCSS: { opacity: 1, color: '#000' },
                timeout: 800
            });
        });

        $(this).bind('ON_CONTENT_CHANGED', function (e) {
            $(this).sliding();
            $(this).unblock();
        });

        var $panels = $(this).find('.scrollContainer > div');
        var $container = $(this).find('.scrollContainer');
        var $resized = $panels.css({ 'width': $(this).width() - 44 });



        // if false, we'll float all the panels left and fix the width 
        // of the container
        var horizontal = true;

        // float the panels left if we're going horizontal
        if (horizontal) {
            $panels.css({
                'float': 'left',
                'position': 'relative' // IE fix to ensure overflow is hidden
            });

            // calculate a new width for the container (so it holds all panels)
            $container.css('width', $panels[0].offsetWidth * $panels.length);
        }

        // collect the scroll object, at the same time apply the hidden overflow
        // to remove the default scrollbars that will appear
        var $scroll = $(this).find('.scroll').css('overflow', 'hidden');

        // handle nav selection
        function selectNav() {
            $(this)
            .parents('ul:first')
                .find('a')
                    .removeClass('selected')
                .end()
            .end()
            .addClass('selected');
        }

        $(this).find('.navigation').find('a').click(selectNav);


        // go find the navigation link that has this target and select the nav
        function trigger(data) {
            var el = $(this).find('.navigation').find('a[href$="' + data.id + '"]').get(0);
            selectNav.call(el);
        }

        if (window.location.hash) {
            trigger({ id: window.location.hash.substr(1) });
        } else {
            $('ul.navigation a:first').click();
        }

        // offset is used to move to *exactly* the right place, since I'm using
        // padding on my example, I need to subtract the amount of padding to
        // the offset.  Try removing this to get a good idea of the effect
        var offset = parseInt((horizontal ? $container.css('paddingTop') : $container.css('paddingLeft')) || 0) * -1;


        var scrollOptions = {
            target: $scroll, // the element that has the overflow

            // can be a selector which will be relative to the target
            items: $panels,

            navigation: '.navigation a',

            // allow the scroll effect to run both directions
            axis: 'xy',

            onAfter: trigger, // our final callback

            offset: offset,

            // duration of the sliding effect
            duration: 500,

            // easing - can be used with the easing plugin: 
            // http://gsgd.co.uk/sandbox/jquery/easing/ 
            easing: 'swing'
        };

        $(this).serialScroll(scrollOptions);
        $.localScroll(scrollOptions);

        scrollOptions.duration = 1;
        $.localScroll.hash(scrollOptions);

    });
};

Then this is the actual html file...

    $('#toggle').toggle(function (e) {
        if ($("#sidebar:animated, #canvas:animated").length) {
            e.preventDefault();
            return;
        }

        $(".ui-sliding").trigger('ON_CONTENT_CHANGING');


        $('#sidebar').hide('slide', { direction: 'right' }, 100, function () {

            $('#canvas').switchClass('span-17', 'span-24', 100, function () {
                $(".ui-sliding").trigger('ON_CONTENT_CHANGED');
                $('#toggle').switchClass('close', 'open');
            });
        })
    },
            function (e) {
                if ($("#sidebar:animated, #canvas:animated").length) {
                    e.preventDefault();
                    return;
                }


                $(".ui-sliding").trigger('ON_CONTENT_CHANGING');

                $('#canvas').switchClass('span-24', 'span-17', 100, function () {
                    $('#sidebar').show('slide', { direction: 'right' }, 100, function () {
                        $(".ui-sliding").trigger('ON_CONTENT_CHANGED');
                        $('#toggle').switchClass('open', 'close');
                    });
                });
            });

Is there any way to prevent the toggle from being fired again if someone clicks while it is performing the function?

I referenced http://stackoverflow.com/questions/2489518/tell-jquery-to-ignore-clicks-during-an-animation-sequence and the technique did not work.

A: 
var toggling = false
$('#toggle').toggle(function() {
if(!toggling)
{
toggling = true;
  // perform something
toggling = false; //or put it in a callback function of animate,show,hide,slide and fade
}
}, function() {
if(!toggling)
{
toggling = true;
  // perform something
toggling = false; //or put it in a callback function of animate,show,hide,slide and fade
}
});
Funky Dude
Nope. That didn't do it. Still crashes if you keep clicking.
Stacey
+2  A: 

You can do something like this, check if anything you animate is animating and cancel if so.

Put this at the top of each toggle function:

if($("#sidebar:animated, #canvas:animated").length) {
  e.preventDefault();
  return;
}
Nick Craver
It still doesn't work like I need it to, but this is still an improvement. It's easy to crash it as it stands now... I wish there was a better way to do this.
Stacey
@Stacey - If you have an example page that I can access, I will take a look.
Nick Craver
Unfortunately I don't have such a page. The problem is that while it changes the other elements sizes, it continues to accept clicks. So if you hammer the element, it just stacks up and crashes everything. I've tried blocking the page with jQuery block UI and it still doesn't work. It keeps taking the clicks.
Stacey
@Stacey - The return code I posted in both functions should stop anything from happening with the clicks, you're saying the animations are still queuing up? (e.g. if you placed an alert after that `if()`, it would fire while animating?)
Nick Craver
Yes. I am saying the animations are continuing to queue up.
Stacey
@Stacey, you have the `if` at the **top** of both of your toggle functions?
Nick Craver
Yes. I have modified my code above to show you what it looks like now. They are still queing up.
Stacey
I updated the code to show the bound events that are being triggered, too.
Stacey
@Stacey - Is this in the same code-block? What wraps those bound events at the end, defining `$(this)`?
Nick Craver
Sorry. I keep forgetting to include all of the information. I've included the jquery.sliding-panel plugin code up there. I'm pretty sure that is where the problem is happening, if I remove any of the calls to that plugin, it works as you have specified.
Stacey
@stacey - Are you calling your plugin before or after the `.toggle()`? Events fire in the order they are bound, so try the toggle first and replace my `return;` with `return false;` and change the `e.preventDefault()` to `e.preventDefault(); e.stopImmediatePropagation();` to cancel it out.
Nick Craver
It worked! Oh wow! What in the world did that do? Thank you so much!
Stacey
@Stacey - Welcome :) Before your other slider code/handlers were still running, now it prevents those handlers from running while still in the animate :)
Nick Craver