代码 一个安全支付表单的HTML结构和样式

2025-03-18 17:39:01 +0800 CST views 409

该文本描述了一个安全支付表单的HTML结构和样式,使用Bootstrap框架和FontAwesome图标。表单包括卡持有人姓名、卡号、过期日期和CVV字段,并实现了实时验证功能。JavaScript用于处理表单提交和验证逻辑,确保用户输入有效。整体设计注重用户体验和安全性。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Secure Payment</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
    <style>
        :root {
            --primary-blue: #2563eb;
            --dark-gray: #334155;
            --light-gray: #e2e8f0;
            --error-red: #dc2626;
        }

        body {
            background: #f8fafc;
            min-height: 100vh;
            font-family: 'Inter', system-ui, sans-serif;
        }

        .payment-card {
            max-width: 520px;
            border-radius: 12px;
            box-shadow: 0 4px 24px rgba(0,0,0,0.08);
            background: white;
            border: 1px solid var(--light-gray);
        }

        .form-label {
            font-size: 0.875rem;
            font-weight: 500;
            color: var(--dark-gray);
            margin-bottom: 0.5rem;
        }

        .input-icon {
            position: absolute;
            left: 16px;  /* Increased spacing */
            top: 50%;
            transform: translateY(-50%);
            color: #64748b;
            font-size: 1rem;
        }

        .form-control {
            padding: 0.875rem 1rem 0.875rem 44px;  /* Adjusted padding */
            border-radius: 8px;
            border: 1px solid var(--light-gray);
            transition: all 0.2s ease;
        }

        .form-control:focus {
            border-color: var(--primary-blue);
            box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
        }

        .error-message {
            font-size: 0.75rem;
            color: var(--error-red);
            margin-top: 4px;
            display: none;
        }

        .submit-btn {
            background: var(--primary-blue);
            color: white;
            padding: 1rem 2rem;
            font-weight: 500;
            border-radius: 8px;
            transition: all 0.2s ease;
            position: relative;
        }

        .submit-btn:disabled {
            background: #94a3b8;
            cursor: not-allowed;
        }

        .loading-spinner {
            display: none;
            width: 20px;
            height: 20px;
            border: 3px solid rgba(255,255,255,0.3);
            border-radius: 50%;
            border-top-color: white;
            animation: spin 1s linear infinite;
        }

        @keyframes spin {
            to { transform: rotate(360deg); }
        }

        .payment-brands img {
            height: 28px;
            opacity: 0.6;
            transition: opacity 0.2s ease;
        }
    </style>
