0

I have a basic page where you can click on several button to show a popup. In this popup you have different button that onClick event make a div slideUp and show some newContent.

My problem comes from the fact that when you click on the different buttons a class is removed from a and added to the current one. But since remove this class and putting it back is a fast operation my css transition property doesn't have time to notice the modification (i guess) and therefore doesn't play the animation.

My idea to solve this was to put a sleep function be after removing the class so css has time to take effect and then putting it back on another div. BUT it doesn't always work, it gets triggered inconsistantly.

I can't provide any fiddlelink or use SO's snippet thing. I don't have full access to the internet only few website are avialable to me like SO or Microsoft MSDN.

Here's is my html:

<html>
<body>
    <div>       
        <input type="button" style='width : 100px; height: 100px; padding-left: 30px;' value="B2" onclick="removeAll();document.getElementById('customFilterRSp2').style.display='block';"/>
    </div>

    <div id="customFilterRSp2" class="filterRSp" >
        <div class="wraper">
            <div >
                <input type="button" value="Opt1" style = "float: left" onclick="SlideUp(this.parentNode.parentNode,2);"/>

                <input type="button" value="Opt2" style = "float: left" onclick="SlideUp(this.parentNode.parentNode,3);"/>

                <input type="button" value="close" style = "float: right" onclick="closeSlide(this.parentNode);"/>
            </div>
        </div>

        <div id="subCustomFilter3" class="subfilterRSp">
            <div >
                <input type="button" value="SOUS OPT 2" style = "float: left" onclick="SlideUp(this.parentNode.parentNode,3);"/>
                <input type="button" value="close" style = "float: right" onclick="closeSlide(this);"/>
            </div>
        </div>      

        <div id="subCustomFilter2" class="subfilterRSp">
            <div >
                <input type="button" value="SOUS OPT 1" style = "float: left" onclick="SlideUp(this.parentNode.parentNode,2);"/>
                <input type="button" value="close" style = "float: right" onclick="closeSlide(this);"/>
            </div>
        </div>
    </div>

</body>
<html>

CSS:

<style>
.wraper{
    height: 100%
}
.subfilterRSp{
    display : none;
    position : relative;
    margin-left: -20px;
    left : 0;
    width : 100%;
    height : 470px;
    padding : 20px;
    box-shadow : 0 0 10px 0px rgba(50,50,50,0.3);
    background-color : white;
    z-index: 1000;
    overflow: auto;
}
.filterRSp{
    display : none;
    position : relative;
    left : 10%;
    width : 80%;
    height : 400px;
    padding : 20px;
    box-shadow : 0 0 10px 0px rgba(50,50,50,0.3);
    background-color : white;
    z-index: 1001;
    overflow: hidden;
}

.slideUp{
  height: 30px;
  overflow: hidden;
  border-radius: 4px 4px 0 0;
  -webkit-transition: height 0.2s; 
  -moz-transition: height 0.2s; 
  -ms-transition: height 0.2s; 
  -o-transition: height 0.2s; 
  transition: height 0.2s;
    z-index : 1100
}

And the faulty javascript:

<script>
function closeSlide(el){
    el.parentNode.parentNode.style.display = "none";
}

function SlideUp(el, n){
    els = document.querySelectorAll('.slideUp');
    for (var i = 0; i < els.length; i++) {
        els[i].classList.remove('slideUp');
    }   

    els = document.querySelectorAll('.currentSlideUp');
    for (var i = 0; i < els.length; i++) {
        els[i].classList.remove('currentSlideUp');
        els[i].style.display = "none";
    }

    setTimeout(function(){
        el.className += "  slideUp";
        var curEl = document.getElementById('subCustomFilter'+n);
        curEl.className += " currentSlideUp";
        curEl.style.display = "block";

    }, 10);


}

function removeAll(){
    var els = document.querySelectorAll('.subfilterRSp');
    for (var i = 0; i < els.length; i++) {
        els[i].style.display = 'none';
    }   
    els = document.querySelectorAll('.slideUp');
    for (var i = 0; i < els.length; i++) {
        els[i].classList.remove('slideUp');
    }   

    els = document.querySelectorAll('.filterRSp');
    for (var i = 0; i < els.length; i++) {
        els[i].style.display = 'none';
    }

}

To see the problem click between Opt1 and Opt2 it will make divs slideUp and sometimes it will just switch to another div without the animation.

Pooja Kedar
  • 439
  • 2
  • 10
  • 23
user5014677
  • 694
  • 6
  • 22
  • `setTimeout` isn't equal to "sleep", it doesn't block the script execution like "sleep" would. – Teemu Jun 16 '17 at 07:02
  • @Teemu What can i use instead of setTimeout? It's the only thing i can think of to delay an action. – user5014677 Jun 16 '17 at 07:04
  • What is the minimum browser? – Ben Aston Jun 16 '17 at 07:19
  • @BenAston They didn't specify the minimum browser requirements. As long as it doesn't support ONLY the last version of all browsers i guess it's good. They didn't mention any specific browsers. – user5014677 Jun 16 '17 at 07:26
  • Try this delay function https://stackoverflow.com/a/37501951/1268350 – Hemant Kumar Jun 16 '17 at 07:30
  • @HemantArora Doesn't change much. Same issues. The animation doesn't always get triggered. – user5014677 Jun 16 '17 at 07:37
  • Your transition is 20ms. Your "wait" is 10ms. Make it longer than 20ms? – Ben Aston Jun 16 '17 at 07:40
  • @BenAston That's not the problem. The problem is that Between the removal of the class SlideUp and putting it back there's almost no time. The css doesn't notice the changes and doesn't play the transition. I could put 6000ms and it won't play it either if the time between removal and adding it back is the same. You can try it by yourself just copy all the code and put in a html file. The sleep function is a necessity to make it work. + I need the transition to happen fast but still noticable. I don't want to slow down the transition that's not what setTimeOut does. – user5014677 Jun 16 '17 at 07:44
  • I don't have time to dig into your code right now. But: make sure you don't remove or `display: none` elements you want to animate until after the animation. `setTimeout` can help with this. CSS animations take effect when transitioning TO those selector states. So if you have not got an animation style against a selector that remains valid for the duration of the program, then you wont see the animation. e.g if you remove a class leaving the element without a style with an animation, you'll get no animation. – Ben Aston Jun 16 '17 at 07:58
  • @BenAston The slideUp animation is applied to the visible div only. It makes the div height smaller revealing the div "under" it. The div that is shown doesn't have animation. I tried putting back the height of the div that's get slideUp an before applying the class but it doesn't play either without the timeout. – user5014677 Jun 16 '17 at 08:10

0 Answers0