Basti
Basti

Reputation: 686

jQuery function wont work after CSS Class change

I actualy have some trouble with a function after a CSS class change.

Here is my Code.

<html>
<head>
    <title>jQuery Animate Test</title>
    <style>
    .animatebox { width: 300px; margin: auto; height: 50px; background: grey; position: absolute; bottom: 250; padding-left: 10px;}
    .hiddenstuff { opacity: 0; } 
    .boxtitle { font-size: 18px; font-weight: 100;}
    .clear { clear: both;}
    .arrow_up { float: right; margin: 7px 0 0 125px; padding-right: 10px;}
    .arrow_down { float: right; margin: 7px 0 0 125px; padding-right: 10px;}
    p {margin: 15px 0 0 0;}
    </style>
    <script src="jquery-1.8.2.js"></script>

</head>
<body>

<h1>Animate Test</h1>
<div id="content">
<div class="animatebox">
<img class="arrow_up" height="35px" src="arrow_up.png"><p class="boxtitle">Lala Box</p>
<div class="clear"></div>
<p class="hiddenstuff">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata </p>
</div>
</div>


<script>

$(function() {
$('.arrow_up').click(function(){
   $('.arrow_up').attr('src',"arrow_down.png");
});
$('.arrow_up').click(function () {
    $('.arrow_up').addClass('arrow_down');
});
$('.arrow_up').click(function () {
    $('.arrow_up').removeClass('arrow_up');
});
});

$(".arrow_up").click(function () {
    $('.animatebox').animate ({
        height: '250px'
    }, 200 );
});

$(".arrow_up").click(function () {
    $('.hiddenstuff').animate ({
        opacity: '1'
    }, 200 );
});

$(".arrow_up").click(function () {
    $('.boxtitle').animate ({
        fontSize: '28px',
        fontWeight: '700'
    }, 200 );
});

$(".arrow_down").click(function () {
    $('.animatebox').animate ({
        height: '50px'
    }, 200 );

});

$(".arrow_down").click(function () {
    $('.hiddenstuff').animate ({
        opacity: '0'
    }, 200 );
});


$(".arrow_down").click(function () {
    $('.boxtitle').animate ({
        fontSize: '18px',
        fontWeight: '100'
    }, 200 );
});




</script>

</body>
</html>

After clicking the up buttons once it changes the class to "arrow_down", but the function for the down animation wont work then?!? :/

UPDATE

$("body").on("click", ".arrow_up", function () {
        $('.arrow_up').attr('src',"arrow_down.png");
        $('.arrow_up').addClass('arrow_down');
        $('.arrow_up').removeClass('arrow_up');

        $('.animatebox').animate ({
            height: '250px'
        }, 200 );

        $('.hiddenstuff').animate ({
            opacity: '1'
        }, 200 );

        $('.boxtitle').animate ({
            fontSize: '28px',
            fontWeight: '700'
        }, 200 );
    });

    $("body").on("click", ".arrow_down", function () {
        $('.arrow_down').attr('src',"arrow_up.png");
        $('.arrow_down').addClass('arrow_up');
        $('.arrow_down').removeClass('arrow_down');

        $('.animatebox').animate ({
            height: '50px'
        }, 200 );

        $('.hiddenstuff').animate ({
            opacity: '0'
        }, 200 );

        $('.boxtitle').animate ({
            fontSize: '18px',
            fontWeight: '100'
        }, 200 );
    });

Upvotes: 0

Views: 652

Answers (5)

Deep Frozen
Deep Frozen

Reputation: 2075

Since it's dynamic, use on. Also, you can shorten the code some:

$("body").on("click", ".arrow_up", function () {
    $('.arrow_up').attr('src',"arrow_down.png");
    $('.arrow_up').addClass('arrow_down');
    $('.arrow_up').removeClass('arrow_up');

    $('.animatebox').animate ({
        height: '250px'
    }, 200 );

    $('.hiddenstuff').animate ({
        opacity: '1'
    }, 200 );

    $('.boxtitle').animate ({
        fontSize: '28px',
        fontWeight: '700'
    }, 200 );
});

$("body").on("click", ".arrow_down", function () {
    $('.animatebox').animate ({
        height: '50px'
    }, 200 );

    $('.hiddenstuff').animate ({
        opacity: '0'
    }, 200 );

    $('.boxtitle').animate ({
        fontSize: '18px',
        fontWeight: '100'
    }, 200 );
});

You don't need an event handler for every single thing you're going to do. This will be just fine (and probably a bit better with performance)

Here is a working jsFiddle

