You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript重复密码验证场景下label标签被移除问题排查

注册页重复密码模块验证逻辑异常

问题表现

  • 正常运行场景:注册操作时,先在「密码」输入框输入内容(无论是否满足8位长度要求),再在「重复密码」输入框输入内容会触发黄色背景错误提示,提示位于输入框上方、「Repeat Password」标签下方。两次输入密码一致时(无论第一个密码是否合法),黄色错误提示正常移除,「Repeat Password」标签保留;表单提交时触发的重复密码错误逻辑也可正常运行。
  • 异常场景:
    1. 「重复密码」与「密码」输入框均为空时,「Repeat Password」标签会消失;比如所有字段留空点击提交,「Repeat Password」标签直接消失,也不会展示黄色错误提示。
    2. 所有输入均合法,表单提交重置后,「Repeat Password」标签同样会消失。

相关代码

JavaScript验证逻辑

/* Register Validation */
function checkField(field) {
    if (!field.checkValidity()) {
        addError(field);
    } else {
        removeError(field);
    }
}   
function checkMatch() {
    const registerForm = document.getElementById("register-form");
    const passwordOneInput = registerForm.passwordone;
    const passwordTwoInput = registerForm.passwordtwo;
    if (passwordOneInput.value !== passwordTwoInput.value) {
        if (passwordTwoInput.previousElementSibling &&
            passwordTwoInput.previousElementSibling.className === 'error') {
                // error message already showing
            return;
            }
        const error = document.createElement('div');
        error.innerHTML = passwordTwoInput.dataset.errorMsg;
        error.style.backgroundColor = 'yellow';
        error.style.borderRadius = '0.2em';
        error.style.width = 'fit-content';
        error.className = 'error';
        passwordTwoInput.parentNode.insertBefore(error, passwordTwoInput);
    } else {
        passwordTwoInput.previousElementSibling.remove();
    }
}
 function addError(field) {
    if (field.previousElementSibling &&
        field.previousElementSibling.className === 'error') {
            // error message already showing
        return;
        }
    const error = document.createElement('div');
    error.innerHTML = field.dataset.errorMsg;
    error.style.backgroundColor = 'yellow';
    error.style.borderRadius = '0.2em';
    error.style.width = 'fit-content';
    error.className = 'error';
    field.parentNode.insertBefore(error, field);
}
function removeError(field) {
    if (field.previousElementSibling &&
        field.previousElementSibling.className === 'error') {
        field.previousElementSibling.remove();
    }
}
window.addEventListener('load', function(e) {
    const registerForm = document.getElementById("register-form");
    const emailInput = registerForm.emailregister;
    emailInput.dataset.errorMsg = 'Enter a valid email address';
    const passwordOneInput = registerForm.passwordone;
    passwordOneInput.dataset.errorMsg = 'Password must be at least 8 characters';
    const passwordTwoInput = registerForm.passwordtwo;
    passwordTwoInput.dataset.errorMsg = 'Password does not match';
    const termsInput = registerForm.terms;
    termsInput.dataset.errorMsg = 'You must check the box to proceed'; 
    emailInput.addEventListener('input', function(e) {
        checkField(emailInput);
    });
    passwordOneInput.addEventListener('input', function(e) {
        checkField(passwordOneInput);
    });
    passwordTwoInput.addEventListener('input', function(e) {
        checkMatch();
    });
    termsInput.addEventListener('input', function(e) {
        checkField(termsInput);
    });
    registerForm.addEventListener('submit', function(e) {
        checkField(emailInput);
        checkField(passwordOneInput);
        checkMatch();
        checkField(terms);
        if (!registerForm.checkValidity()) {
            e.preventDefault();
            alert('Please fix form errors.');}
        else {registerForm.submit;
            registerForm.reset();
        }
    });
});

页面HTML代码

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="stylesheet" href="../normalize.css">
<link rel="stylesheet" href="index-styles.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.3/css/all.css" 
      integrity="sha384-SZXxX4whJ79/gErwcOYf+zWLeJdY/qpuqC4cAa9rOGUstPomtqpuNWT9wdPEn2fk" crossorigin="anonymous">
