开发者

possible reasons chained effects would break a toggle in jquery?

My below toggle() breaks when I uncomment the line $('.comments').slideUp('slow'); in the effects chain on the first half of the toggle.

When I copy this code and the associated CSS and HTML into their own page everything works fine, as to identical pieces of code on the same page that toggle other elements.

I get no errors or anything in firebug, does anyone have any idea why the slideUp() would cause the second half of the toggle() to break?

$('#show_hide_comments').toggle(function()
    {
        //alert('1');
        $('#show_hide_comments').attr('src','images/up.png');

        $('.comments').fadeTo('slow', 0.01, function()
        {
            //$('.comments').slideUp('slow');
        });

    },function()
    {
        $('#show_hide_comments').attr('src','images/down.png');

        $('.comments').slideDown('slow', function()
        {
            $('.comments').fadeTo('slow', 1);
        });
    });

Full code below:

<?

    //include_once '../cookie_factory.php';
    include_once '../connect.php';
?>

<style>


    .comments_container
    {
        position:relative;
        top:240px;
        left:15px;
    }

    .show_hide_comments
    {
        padding-left:10px;
    }
    .comments
    {

        position:relative;
        width:900px;
        background-color:#CCC;
        padding-bottom:10px;

        border-radius:5px;
        -moz-border-radius:5px;
        -webkit-border-radius:5px;

    }


    .new_comment
    {
        position:relative;
        padding-bottom:30px;
        padding-left:10px;
        display:inline;
    }


    .new_comment input 
    {
        font-family:Tahoma;
        font-size:12px;
        width:585px;
        height:25px;
        border-style: solid, 2px;
        border-color:#000;
    }
    .author
    {
        padding-top:15px;
        padding-left:10px;
        display:inline;
    }
    .author input
    {
        font-family:Tahoma;
        font-size:12px;
        width:80px;
        height:25px;
        border-style: solid, 2px;
        border-color:#000;

    }
    .email
    {
        padding-top:15px;
        padding-left:10px;
        display:inline; 
    }
    .email input
    {
        font-family:Tahoma;
        font-size:12px;
        width:155px;
        height:25px;
        border-style: solid, 2px;
        border-color:#000;  
    }
    .comment_check
    {
        position:relative;
        display:inline;
        padding-left:5px;
        top:2px;
    }

    .captcha
    {
        position:relative;
        top:5px;
        display:none;
        padding-left:10px;      
    }

    .captcha_statment
    {

        display:inline;
        font-family:Tahoma;
        font-size:14px;
    }
    .captcha_response
    {
        display:inline;
        padding-left:5px;
    }
    .captcha_response input
    {
        font-family:Tahoma;
        font-size:14px;
        width:50px;;
        height:25px;
        border-style: solid, 2px;
        border-color:#000;
    }
    .captcha_check
    {
        position:relative;
        display:inline;
        padding-left:5px;
        top:2px;

    }
    .captcha_result
    {
        display:inline;
        font-family:Tahoma;
        font-size:14px;
        padding-left:5px;
    }
    .the_comments
    {
        padding-top:10px;
        padding-left:10px;
        font-family:Tahoma;
        font-size:12px;
    }
    .full_comments_toggle
    {
        padding-top:10px;
        font-family:Tahoma;
        font-size:12px;
    }
    .full_comments
    {
        padding-top:10px;
        display:none;
    }

</style>

<script src="jquery-1.4.2.min.js"></script>

<script>

$(document).ready(function()
{
$('#comment').keyup(function()
        {

            // get new length of characters
            var length = $(this).val().length;
            var content = $(this).val();               

            //if the comment field has at least 1 character AND is not the original value then enable the submit button
            if ( length >= 1 && content != "your comment here...")
            {

                $('#comment_check').removeAttr('disabled');
                $('#comment_check').attr('src','images/check.png');


            }
            else if ( length == 0 || content == "your comment here...")
            {
                $('#comment_check').attr('disabled', 'disa开发者_运维技巧bled');
                $('#comment_check').attr('src','images/uncheck.png');
            }
        });

        $('#comment_check').click(function()
        {
            //alert('show captcha');
            $('.captcha').css( 'display', 'inline' );
        });

        //get the captcha value and check to see if it is correct. if it is, submit
        $('#captcha_check').click(function()
        {   

            $('#captcha_check').attr('disabled','disabled');
            $('#captcha_check').attr('src','images/uncheck.png');

            var captcha = $('#captcha_response').val();
            var comment = $('#comment').val();
            var name = $('#name').val();
            var email = $('#email').val();

            //rating = rating.substr(5);

            $.ajax({
                type: "GET",
                url: "ajax/check_captcha.php",
                data: ({ captcha:captcha , comment:comment , name:name , email:email }),
                dataType: "json",
                success: function(data)
                {

                    //alert( data );

                    if( data == 'success')
                    {
                        $('.captcha_result').css('color','black');
                        $('.captcha_result').html('Comment submitted for aproval.');
                    }
                    if( data == 'fail')
                    {

                        $('#captcha_check').removeAttr('disabled');
                        $('#captcha_check').attr('src','images/check.png');

                        $('.captcha_result').css('color','red');
                        $('.captcha_result').html('Uh no...');
                    }

                    //on success set... the average rating.. and yelllow stars
                    //var count = 0;
                }
                ///$(".average").html( "Average rating of " + data[0] + " votes: " + data[1] );
            });
        });

        //$("input, textarea").focus(function()
        //{
            // only select if the text has not changed
        //  if(this.value == this.defaultValue)
        //  {
        //      this.select();
        //  }
        //});

        $("input, textarea").click(function()
        {
            // only select if the text has not changed
            if(this.value == this.defaultValue)
            {
                this.select();
            }
        });


        //toggle to show/hide comments

        $('#show_hide_comments').toggle(function()
        {
            $('#show_hide_comments').attr('src','images/up.png');

            $('.comments').fadeTo('slow', 0.01, function()
            {
                $(this).slideUp('slow',function()
                {
                });
            });
        }, function()
        {
            $('#show_hide_comments').attr('src','images/down.png');

            //alert('wtf');

            $('.comments').slideDown('slow', function()
            {
                $(this).fadeTo('slow', 1, function()
                {
                });
            });
        });


        //toggle to show full comments
        $('#full_comments_toggle').toggle(function() 
        {

            $('#full_comments_toggle').attr('src','images/down.png');

            $('.full_comments').slideDown('slow', function()
            {
                $(this).fadeTo("slow", 1, function()
                {
                });
            });

        }, function() 
        {

            $('#full_comments_toggle').attr('src','images/up.png');

            $('.full_comments').fadeTo('slow',0.01, function() 
            {
                $(this).slideUp("slow", function()
                {
                });
            });
        });
});
</script>



