简体   繁体   中英

Why this jQuery code works only for one Iteration?

Basically I have a drop icon, which should expand and collpase an area beneath it. It changes the background position and points downwards and shows some content.On click again it collapses the content and changes the background position. below is what i have written but it doesn't work properly.

$(function() {
    $(".aclass").live('click' , function() {
        $(this).css("background-position","-156px -42px").addClass("new");

        $(".blockedDiv").hide();
        $(".mystery").css("max-height","189px");
    });

    $(".new").live('click', function() {
        $(this).css("background-position","0px 0px");
        $(".blockedDiv").show();
        $(".mystery").css("max-height","1007px");
    });
});

My two questions: 1: Why is this working only for one Iteration 2: Is there a better way to achieve this.

You're not removing the new class you added. Because of that, when you click on it again, the second event handler fires as well, reversing what the first event handler did.

As a side note-slash-tip, what you want is to specify explicit CSS rules, which you can toggle with jQuery, so that you don't have to muck through (relatively) complicated logic.

.mystery { max-height:10007px; }
.mystery.flagged { max-height:189px; }

.aclass { background-position:0 0; }
.aclass.flagged { background-position:-156px -42px; }

then in your jQuery:

$('.aclass').live('click', function () {
    $('.mystery').toggleClass('flagged');
    $(this).toggleClass('flagged');
    $('.blockedDiv').toggle();
});

Richard has already pointed out the problem with your code already. You need to toggle the new class.

A cleaner way to this is probably using the toggleClass() jQuery function.

You define two CSS classes:

.hiddenDiv {...}
.expandedIcon {...}
.collapsedIcon {...}

And JS:

$(function(){
   $(".aClass").click(function(){
         $(".blockDiv").toggleClass("hiddenDiv");
         $(this).toggleClass("expandedIcon");
         $(this).toggleClass("collapsedIcon");

    });
})

And in your HTML, have something like:

<div class="aClass collapsedIcon"> </div> <!-- initially collapsed -->
<div class="blockDiv hiddenDiv"> </div> <!-- initially hidden -->

Here is a slightly different way of doing it that should work.

$(function() {
    $(".aclass").live('click' , function() {
        var $this = $(this), // cache the result of the function to prevent recreating it each time
            is_expanded = $this.hasClass('new');
        $this.css({'background-position': (is_expanded ? '-156px -42px' : '0px 0px')});
        $('.mystery').css({'max-height': (is_expanded ? '189px' : '1007px')});
        if (is_expanded) {
            $('.blockedDiv').show();
            $this.removeClass('new');
        } else {
            $('.blockedDiv').hide();
        }
        $this.addClass('new'); // won't do anything if it already has the class
    });
});

EDIT: As @Richard Neil Ilagan mentioned, you (and I) forgot to remove the new class.

It's working just fine. jsFiddle

Click ".aclass" and it will: 1) set the background-position of 'this' 2) add the class "new" (which makes it a target for BOTH handlers now) 3) hide a different thing .blockedDiv 4) set the max-height of .mystery

Click ".new" and it will: 1) set the background-position of 'this' 2) show a different thing .blockedDiv 3) set the max-height of .mystery

What did you intend for it to do? Maybe you wanted to remove the class .aclass int he first handler, and do the opposite in the second (add .aclass remove .new)?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM