Vanilla JS年龄验证模态框:正确输入后无法关闭问题求助
年龄验证模态框无法正常关闭的问题
我用Vanilla JS开发年龄验证模态框,目前能检测到未满18岁的情况并显示「Invalid Credentials」错误,但输入正确年龄后无法关闭模态框,求带解释的解决方案。
我的JS代码
const modal = document.getElementById("myModal"); const form = document.querySelector('form'); const loading = document.getElementById("loading"); const btnSubmit = document.getElementById('btnSubmit'); // 点击模态框外部关闭 window.onclick = function(event) { if (event.target == modal) { modal.style.display = "none"; } }; // 输入验证函数 function onlyNumbers(e) { const ageGate = document.querySelectorAll('.ageGate'); const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; const errMsgDiv = document.getElementById('errorMsg'); let containsNumber = false ageGate.forEach(input => { if(numbers.some(num => input.value.includes(num))) containsNumber = true; }) if (containsNumber || ageGate.value !== numbers && ageGate.value == '' || ageGate[2].value < 2004) { let paragraph = document.createElement('p'); paragraph.innerHTML = 'Invalid Credentials'; errMsgDiv.append(paragraph); e.preventDefault() } else if (containsNumber = true) { btnSubmit.remove() loading.classList.remove('hide') } };
模态框HTML代码
<div id="modal"> <div class="modal-content"> <div class="flex-container"> <div> <img src="{% static 'imgs/Fireball_logo.png' %}" class="logo" alt="fireball logo" /> <h1>WOAH THERE!</h1> <p class="info-text">We just need to see something</p> </div> <form action=""> {% csrf_token %} <div class="form-flex"> <input class="ageGate" type="text" max-length="2" placeholder="DD" /> <input class="ageGate" type="text" max-length="2" placeholder="MM" /> <input class="ageGate" type="text" max-length="4" placeholder="YYYY" /> </div> <p class="cookie-policy"> <small> This site uses cookies. Cookie Policy. I agree to the terms of use, and the privacy policy. This information will not be used for marketing purposes </small> </p> <div class="text-center"> <button id="btnSubmit" class="btn" type="submit"> <p class="btn-text">Enter</p> </button> <img src="{% static 'imgs/spinner.gif' %}" alt="spinner" id="loading" class="loading close"> </div> <span id="errorMsg"></span> </form> <div> <img src="{% static 'imgs/Drinkaware_logo.png' %}" alt="Drinkaware Logo" /> </div> </div> </div> </div>
问题分析与修复方案
1. 核心问题梳理
你的代码存在3个关键问题导致验证通过后无法关闭模态框:
- 模态框ID不匹配:HTML里模态框ID是
modal,JS里写的是myModal,根本获取不到目标元素 - 验证逻辑混乱:
containsNumber = true是赋值而非比较操作,且年龄仅判断年份<2004,未考虑月日(比如2004年12月出生的用户可能还未满18) - 未添加验证通过后的关闭逻辑:没有在合法年龄分支里写关闭模态框的代码
2. 修复后的完整JS代码
const modal = document.getElementById("modal"); // 修正ID匹配问题 const form = document.querySelector('form'); const loading = document.getElementById("loading"); const btnSubmit = document.getElementById('btnSubmit'); const errMsgDiv = document.getElementById('errorMsg'); // 点击模态框外部关闭 window.onclick = function(event) { if (event.target === modal) { modal.style.display = "none"; } }; // 统一错误提示函数 function showError(msg) { errMsgDiv.innerHTML = ''; // 每次提交清空旧错误 const errP = document.createElement('p'); errP.textContent = msg; errMsgDiv.appendChild(errP); } // 表单提交处理函数 function handleAgeCheck(e) { e.preventDefault(); // 先阻止默认表单提交 errMsgDiv.innerHTML = ''; // 获取并格式化输入值 const [dayInput, monthInput, yearInput] = Array.from(document.querySelectorAll('.ageGate')).map(i => i.value.trim()); // 1. 验证输入格式是否合法 const isDayValid = /^\d{2}$/.test(dayInput); const isMonthValid = /^\d{2}$/.test(monthInput); const isYearValid = /^\d{4}$/.test(yearInput); if (!isDayValid || !isMonthValid || !isYearValid) { showError('Invalid Credentials'); return; } // 2. 准确计算用户年龄是否满18 const birthDate = new Date(`${yearInput}-${monthInput}-${dayInput}`); const today = new Date(); let age = today.getFullYear() - birthDate.getFullYear(); // 处理生日未过的情况:比如今天是2024年5月,用户生日是2006年6月,实际未满18 const hasBirthdayPassed = today.getMonth() > birthDate.getMonth() || (today.getMonth() === birthDate.getMonth() && today.getDate() >= birthDate.getDate()); if (!hasBirthdayPassed) age--; if (age < 18) { showError('Invalid Credentials'); return; } // 3. 验证通过,执行关闭逻辑 btnSubmit.style.display = 'none'; loading.classList.remove('hide'); // 模拟加载动画后关闭模态框(实际项目可替换为接口请求/设置cookie逻辑) setTimeout(() => { modal.style.display = 'none'; // 可选:设置cookie,下次打开页面不再显示年龄验证 }, 1000); } // 绑定表单提交事件 form.addEventListener('submit', handleAgeCheck);
3. 关键修复点解释
- ID匹配修正:把
document.getElementById("myModal")改成document.getElementById("modal"),确保能正确获取模态框元素 - 严谨的年龄计算:用
Date对象结合月日判断用户是否真的满18岁,避免仅用年份判断的误差 - 统一错误处理:每次提交先清空旧错误提示,避免重复堆积
- 添加关闭逻辑:在验证通过的分支里,通过
modal.style.display = 'none'关闭模态框,同时保留你原本的加载动画逻辑 - 格式验证优化:用正则表达式验证输入是否符合DD/MM/YYYY的数字格式,提升验证准确性
4. HTML小优化建议
- 把
max-length改成标准HTML属性maxlength - 给输入框添加
pattern属性,在浏览器层面做基础校验:<input class="ageGate" type="text" maxlength="2" placeholder="DD" pattern="\d{2}" required> <input class="ageGate" type="text" maxlength="2" placeholder="MM" pattern="\d{2}" required> <input class="ageGate" type="text" maxlength="4" placeholder="YYYY" pattern="\d{4}" required>
内容的提问来源于stack exchange,提问作者TrevTheDev
相关产品推荐
相关产品推荐