<div class="comments_container">

<div class="show_hide_comments"><img id="show_hide_comments" src="images/down.png" width="19" height="10" alt="Expand" />

    <div class="comments">
        <div class="new_comment_container">
            <div class="new_comment"><input id="comment" name="comment" type="text" value="your comment here..."></div>
            <div class="author"><input id="name" name="name" type="text" value="your name"></div>
            <div class="email"><input id="email" "name="email" type="text" value="your email"></div>

            <div class="comment_check"><input id="comment_check" type="image" src="images/uncheck.png" HEIGHT="16" WIDTH="16" BORDER="0" ALT="Submit Comment!" DISABLED></div>
        </div>   

        <div class="captcha">
            <div class="captcha_statment">Mostly Dirty, Always:</div><div class="captcha_response"><input id="captcha_response" name="captcha_response" type="text" value="" size="5" maxlength="5"></div>
            <div class="captcha_check"><input id="captcha_check" type="image" src="images/check.png" HEIGHT="16" WIDTH="16" BORDER="0" ALT="Submit Captcha!"></div>
            <div class="captcha_result"></div>
        </div>

        <div class="the_comments">
            <?php

                $query = mysql_query("SELECT * FROM comments WHERE approved = 1 LIMIT 3");  

                while($comments = mysql_fetch_array($query))
                {
                    $date = date( 'F jS', strtotime($comments['date']));

                    echo '<div class="comment" id="'.$comments[id].'">'.$date.' - '.$comments[comment].' - '.$comments[name].'</div>';
                }
            ?>

            <div class="full_comments_toggle"><img id="full_comments_toggle" src="images/up.png" width="19" height="10" alt="Expand" />
            <?  
                $query = mysql_query("SELECT * FROM comments WHERE approved = 1 LIMIT 3,10000");    
                $count = mysql_num_rows($query);

                echo 'Show '. $count . ' more comments.';
            ?>

            </div>

            <div class="full_comments">
            <?php

                while($comments = mysql_fetch_array($query))
                {
                    $date = date( 'F jS', strtotime($comments['date']));

                    echo '<div class="comment" id="'.$comments[id].'">'.$date.' - '.$comments[comment].' - '.$comments[name].'</div>';
                }
            ?>
            </div>
        </div>
    </div>


</div>
</div>


You should use this instead of a selector in the callback, like this:

$('#show_hide_comments').toggle(function() {
    //alert('1');
    $('#show_hide_comments').attr('src','images/up.png');

    $('.comments').fadeTo('slow', 0.01, function()
    {
        $(this).slideUp('slow');
    });

},function()
{
    $('#show_hide_comments').attr('src','images/down.png');

    $('.comments').slideDown('slow', function()
    {
        $(this).fadeTo('slow', 1);
    });
});

If you don't do it like this (use a selector), and you have say 10 .comments elements, bad things can happen with the animation queue. You have to remember the callback fires for each animated element, so if 10 .comments fade out, they'll each queue a .slideUp() on each .comments element again, suddently causing 100 animations, not 10.

By using $(this) you're calling .slideUp() for the element that just finished fading out, not any others.


Actually, on second thought, there are animations, they can just be queued, like this:

$('#show_hide_comments').toggle(function() {
  $(this).attr('src','images/up.png');
  $('.comments').fadeTo('slow', 0.01).slideUp('slow');
}, function() {
  $(this).attr('src','images/down.png');
  $('.comments').slideDown('slow').fadeTo('slow', 1);
});

Are you getting the same result if you're adding to the queue immediately like this?


One more note, there's some invalid HTML going on here:

<input id="email" "name="email" type="text" value="your email">

You should remove that extra " before name="email" to avoid other issues :)


For me this works perfectly in Firefox 3.6, Chrome 5 and IE 8 (with and without DOCTYPE, which I'd suggest you also add for many reasons). I took your code and made it static HTML for testing purposes.

If you click it repeatedly in quick succession it will break however but that's because you're not handling the animation queue correctly. It's a good practice to stop() animations. You don't even have to do it repeatedly. If you click it twice really fast you may break it as well.

Also, inside event handlers you generally want to use this to refer to the source of the event (if not the source from the event object) rather than re-selecting, which could have unforeseen (and typically undesired) consequences.

Lastly, animations can be queued directly without using a callback.

Try:

$('#show_hide_comments').toggle(function() {
  $(this).attr('src','images/up.png');
  $('div.comments').stop().fadeTo('slow', 0.01).slideUp('slow');
}, function() {
  $(this).attr('src','images/down.png');
  $('div.comments').stop().slideDown('slow').fadeTo('slow', 1);
});

and tell me what happens.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