When clicking the tab very fast two tab's got Selected

1.5k Views Asked by At

When try to click the tabs very fast two tabs got Selected in Jquery SmartWizard.js plug-in i tried this way but no luck any one experienced this... and also tried .on /.off events no luck.

$($this.steps).bind("click", function (e) {

    //e.stopImmediatePropagation();       
    $($this.steps).unbind("click");

    if ($this.steps.index(this) == $this.curStepIdx) {

        return false;
    }
    var nextStepIdx = $this.steps.index(this);
    var isDone = $this.steps.eq(nextStepIdx).attr("isDone") - 0;
    if (isDone == 1) {
        _loadContent($this, nextStepIdx);
    }

    $($this.steps).bind("click");
    return false;
});
5

There are 5 best solutions below

0
On BEST ANSWER

hi guy's thank you for your efforts i solved the issue by blocking the UI using UI block plugin

$($this.steps).on("click", function (e) {

    e.preventDefault();
    e.stopImmediatePropagation();
    if ($(this).attr('class') !== 'disabled' && $(this).attr('class') !== 'selected' && $(this).attr('class') !== 'error') {

        $('div.swMain').block({ message: "Processing..." });
    }

    try {

        if ($this.steps.index(this) == $this.curStepIdx) {

            $('div.swMain').unblock();
            return false;
        }

        var nextStepIdx = $this.steps.index(this);
        var isDone = $this.steps.eq(nextStepIdx).attr("isDone") - 0;
        if (isDone == 1) {           
            e.preventDefault();
            _loadContent($this, nextStepIdx);

        }
    }
    catch (e) {

        $($this.steps).on("click");
        console.log("Fast click Error ===>   " + e);
    }


    if ($(this).attr('class') !== 'disabled' && $(this).attr('class') !== 'selected' && $(this).attr('class') !== 'error') {

        $('div.swMain').unblock();
    }

    return false;
});
8
On

Maybe set a global variable and check if the global variable is true? You could set a short delay with the built-in javascript delay() function for just a very small period of time after clicking. For example,

go=true;
onclick:
    go=false;
    delay(100, some filler event);
    go=true;

EDIT: this link might help: http://ejohn.org/blog/how-javascript-timers-work/

EDIT: try this in jQuery:

$('id').click(function() {return false;});

Then set a delay and set it back.

EDIT: this seems to work for me. Notice if you click the link twice with a small delay, it'll only flash once. Unless you spam the button about 10 times really quickly, it works fine. (Using latest Chrome btw)

EDIT: http://jsfiddle.net/ZDHZv/2/ works fine for me. If you use that method for tabs, then it's impossible to get double selects. Implement that with whatever plugin you're using with $('.selected')

1
On

I usually do something like this:

var selection;
$('a').click(function () {
    if (selection !== undefined) {
        selection.removeClass('selected');
    }
    selection = $(this);
    selection.addClass('selected');
});

http://jsfiddle.net/ZDHZv/7/

But it occurred to me that you could also do this, assuming all the tabs were siblings and nothing else was:

$('a').click(function () {
    $(this).addClass('selected');
    $(this).siblings().removeClass('selected');
});

http://jsfiddle.net/ZDHZv/9/

2
On

After I readed your 400+ lines of source code, I think I know where the problem is.

It is in the function _loadContent. Content loading is asynchronous because of ajax, and you set selected after ajax loading.

So the next tab can be selected when the previous tab is loading although its click is finished.

I get two answers for you.

  1. Make the ajax synchronized.Like

    var ajax_args = {
        ...
        async : false,
        ...
    

    It can promise the order of selected and all. But, as you know, it will forced user waiting until content loading finished too.

  2. Set selected immediately, and set error style after.Like

    ...
    var stepNum = stepIdx + 1;
    _showStep($this, stepIdx);// add this to set selected immediately.
    if (ajaxurl && ajaxurl.length > 0) {
        if ($this.options.contentCache && hasContent) {
            return; // remove this and other _showStep calls.
        } else {
            var ajax_args = {
                ...
                error : function() {
                    $this.loader.hide();
                    $this.showError(stepIdx);// show error.
                },
                ...
    

    Order of selected will be ok. But ajax loading and error style will become asynchronous.

It is your call.

1
On

You can try something like this:

var process = false;
$($this.steps).bind("click", function (e) {
    if (process) {
        return false;
    }
    process = true; 

    if ($this.steps.index(this) == $this.curStepIdx) {

        return false;
    }
    var nextStepIdx = $this.steps.index(this);
    var isDone = $this.steps.eq(nextStepIdx).attr("isDone") - 0;
    if (isDone == 1) {
        _loadContent($this, nextStepIdx);
    }
    process = false;
    return false;
});