<script src="login.js"></script>
<title>Play2Learn Login</title>
</head>
<body>
    <header>
        <h1><img src="logo.png" alt="logo"></h1>
        <nav>
            <ul>
                <li><a class="border" href="index.html">Home</a></li> 
                <li id="games-li"><a class="border" href="#">Games</a> 
                    <ul id="games-ul">
                        <li><a href="games/anagram-hunt.html">Anagram Hunt </a></li>
                        <li><a href="games/math-facts.html">Math Facts Practice</a></li>
                    </ul>
                </li>
                <li><a class="border" href="about.html">About</a></li> 
                <li><a href="login.html">Login </a></li> 
            </ul>
        </nav>
    </header>
<main>
    <div id="login-div" class="form-div">
        <h2>Log In</h2>
            <article id="article3">
                <form id="login-form" method="post" action="javascript:alert('Form Submitted. You are now logged in.')" novalidate>
                    <div>
                        <label for="emaillogin">Email:</label>
                        <input type="email" name="emaillogin" id="emaillogin" size="25" required>
                    </div>
                    <div>
                        <label for="passwordlogin">Password:</label>
                        <input type="password" name="passwordlogin" id="passwordlogin" size="25" minlength="8" required>
                    </div>
                    <div>
                        <a href="#" id="login-toggle">Need an account? Register</a>
                    </div>
                    <div>
                        <input type="submit" name="login-submit" id="login-submit" value="Login">
                    </div>
                </form>
            </article>
    </div>
    <div id="register-div" class="form-div">
        <h2>Register</h2>
            <article id="article3">
                <form id="register-form" method="post" action="javascript:alert('Form Submitted. Check your email to complete registration.')" novalidate>
                    <div>
                        <label for="emailregister">Email:</label>
                        <input type="email" name="emailregister" id="emailregister" size="25" required>
                    </div>
                    <div>
                        <label for="passwordone">Password:</label>
                        <input type="password" name="passwordone" id="passwordone" minlength="8" size="25" required>
                    </div>
                    <div>
                        <label for="passwordtwo">Repeat Password:</label>
                        <input type="password" name="passwordtwo" id="passwordtwo" minlength="8" size="25" required>
                    </div>
                    <div>
                        <input type="checkbox" name="terms" id="terms" required>
                        <label for="terms" class="required">
                            I am at least 8 years old.</label>
                        
                    
                    </div>
                    <div>
                        <a href="#" id="register-toggle">Already have an account? Login</a>
                    </div>
                    <div>
                        <input type="submit" name="register-submit" id="register-submit" value="Register">
                    </div>
                </form>
            </article>
    </div>
</main>
<footer>
    <div class="footer">
        &#169 2021 Play2Learn
        <a href="contact-us.html" title="Contact Us"><i class="fas fa-envelope-square"></i></a>
        <a href="https://instagram.com" title="Instagram"><i class="fab fa-instagram-square"></i></a>
        <a href="https://twitter.com" title="Twitter"><i class="fab fa-twitter-square"></i></a>
        <a href="https://facebook.com" title="Facebook"><i class="fab fa-facebook-square"></i></a>
    </div>
</footer>
</body>
</html>

问题原因与修复方案

根因

checkMatch函数的else分支没有判断被移除的元素是否是错误提示元素,直接删除了重复密码输入框的前一个相邻元素。当两个密码输入框都为空时,二者值相等会进入else分支,此时重复密码输入框的前一个元素就是「Repeat Password」标签,会被误删。

修复代码

只需要修改checkMatch函数的else分支,增加和removeError一致的判断逻辑即可:

function checkMatch() {
    const registerForm = document.getElementById("register-form");
    const passwordOneInput = registerForm.passwordone;
    const passwordTwoInput = registerForm.passwordtwo;
    if (passwordOneInput.value !== passwordTwoInput.value) {
        // 原有逻辑保持不变
        if (passwordTwoInput.previousElementSibling &&
            passwordTwoInput.previousElementSibling.className === 'error') {
            return;
        }
        const error = document.createElement('div');
        error.innerHTML = passwordTwoInput.dataset.errorMsg;
        error.style.backgroundColor = 'yellow';
        error.style.borderRadius = '0.2em';
        error.style.width = 'fit-content';
        error.className = 'error';
        passwordTwoInput.parentNode.insertBefore(error, passwordTwoInput);
    } else {
        // 修改部分:仅当前一个元素是错误提示时才删除
        if (passwordTwoInput.previousElementSibling &&
            passwordTwoInput.previousElementSibling.className === 'error') {
            passwordTwoInput.previousElementSibling.remove();
        }
    }
}

内容的提问来源于stack exchange,提问作者Hawkins.bp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 19:27:04