</head>
<body class="d-flex align-items-center">
    <div class="container py-5">
        <div class="payment-card mx-auto">
            <div class="p-4">
                <div class="d-flex justify-content-between align-items-center mb-4">
                    <h4 class="mb-0 fw-semibold">Payment Details</h4>
                    <div class="payment-brands d-flex gap-2">
                        <img src="https://upload.wikimedia.org/wikipedia/commons/5/5e/Visa_Inc._logo.svg" alt="Visa">
                        <img src="https://upload.wikimedia.org/wikipedia/commons/2/2a/Mastercard-logo.svg" alt="Mastercard">
                        <img src="https://upload.wikimedia.org/wikipedia/commons/3/30/American_Express_logo.svg" alt="Amex">
                    </div>
                </div>

                <form id="paymentForm">
                    <!-- Cardholder Name -->
                    <div class="mb-4">
                        <label class="form-label">Cardholder Name</label>
                        <div class="position-relative">
                            <i class="fas fa-user input-icon"></i>
                            <input type="text" 
                                   class="form-control"
                                   id="cardholderName"
                                   placeholder="John Doe"
                                   required>
                            <div class="error-message" id="nameError">Please enter valid name</div>
                        </div>
                    </div>

                    <!-- Card Number -->
                    <div class="mb-4">
                        <label class="form-label">Card Number</label>
                        <div class="position-relative">
                            <i class="fas fa-credit-card input-icon"></i>
                            <input type="text"
                                   class="form-control"
                                   id="cardNumber"
                                   placeholder="4242 4242 4242 4242"
                                   maxlength="19"
                                   required>
                            <div class="error-message" id="cardError">Invalid card number</div>
                        </div>
                    </div>

                    <div class="row g-3 mb-4">
                        <!-- Expiration Date -->
                        <div class="col-md-6">
                            <label class="form-label">Expiration Date</label>
                            <div class="position-relative">
                                <i class="fas fa-calendar-alt input-icon"></i>
                                <input type="text" 
                                       class="form-control"
                                       id="expiryDate"
                                       placeholder="MM/YY"
                                       maxlength="5"
                                       required>
                                <div class="error-message" id="expiryError">MM/YY required</div>
                            </div>
                        </div>

                        <!-- CVV -->
                        <div class="col-md-6">
                            <label class="form-label">CVV</label>
                            <div class="position-relative">
                                <i class="fas fa-lock input-icon"></i>
                                <input type="text"
                                       class="form-control"
                                       id="cvv"
                                       placeholder="123"
                                       maxlength="3"
                                       required>
                                <div class="error-message" id="cvvError">3 digits required</div>
                            </div>
                        </div>
                    </div>

                    <button type="submit" class="btn w-100 submit-btn" disabled>
                        <span class="submit-text">Pay $125.00</span>
                        <span class="loading-spinner"></span>
                    </button>
                </form>
            </div>
        </div>
    </div>

    <script>
        const form = document.getElementById('paymentForm');
        const submitBtn = form.querySelector('button[type="submit"]');
        let isSubmitting = false;

        // 实时验证逻辑
        function validateField(field, validateFn, errorElement) {
            field.addEventListener('input', () => {
                const isValid = validateFn(field.value);
                errorElement.style.display = isValid ? 'none' : 'block';
                field.classList.toggle('is-invalid', !isValid);
                updateSubmitButton();
            });
        }

        // 字段验证规则
        const validators = {
            name: value => value.trim().length >= 2,
            card: value => /^\d{16}$/.test(value.replace(/ /g, '')),
            expiry: value => /^(0[1-9]|1[0-2])\/?([0-9]{2})$/.test(value),
            cvv: value => /^\d{3}$/.test(value)
        };

        // 初始化验证
        validateField(document.getElementById('cardholderName'), 
            validators.name, document.getElementById('nameError'));
        
        validateField(document.getElementById('cardNumber'), value => {
            const cleaned = value.replace(/ /g, '');
            return cleaned.length === 16 && /^\d+$/.test(cleaned);
        }, document.getElementById('cardError'));

        validateField(document.getElementById('expiryDate'), 
            validators.expiry, document.getElementById('expiryError'));
        
        validateField(document.getElementById('cvv'), 
            validators.cvv, document.getElementById('cvvError'));

        // 卡号格式化
        document.getElementById('cardNumber').addEventListener('input', function(e) {
            const value = e.target.value.replace(/ /g, '');
            let formatted = value.match(/.{1,4}/g)?.join(' ') || '';
            e.target.value = formatted.substring(0, 19);
        });

        // 更新提交按钮状态
        function updateSubmitButton() {
            const isValid = Object.values(validators).every((validator, index) => {
                const field = form.elements[index];
                return validator(field.value);
            });
            submitBtn.disabled = !isValid || isSubmitting;
        }

        // 表单提交处理
        form.addEventListener('submit', async (e) => {
            e.preventDefault();
            if (isSubmitting) return;

            isSubmitting = true;
            submitBtn.disabled = true;
            submitBtn.querySelector('.submit-text').style.opacity = '0';
            submitBtn.querySelector('.loading-spinner').style.display = 'block';

            try {
                // 模拟API调用
                await new Promise(resolve => setTimeout(resolve, 1500));
                alert('Payment successful!');
            } catch (error) {
                console.error(error);
                alert('Payment failed. Please try again.');
            } finally {
                isSubmitting = false;
                submitBtn.disabled = false;
                submitBtn.querySelector('.submit-text').style.opacity = '1';
                submitBtn.querySelector('.loading-spinner').style.display = 'none';
            }
        });
    </script>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
复制全文 生成海报 支付 前端开发 Web设计

推荐文章

html一些比较人使用的技巧和代码
2024-11-17 05:05:01 +0800 CST
vue打包后如何进行调试错误
2024-11-17 18:20:37 +0800 CST
XSS攻击是什么?
2024-11-19 02:10:07 +0800 CST
Vue中的表单处理有哪几种方式?
2024-11-18 01:32:42 +0800 CST
Python Invoke:强大的自动化任务库
2024-11-18 14:05:40 +0800 CST
初学者的 Rust Web 开发指南
2024-11-18 10:51:35 +0800 CST
JavaScript数组 splice
2024-11-18 20:46:19 +0800 CST
实用MySQL函数
2024-11-19 03:00:12 +0800 CST
MySQL设置和开启慢查询
2024-11-19 03:09:43 +0800 CST
Gin 与 Layui 分页 HTML 生成工具
2024-11-19 09:20:21 +0800 CST
html5在客户端存储数据
2024-11-17 05:02:17 +0800 CST
Web 端 Office 文件预览工具库
2024-11-18 22:19:16 +0800 CST
如何优化网页的 SEO 架构
2024-11-18 14:32:08 +0800 CST
程序员茄子在线接单