JSFiddle - React, Tailwind, and code Playground

by ZooeyLai

HTML

<div id="app">
        <div class="card">
            <div class="card-header">
                <h2>註冊帳戶</h2>
            </div>
            <div class="card-body">
                <form id="siginForm" autocomplete="off">
                    <div class="form-group">
                        <label for="userName" class="form-label">用戶暱稱</label>
                        <input type="text" id="userName" class="form-input" placeholder="請輸入您的暱稱" >
                        <span class="error">不能為空白、必須在40字以內</span>
                    </div> 
                    <div class="form-group">
                        <label for="userMail" class="form-label">Email 信箱</label>
                        <input type="text" id="userMail" class="form-input" placeholder="[email protected]">
                        <span class="error">不能為空白、必須包含 @ 符號</span>
                    </div> 
                    <div class="form-group">
                        <label for="password" class="form-label">密碼</label>
                        <input type="password" id="password" class="form-input" placeholder="請輸入您的密碼">
                        <span class="error">不能為空白、必須在8字以上、必須在100字以內</span>
                    </div> 
                    <button class="btn btn-primary" id="submit" type="submit">註冊</button>  
                </form>
            </div>
        </div>
    </div>

CSS

:root{
        --primary: #4f46e5;
        --secondary:#2563eb;
        --secondary100: #dbeafe;
        --gray800: #333;
        --white: #fff;
        --background:#e4e4e4;
        --warning100 :#ffedd5;
        --warning : #ea580c;
        --danger100 :#fee2e2;
        --danger : #dc2626;
        --success : #059669;
        --success100: #ecfdf5;
    }
    *{
        box-sizing: border-box;
        font-size: 1rem;
        line-height: 1.5;
    }
    body{
        background: var(--background);
        color: var(--gray800);
        font-family: Lato, sans-serif;
    }
    .card{
        width: 480px;
        margin: 40px auto 0;
        padding: 1.5rem;
        background: var(--white);
        border-radius: 0.5rem;
        box-shadow: 0 0 12px rgba(0, 0, 0, 0.15);
    }
    h2 {
        text-align: center;
        margin: 1.5rem 0 2rem;
        font-size: 1.75rem;
    }
    h3{
        font-size: 1.125rem;
        padding: 0.5rem 0;
        border-bottom: 2px solid var(--gray800);
    }

    .form-group{
        margin-bottom: 1rem;
        display: flex;
        flex-direction: column;
    }
    .form-label{
        font-size: 0.875rem;
        margin-bottom: 0.25rem;
        color: #9ca3af;
    }
    ::placeholder { 
        color: #94a3b8;
        opacity: 1;
    }
    .form-input{
        border: 1px solid #cbd5e1;
        padding: 0.5rem 1rem;
        border-radius: 0.25rem;
        color: #475569;
        font-size: 0.875rem;
        /* flex: auto; */
    }
    .form-input:focus{
        border-color: var(--primary);
        box-shadow: 0px 0px 0px 3px rgb(79 70 229 / 40%);
        outline: none;
    } 
    .input-warning{
        border-color: var(--warning);
        background-color: var(--warning100);
    }
    .input-warning:focus{
        border-color: var(--warning);
        box-shadow: 0px 0px 0px 3px rgb(234 88 12 / 40%);
        outline: none;
    }
    .input-danger{
        border-color: var(--danger);
        background-color:...

JavaScript

let form = document.querySelector('#siginForm');
        let userName = document.querySelector('#userName');
        let userMail = document.querySelector('#userMail');
        let password = document.querySelector('#password');

        let forms = document.querySelectorAll('input');
        //點擊input移除所有驗證狀態
        forms.forEach(input =>{
            input.addEventListener('click', function(){
                input.classList.remove('valid');
                input.classList.remove('invalid');
                input.nextElementSibling.classList.remove('visible');
            });
        })
        // 取得input內的值並去除空白
        form.addEventListener('submit', function(event){
            let nameValue = document.querySelector('#userName').value.trim();
            let mailValue = document.querySelector('#userMail').value.trim();
            let passwordValue = document.querySelector('#password').value.trim();
            //阻止表單提交
            event.preventDefault(); 
            //暱稱驗證
            if (nameValue === '' || nameValue.length >= 40){
                userName.classList.add('invalid');
                userName.closest('.form-group').querySelector('.error').classList.add('visible');
            }else{
                userName.classList.add('valid');
            };
            //信箱驗證
            if (mailValue === '' || mailValue.includes('@') === false){
                userMail.classList.add('invalid');
                userMail.closest('.form-group').querySelector('.error').classList.add('visible');
            }else{
                userMail.classList.add('valid');
            };
            //密碼驗證
            if (passwordValue === '' || passwordValue.length < 8|| passwordValue.length > 100){
                password.classList.add('invalid');
                password.closest('.form-group').querySelector('.error').classList.add('visible');
            }else{
                password.classList.add('valid');
            };
        })