Upvotes: 1

Sushanth --
Sushanth --

Reputation: 55750

Why do you want to use events on a element that has ever changing class.. Why don't you use a ID instead.. Also there is no need to write up each event seperately.. They can be handled in a single event and with lot less confusion..

I have given the id arrowImg to the Img element..

  $(function() {
    $('#arrowImg').on('click', function() {
        var height = '250px';
        var opacity = '1';
        var fontSize = '28px';
        var fontWeight =  '700';
        if ($(this).hasClass('arrow_up')) {
            $(this).attr('src', "arrow_down.png").toggleClass()('arrow_down').removeClass('arrow_up');
        }
        else {
            height = '50px';
            opacity = '0';
            fontSize = '18px';
            fontWeight ='100';
            $(this).attr('src', "arrow_up.png").addClass('arrow_up').removeClass('arrow_down');
        }

        $('.animatebox').animate({
            height: height
        }, 200);
        $('.hiddenstuff').animate({
            opacity: opacity
        }, 200);
        $('.boxtitle').animate({
            fontSize: fontSize,
            fontWeight: fontWeight
        }, 200);
    });
});​

The code can be more optimized by removing the repetitive lines...

DEMO HERE

UPDATED DEMO

Upvotes: 0

Ahsan Khurshid
Ahsan Khurshid

Reputation: 9469

As Blender stated in his answer

$('.arrow_up') returns the list of all currently present elements with the class of arrow_up. Your .arrow_down elements are being dynamically created, so when you bind the events on page load, those elements aren't actually there.

You'll need to bind the events slightly differently in order to account for dynamically-created elements:

So try the following code:

// Arrow Up Click Event
$('body').on('click', '.arrow_up', function(){

   $('.arrow_up').attr('src',"arrow_down.png");
   $('.arrow_up').removeClass('arrow_up').addClass('arrow_down');

   $('.animatebox').animate ({
        height: '250px'
   }, 200 );

   $('.hiddenstuff').animate ({
        opacity: '1'
   }, 200 );

   $('.boxtitle').animate ({
        fontSize: '28px',
        fontWeight: '700'
   }, 200 );
});

// Arrow Down Click Event
$('body').on('click', '.arrow_down', function(){ 

   $('.arrow_down').attr('src',"arrow_up.png");
   $('.arrow_down').removeClass('arrow_down').addClass('arrow_up');

   $('.animatebox').animate ({
       height: '50px'
   }, 200 );

   $('.hiddenstuff').animate ({
        opacity: '0'
   }, 200 );

   $('.boxtitle').animate ({
        fontSize: '18px',
        fontWeight: '100'
    }, 200 );
});

SEE A SMALL DEMO

Upvotes: 1

Guffa
Guffa

Reputation: 700362

You should bind all the event in the ready event, that way you can put the script in the head.

Don't bind on event for each thing that you want to do, you can do more than one thing in an event handler. Also, you can chain jQuery methods so that you don't have to select the same element over and over.

When you bind events, they are only bound on the elements that exist at that time, so the events for .arrow_up won't be bound as there are no such elements when the code runs. To handle events for elements that changes, you need to use a delegate instead of binding the event on the element. You bind the delegate on an element that doesn't change, like the .animatebox element.

$(function() {

  $('.animatebox').on('click', '.arrow_up', function(){
    $('.arrow_up').attr('src',"arrow_down.png").addClass('arrow_down').removeClass('arrow_up');
    $('.animatebox').animate ({
      height: '250px'
    }, 200 );
    $('.hiddenstuff').animate ({
      opacity: '1'
    }, 200 );
    $('.boxtitle').animate ({
      fontSize: '28px',
      fontWeight: '700'
    }, 200 );
  });

  $('.animatebox').on('click', '.arrow_down', function () {
    $('.animatebox').animate ({
      height: '50px'
    }, 200 );
    $('.hiddenstuff').animate ({
      opacity: '0'
    }, 200 );
    $('.boxtitle').animate ({
      fontSize: '18px',
      fontWeight: '100'
    }, 200 );
  });

});

Upvotes: 0

Blender
Blender

Reputation: 298196

$('.arrow_up') returns the list of all currently present elements with the class of arrow_up. Your .arrow_down elements are being dynamically created, so when you bind the events on page load, those elements aren't actually there.

You'll need to bind the events slightly differently in order to account for dynamically-created elements:

$('body').on('click', '.arrow_down', function() {
  ...

$('body').on('click', '.arrow_up', function() {
  ...

Upvotes: 1

Related Questions