velocity icon indicating copy to clipboard operation
velocity copied to clipboard

Velocity issue when changing focus before running animation

Open scblason opened this issue 6 years ago • 4 comments

My system information

  • VelocityJS version: 1.5.1
  • Browser: Safari WebView (UIWebView)
  • Operating System: iOS

Checklist

  • Is this an issue with code?: Probably
  • Is this an issue with documentation?: No
  • Have you reproduced this in other browsers?: No
  • Have you checked for updates?: Yes
  • Have you checked for similar open issues?: Yes

I'm using VelocityJS in a ReactJS, building a mobile web and I found an issue related to iOS, the keyboard and the change of (input) focus.

In iOS, using the UIWeView, there is a problem changing the focus to an input (and wanting the keyboard to stay visible) if you are outside of an event started by the user (example: click of a button). A simple example is using a setTimeout to set the focus (focus() not working within setTimeout on iOS, i.e. https://stackoverflow.com/questions/6866433/focus-not-working-within-settimeout-on-ios).

This is clear when there is an animation. I have N divs loaded in the DOM, with only one visible (ordered by z-index). Each div has an input with a "Next" button at the bottom (a kind of form, wizard like) . We are performing a mobile-style animation where the current visible div goes away right-to-left and the next div (in the z-index order) becomes visible in the same way. I perform this by using translateX (and force-feeding) to move the divs in the animation.

If we set the input.focus() (input of the entering div) in the "complete" event of the animation, the keyboard goes away. We are launching the animation in the click event, but the change of focus occurs in a diferente event ("complete" event of velocity).

Now, I tried to do it without the "complete" event. When the button is clicked, before starting any animation, I change the focus to the other div's input. Then, I call velocity on the divs to perform the animation. This works and the keyboard does not get hide. But the problem is, the animation gets broken after playing around (going back and forward, right-to-left and left-to-right between two or any divs).

My code is:

animateForm = (currentIndex, direction) => {

    let nextView = direction === 'left' ? 1 : -1 
    let currentDiv = document.getElementById("div_" + this.props.views[currentIndex].id);
    let divToShowId = this.props.views[currentIndex + nextView].id;
    let divToShow = document.getElementById("div_" + divToShowId);

    this.changeFocus(divToShowId);   

    Velocity(currentDiv, (nextView < 0) ? this.rtlOut : this.ltrOut, {
        duration: NavConfig.TRANSITION_TIME,
        _cacheValues: false,
        begin: () => this.animationBegin(divToShowId, direction),
        complete: () => { 
            this.animationComplete("div_" + divToShowId, "div_" + this.props.views[currentIndex].id);
        },
    });
    Velocity(divToShow, (nextView < 0) ? this.rtlIn : this.ltrIn, {
        _cacheValues: false,
        duration: NavConfig.TRANSITION_TIME
    });
}

This method gets called in the click event. If the this.changeFocus(divToShowId) method get called in the "complete" event (this.animationComplete(..)), there are no problems with the animation and they work just fine (but I have the keyboard issue). If I change the focus before calling the animations, the keyboard keeps open, but the animation starts to misbehave.

Any thoughts? Thanks!

scblason avatar Apr 20 '18 19:04 scblason

Velocity V1 is unsupported except for any major issues that might turn up - can you repeat with the V2 beta and see what the result is. Do note that there are several differences, such as translateX is not valid css, so make sure to use the real transform property instead etc.

Rycochet avatar Apr 22 '18 19:04 Rycochet

Hi @Rycochet, thank you for your response. I tried using the V2 version, but unfortunately I have the same issue. I change the css like you point out (I was using translateX and It does not work in V2). I'm using "left" css now:

    //Animations
    this.rtlOut = { left: '-100%' };
    this.rtlIn = { left: [0, '100%'] };
    this.ltrOut = { left:'100%' };
    this.ltrIn = { left: [0, '-100%'] };

I have the same issue. First, animations works fine: moving 1 element forward in the wizzard (rtl), and then going backwards (ltr). But when I try to go forward again, the animations stop working. I found it really weird, since the first animation going forward works just fine.

Any other thoughts would be really appreciate it. Thanks!

scblason avatar Apr 22 '18 20:04 scblason

Just FYI, you can use {transform: ["translateX(0%)", "translateX(100%)"] in V2 btw - and if you forcefeed both directions that part will be better than trying to disable the cache - don't forget it should always be a string, and that you should be using the same units for both so it's "type safe".

I am wondering if the lack of cache might be part of the issue - that's not really something that should be used manually, and forcefeeding both directions would be safer to do in this situation. If that doesn't make any difference then can you put a demo up on JSFiddle that shows the issue (and I can then check it in the various browsers).

This is far more of a SO question btw, although there is the possibility that it is yet another Safari bug that we might be able to work around.

Rycochet avatar Apr 22 '18 20:04 Rycochet

I'll will try to put out a JSFiddle and let you know @Rycochet. Regarding the cache issue, I put the "cache=false" just to test if that could help, since originally I didn't use it. I'll also try forcefeeding both ways, with the same result.

I'll will add that this issue is not just an iOS problem. You can test this in a Chrome desktop browser and you can see the problem there too. The iOS part of the problem is regarding the change of focus in the animation "complete" event (where the animations does not break).

Thank you, I'll contact you when I get the fiddle done!

scblason avatar Apr 23 '18 00:04 scblason