Closed faebeee closed 6 years ago
Same problem here.
This isn't link to this repository and its components since I don't use them, I did my own wrapper around the stripe.js script.
It seems something is keeping the focus once the card element got it. No way to get rid of it (blur()
or unmount()
function does not work, it keeps popping even if the parent component has been unmounted...
I confirm this is specific to Safari on iOS, I don't have the problem elsewhere.
I keep digging but some help from you guys would be great @michelle
Thanks
More investigation :
blur()
is triggered on the iframe (since it does not do it by itself) while it has the focus, the keyboard is correctly close and will remain closeI found this problem is already discussed in #161 with a (kind of) workaround from @asolove-stripe
I came to the same conclusion that the iframe
with a different origin is messing up with the main app, and the fix should be in the Stripe.js script itself.
Why are you not fixing it ? This is basically making impossible to use your library on ALL iOS devices, it should be at least mentioned on the documentation page (https://stripe.com/docs/stripe-js) and in the readme of this repository. We should not have to dig in closed (unresolved) issues on github to eventually find something related.
EDIT: @asolove-stripe your workaround on #161 only takes into account the submit of the form. But the keyboard stays open in any other case (ie. when a blur occurs, no matter why).
I'm using something a bit more twisted (not really a fan, but at least it works in every case) :
// With element being a reference to the card element created by stripe.elements()
// or the CardElement component.
element.addEventListener('blur', ev => {
// Apply only as a workaround for Safari on iOS,
// else it will create an infinite loop on the `blur` event.
if (navigator.userAgent.search("iPhone") != -1 &&
navigator.userAgent.search("Version/" != -1)) {
element.focus()
element.blur()
}
// This is mandatory for all browsers
element.getElementsByTagName("iframe")[0].blur()
}
Hi @sylv3r!
Thanks for the note, and sorry for the trouble this has been causing you. We're actively working on a fix internally and will post an update when it's out.
This should now be fixed! Let us know if you're still seeing issues.
We're still seeing this issue. On version 1.6.0 the keyboard persists after the submit action and the app has moved to the next page.
Hi @afholderman I can not reproduce the issue anymore. Could you provide some info on your integration (a code snippet or a link) and the device (iOS / Safari version) you are still seeing the issue with? Is it still broken for you on https://stripe.github.io/elements-examples/ ?
@cweiss-stripe I was able to create a minimal repo and reproduce the issue on an ipad IOS 10.3.3. Once you click pay the keyboard will persist https://codesandbox.io/s/l72l6k779q
Thank you @afholderman I can confirm that I am also seeing this issue with react-stripe-elements and split card* fields on Mobile Safari. (Heads up, that your codesandbox example is transitioning away before the token gets created, but after fixing this the keyboard behavior is still the same)
I'll reopen this PR and we'll post an update here once this is fixed.
@afholderman thanks again for providing the details! This issue should be fixed now, you can check it e.g. here: https://codesandbox.io/s/5x09mrv58n Let me know if it works for you!
@cweiss-stripe we have confirmed the fix in codesandbox and our application, thank you!
I found this issue through a google search. I'm having a similar issue in our private codebase in an input that has some formatting logic. It turned out that our issue was happening because we update the cursor position of the input (using a ref) in componentDidUpdate
, which for some reason causes a random focus event to fire only in iOS. My fix was to just track whether or not the input has focus (and this doesn't and probably shouldn't be part of component state since it doesn't change what gets rendered, just make it a class property or a plain variable in the component's module scope), and only run the cursor updating logic within the componentDidUpdate
if hasFocus === true
and the position needs to be updated.
Just thought I'd throw this in here in case it helps with your issue.
Can somebody please provide more information about how this has been fixed? I have the same issue with vue-stripe-elements and Iām not able to work around it using the information provided above.
Still an issue here, too. The keypad doesn't dismiss but worse is that even if the user dismisses it manually with "Done", it comes back later as they tap around. We're using elements directly -- no react or vue, etc.
Same issue using ember-stripe-elements too.
@granmoe Thanks for sharing your insights!
@LeBenLeBen @jackhair We fixed the issue in the underlying stripe-js, so it should be fixed for all wrapper libraries as well. Do you have an example page where I still can reproduce the issue?
@davebalmer Thanks for reporting this again. I can't reproduce it anymore on e.g. http://stripe.github.io/elements-examples/ Do you have a link to an example or a minimal reproduction where the problem still happens?
@cweiss-stripe Thank you, can confirm this is fixed for us using the ember wrapper.
Which repo reflects the update for reference?
@cweiss-stripe I can still reproduce the problem, but I think I narrowed the cause now. When I submit the form to get the token and then process the payment, I hide the Stripe Element and show a loader instead. In that specific case the bug happens. Here is a minimal reproduction case: https://codesandbox.io/s/0p8q30n30n (see App.vue file where every happens, except the Stripe JS file being included in index.html)
Could you please see if you can fix that case on your side as well or share any hints you would have to work around it? š
@LeBenLeBen Thanks for the example!
After submit, on Mobile Safari, the Stripe Card Element tries to close the keyboard by focusing and blurring a hidden input, which happens asynchronously and takes some time.
In your case, you are removing the Element from the DOM on submit (with the if
-directive that only renders the Element when loading === false
), so the Element can't perform the steps to close the keyboard.
There are a few ways to mitigate this by not removing the Element from the DOM. You could hide it via css or place an item on top of it. Please let me know if that works for you!
@jackhair The change was made to the underlying Stripe.js library, which is not open source.
@cweiss-stripe Actually I use v-show
instead of v-if
to hide the component from the page instead of removing it.
I tried to change the display: none
(added by the v-show) to visibility: hidden
but the result is the same. However if I use opacity: 0
the focus/blur happen and the keyboard is successfully hidden š
I think I have enough information to work around it now, thanks for your help!
Hi to All, I thing you get the separate problem to my, at iOS, maybe somebody can help me with stripe elements, I have use vue-stripe-elemetns and stripe-client packages but still get this on iPhone Safari. When I focus one of element it become to send requests to get some gif from stripe server, but real phone just freezing down. https://drive.google.com/file/d/13zxxwjFw4LKbEGumPRrbgczpMY59L8j2/view?usp=sharing
@cweiss-stripe
@alexander-v-ysbm, I'm seeing the same issue but using the current version of stripe.js directly with no wrapper. Using element.focus()
is causing an infinite loop of alternating blur/focus GET
requests to some gif on q.stripe.com
, like you said. This effectively locks the site. I don't really understand why this is trying to get a gif, but it is sending elements.event.focus
and elements.event.blur
repeatedly as the event
parameter for these requests.
@binomialstew Yikes, that doesn't sound good! I'm looking at our logs and can't seem to find an instance of this happening. I also tried several things in our test pages and couldn't make this happen. Do you have a url or a set of steps that can reliably reproduce it?
@asolove-stripe, thanks for reaching out.
I just looked at this again and realize it was my fault. I'm using a setOutcome()
function both on element change and form submit that uses the element.focus()
method, like this example. When I remove the function on change, there is no infinite loop. It seems there is a change event in iOS on submit that is not triggered in desktop browsers.
Are you all using Firefox on iOS by any chance?
I just had this issue: I would click on an input box, then click 'x' or 'done' on the keyboard, and then whenever I clicked anywhere else the keyboard would pop back up.
The code that simulated it is here
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
</head>
<body>
<div>
<input value="hiya">
</div>
<div>Sup with you???</div>
</body>
</html>
It does not happen on Safari or Chrome.
Summary
The keyboard reopens automatically while clicking around.
iOS 11.2.1 Chrome 64.0.3282.112 Safari
Other information
Steps to reproduce: Can also be reproduced here: https://stripe.github.io/elements-examples/
Done
or the X button