joaopereirawd / animatedModal.js

animatedModal.js is a jQuery plugin to create a fullscreen modal with CSS3 transitions. You can use the transitions from animate.css or create your own transitions.
MIT License
962 stars 207 forks source link

Child element animations are not possible, have the fix. #67

Open bjornweb opened 4 years ago

bjornweb commented 4 years ago

Found a bug?

If have a modal that has a child with a SVG checkmark animation. But after closing and re-opening the modal, the checkmark animation triggered the animatedModal.js -> afterClose(), causing the modal to vanish....

Ok after some debugging I know why and I have the solution.

The Why. animatedModal uses the following to bind animationEnd event handlers: id.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', afterClose);

Note: Binded on modal Open & Close.

With one() the event can only be triggered once. But because you bind all the possible events ie webkitAnimationEnd & animationend, the one that has presedence gets fired, but the remaining bind still is connected to the element (modal container).

With event bubbling (event bubbles up the parents until it hits a handler) my checkmark animationEnd event bubbles up until it hits the remaining binded event handler on the modal container. Which causes afterClose() to run.

Solution First I thought to only bind the correct event handler with: (!!window.webkitURL)?'webkitTransitionEnd':'transitionend';

But this maybe has backward compatibility issues?

I took a further look at one(), and this method passes the event. So we can also check the event.target and do a simple id comparison to make sure we have the correct target.

Old

        function afterClose () {
          id.css({'z-index':settings.zIndexOut});
          settings.afterClose(); //afterClose
        }

        function afterOpen () {
          settings.afterOpen(); //afterOpen
        }

Updated

        function afterClose (e) {
          if(e.target.id !== idConc) return;
          id.css({'z-index':settings.zIndexOut});
          settings.afterClose(); //afterClose
        }

        function afterOpen (e) {
          if(e.target.id !== idConc) return;
          settings.afterOpen(); //afterOpen
        }

Now I can use all the css animations I want inside my modal.

beepdigital-jenna commented 4 years ago

This was a massive help! Exactly what I needed, Thank you