Dogstudio / highway

Highway - A Modern Javascript Transitions Manager

Home Page:https://highway.js.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

from.remove() when the user does not wait for the transition to be completed (with overlap)

Totokoutonio opened this issue · comments

Hello!

I'm using Highway to make overlap transition. Everything works fine but the old page isn't remove if the user click on a link before the end of the transition.

I didn't use gasp (or any other transition library), I use keyframes from my CSS and run from.remove() with a setTimeout. Maybe that's where the problem's coming from?

//main.js
import Highway from './highway.module.js';
import Overlap from './CustomTransition.js';
(() => {
  const H = new Highway.Core({
    transitions: {
      default: Overlap
    }
  });
})();
//CustomTransition.js
import Highway from './highway.module.js';
 class Overlap extends Highway.Transition {
  in({ from, to, trigger, done }) {      
      from.style.position = 'absolute';
      to.style.animation = "overlapTest 1s";            
      let timeremove = setTimeout(() => from.remove(), 1200)      
      done();
  }
  out({ from, done }) {
    done();    
  }
}
export default Overlap;
/*style.css*/
@keyframes overlapTest {
    from{ transform: translateX(100vw); }
    to{transform: translateX(0); }    
}

I have make a demo with a transition of 1s => https://eloquent-heisenberg-124835.netlify.app/

I have also make a repo : https://github.com/Totokoutonio/Highway_Overlap

Thx for helping!

Hey @Totokoutonio

Highway doesn't manage the cancellation of the click event on the links during a transition. That's something we may add in the future. However, you can access all the links used by Highway with H.links and you also have access to the H.attach and H.detach methods.

I believe this is enough to cancel the click event or call the e.preventDefault method on each one of them during the transition before enabling it again when the transition is done. We'll see what we can do as soon as possible to add a fix in the library for this use case but in the meantime you have enough elements to create your own solution with the events available in the Highway.

Keep us in touch when you'll have found a clean solution. That may contribute to the improvement of the library and that may help other members of the community :).

Best regards,
Anthodpnt

Hey @Totokoutonio , just to add another option that I use myself to avoid clicking on another element when navigation already started. Here's what I do :

  • On navigation start : add a class to the body.
  • give pointer-events: none; to that class.
  • Remove that class when navigation ended.

This should prevent clicking on elements while a navigation is running.

Hey @Anthodpnt and @ThaoD5 thanks for your fast answer!

I have use the option with the pointer-events: none in my CustomTransition file. And it's look fine. I set a timer to match the duration of the transition (1s in the demo) and I remove the class in this timer.

//CustomTransition.js
import Highway from './highway.module.js';

class Overlap extends Highway.Transition {
  in({ from, to, done }) {      
      let el = document.querySelector('body');
      el.classList.add('transitions-active');      
      to.style.animation = "overlapTest 1s";            
      function remover(){
          from.remove();
          el.classList.remove('transitions-active');
      }
      let timeremove = setTimeout( remover, 1000)      
      done();
  }
  out({ from, done }) {
    done();
  }
}

export default Overlap;

But do you think using a timer is a good approach?

Thanks for your prompt help and for Highway!

For a cleaner approach, I would advise to use an event like 'transitionend on the element that has your transition animation, that way you're not playing with settimeout, but this is a very personal approach. :)

Glad that solution worked for you !

@ThaoD5 I have use animationend and it works well!

//CustomTransition.js
import Highway from './highway.module.js';

class Overlap extends Highway.Transition {
  in({ from, to, done }) {      
      let el = document.querySelector('body');
      el.classList.add('transitions-active');      
      to.style.animation = "overlapTest 1s";
      to.addEventListener('animationend', () => {
        from.remove();
        el.classList.remove('transitions-active');
      });
      done();
  }
  out({ from, done }) {
    done();
  }
}

export default Overlap;
/*style.css*/
@keyframes overlapTest {
    from{ transform: translateX(100vw); }    
    to{ transform: translateX(0); }    
}

body.transitions-active{
    pointer-events: none;
}

Thanks a lot, I close this issue.