yaakov
yaakov

Reputation: 4645

jquery toggleClass changing only once

I am making a slideshow with jQuery. I'm using jquery ui icons to be the play/pause button and so on. so I have this code:

$(function(){
    $(".controls").hide(); //Hide controls

    $(".slider").hover(function(){
        $(".controls").fadeIn(500);
    }, function(){
        $(".controls").fadeOut(500);
    }); // show controls on hover

    $(".play").click(function(){
        $(".slider").attr({'data-running' : 'true', 'data-paused' : 'false'});
        $(this).toggleClass("ui-icon-play ui-icon-pause play pause");
    });

    $(".pause").click(function(){
        $(".slider").attr({'data-running' : 'false', 'data-paused' : 'true'});
        $(this).toggleClass("ui-icon-play ui-icon-pause play pause");
    }); //Add play/pause functionality

}); 

HTML:

<div class="slider-wrap">
<div class="slider" data-running="false" data-paused="true">
    <img class="starter-img" src="http://images.freeimages.com/images/previews/e16/tree-1533498.jpg" />
    <a href="http://labs.blogs.com/.a/6a00d8341caed853ef016768796ee4970b-pi" role="img-data"></a>
    <a href="http://www.successconnections.com/articles/wp-content/uploads/2013/04/technology.jpg" role="img-data"></a>
    <span class="controls">
        <span class="ui-icon ui-icon-circle-triangle-w prev control"></span>
        <span class="ui-icon ui-icon-play play control"></span>
        <span class="ui-icon ui-icon-circle-triangle-e seek-for control">
    </span>
</div>
</div>

The first time I click on the play button, it switches the data-running attribute to true, the data-paused attribute to false, and it's own class to ui-icon-pause pause, as it should. But when I click it again, it's own class changes, but the data-running and the data-paused don't change. Why aren't the attribute changes being made? FIDDLE

Upvotes: 3

Views: 650

Answers (3)

Lieutenant Dan
Lieutenant Dan

Reputation: 8264

I think I've ran into this issue.

"The problem with jQuery’s Toggle is indeed as you pointed out that it add’s an inline style to the element which does not get removed untill the toggle is triggered again" -https://css-tricks.com/forums/topic/issue-with-jquery-slidetoggle-display-none/

You need to reset the .toggleClass or use .addClass and .removeClass to achieve your effect.

If you don't want to create a reset function for your .toggleClass nor use .addClass / .removeClass you sometimes can getaway with wrapping with a setTimeout function. ie. simple sample below:

$(document).ready(function(){
  $("button").click(function(){
    $(".wrap").toggleClass("fixed");

    setTimeout(function () {
      $('.wrap').toggleClass('shift')
    }, 20);

  });
});

CodePen of above in action. (< you are essentially resetting)

Upvotes: 0

Meenesh Jain
Meenesh Jain

Reputation: 2528

Your classes should be like this , as pause for play and vice versa

 $(".play").click(function(){
    $(".slider").attr({'data-running' : 'true', 'data-paused' : 'false'});
    $(this).toggleClass("ui-icon-play ui-icon-play play");
});

$(".pause").click(function(){
    $(".slider").attr({'data-running' : 'false', 'data-paused' : 'true'});
    $(this).toggleClass("ui-icon-play ui-icon-pause pause");
}); //Add play/pause functionality

Upvotes: 0

epascarello
epascarello

Reputation: 207501

The $(".pause") does not bind when you flip classes. It only finds the elements that are there at that moment in time. Either use event delegation or add logic inside the one click that handles both states.

Event delegation:

$(".controls").on("click", ".play", function(){
    $(".slider").attr({'data-running' : 'true', 'data-paused' : 'false'});
    $(this).toggleClass("ui-icon-play ui-icon-pause play pause");
});

$(".controls").on("click", ".pause", function(){
    $(".slider").attr({'data-running' : 'false', 'data-paused' : 'true'});
    $(this).toggleClass("ui-icon-play ui-icon-pause play pause");
}); //Add play/pause functionality

Better just do it in one since code is 95% the same

$(".controls").on("click", ".play", function(){
    $(this).toggleClass("ui-icon-play ui-icon-pause play pause");
    var isPaused = $(this).hasClass("pause");
    $(".slider").attr({'data-running' : !isPaused, 'data-paused' : isPaused});
});

Upvotes: 2

Related Questions