开发者

If submit button is clicked too quickly after its previous click, my jquery protection against it breaks

开发者 https://www.devze.com 2023-03-29 15:01 出处:网络
I have a survey-type \'form\'. What the user votes on changes, but the input stays the same. After they press submit, among other things, the new thing the user gets to vote on is to be loaded. If the

I have a survey-type 'form'. What the user votes on changes, but the input stays the same. After they press submit, among other things, the new thing the user gets to vote on is to be loaded. If the submit button is pressed at a low frequency, my program work开发者_运维百科s fine. However, if it is pressed too quickly, my program breaks. I am confused as to why that is, since I have played around with enabling/disabling the button at particular times in my code.

Here is an excerpt of my HTML:

<button id='submit-vote' disabled='disabled'>Submit</button>
<element class='change'><INPUT id='hidden_id' TYPE='hidden' name='id' value='<?php echo $id; ?>'/></element>

Here is script from my jquery (I don't know if this matters, but this is all written in between </body> and </HTML> tags, and not in between the <head> and </head> tags.):

    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">
    $(document).ready(function(){
        $("#submit-vote").attr("disabled", false).data('disabled', false);
    });

    function loadListing()
    {
        var id = $('input:hidden[name=id]').val();
        $.get("controller.php",{/* [relevant values]*/}, 
        function(data)
        {
            if(data.response == 'success')
            {
                //some code
                var newId = $("<INPUT id='hidden_id' TYPE='hidden' name='id' value='"+data.id+"'/>");
                $('#hidden_id').replaceWith(newId);
                return true;
            }
            else
            {
                //some code
                return false;
            }
        }, "json");
    }
    jQuery(function($){
        $("#submit-vote").click( 
            function(){ 
                if($(this).data('disabled') !== false )
                {
                    return;
                }
                else
                {
                    $(this).attr('disabled', true).data('disabled', true);
                    $.post('controller.php', {/*[relevant values]*/} , 
                    function(data)
                    {
                        if(data.response == 'success')
                        {
                            //code
                            loadListing();
                            $('#submit-vote').attr('disabled', false).data('disabled',false);
                            return true;
                        }
                        else
                        { 
                            //code
                            $('#submit-vote').attr('disabled', false).data('disabled',false)
                            return false; 
                        } 
                    }, "json"); 
                }
            }
        );
    });
    </script>

EDIT: (I have updated my jquery to include code from the 1st answer to this question, and I have also included a bit more of my html).

Here is my 'controller.php' excerpt. I have edited a lot of stuff out of it, so as only to include the important stuff. The important thing to know is that all of this usually works perfectly fine unless the submit button click is clicked very very frequently.:

if(!isset($_POST['poll']) && !isset($_GET['newListing'])) //UPON PAGE LOAD
{
    $activities = Activity::newActivitiesArrays($user_id);
    $_SESSION['activities'] = $activities;
    //more relevant code
    include('view.php');
}
if(isset($_POST['poll']) && !isset($_GET['newListing'])) //submitting vote
{   
    //relevant code using posted values
    $res = Activity::vote($user_id, $id, $vote);
    if( !$res )
    {
        echo json_encode(array("response"=>"fail"));
    }
    else
    {
        echo json_encode( array("response"=>"success"));
    }
}
if(isset($_GET['newListing']) && isset($_GET['id'])) //getting something different to display
{
    $id = $_GET['id'];
    $activities = $_SESSION['activities'];
    list($acts, $links, $ids) = $activities;
    $keys = array_keys($ids, $id);
    $key=$keys[0];
    if(!$key)
    {
        echo json_encode( array("response"=>"failure"));
    }
    else
    {
        //relevant code
        unset($_SESSION['activities']);
        $_SESSION['activities'] = $activities;
        echo json_encode( array("response"=>"success"));
    }
}

Any help/suggestions appreciated.


A button with the property disabled="disabled" will still fire a click event. You need to assign a variable so the script knows that it is disabled. I recommend using data()

        $(function(){
             //The button should be enabled only as soon as the page is ready.
            $("#submit-vote").attr("disabled", false).data("disabled", false);

            $("#submit-vote").click( 
                function(){ 
                    if($(this).data('disabled') !== false)
                    {
                        return;
                    }
                    else
                    {
                        $(this).attr('disabled', true).data('disabled',true); //disable the button

                        $.post('controller.php', {/* [RELAVANT VALUES] */ } , 
                        function(data)
                        {
                            if(data.response == 'success')
                            {
                                //some code
                                $('#submit-vote').attr('disabled', false).data('disabled',false); //enable button
                                return true;
                            }
                            else
                            { 
                                //some code
                                $('#submit-vote').attr('disabled', false).data('disabled',false); //enable button
                                return false; 
                            } 
                        }, "json"); 
                    }
                }
            );
        });

Docs: http://api.jquery.com/data/


basically you are running into a race condition of some sort.. please read this post for more deatails abt achieving mutual exclusion in JS http://www.developer.com/lang/jscript/article.php/3592016

0

精彩评论

暂无评论...
验证码 换一张
取 消