简体   繁体   中英

Tab order broken with stripe card-element and vue.js

When using Vue.js and having a stripe card-element inside the Vue main element the tabindex is not working properly. Check the following code:

<html>
<head>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://js.stripe.com/v3/"></script>
</head>
<body>
    <input type="text" placeholder="first tab element on page"><br />
    <br />
    <div id="stripeDiv">
        <div id="card-element" style="border: 1px solid black;max-width:300px">
            <!-- A Stripe Element will be inserted here. -->
        </div>
        <div id="card-errors" role="alert"></div>
    </div>    
    <br />
    <input type="text" placeholder="tab element after stripe form"><br />
    <script>
        var stripe = Stripe("somestripepublickey");
        var card = stripe.elements().create('card').mount('#card-element');

        var vue_test = new Vue({
            el: '#stripeDiv'
        });
    </script>
</body>
</html>

When you tab through it, you end up in the top input box right after leaving the stripe fields. You should end up in the bottom input box. When I remove the Vue stuff, it just works.

I know I could use some js with onfocus, but I'd rather not.

PS: no stripe account needed to test this.

You just need to change the order of your Javascript. Mounting the card element does a lot of crazy stuff to the dom.

var stripe = Stripe("somestripepublickey");
var vue_test = new Vue({
  el: '#stripeDiv'
});
var card = stripe.elements().create('card').mount('#card-element');

That should fix your problem though.

I am not using Vue, but the solution I found may apply to your situation as well. In my case, the code to mount #card-element was being called before the DOM was loaded. I fixed by wrapping it in code that waits until the DOM is fully loaded before initializing all the Stripe stuff. Here's an example:

window.addEventListener('load',function() {
    var stripe = Stripe("somestripepublickey");
    var card = stripe.elements().create('card').mount('#card-element');

    var vue_test = new Vue({
        el: '#stripeDiv'
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM