Javascript 使用querySelectorAll验证表单时-如何选择适当的范围以输出错误

Javascript 使用querySelectorAll验证表单时-如何选择适当的范围以输出错误,javascript,Javascript,我正在使用querySelectorAll向input字段添加事件侦听器,我想知道当表单“error”发生时,如何在适当的范围内显示错误消息 我已经找到了一个看起来很有希望的帖子,但我不知道它是否适合我目前的职位 const inputs = document.querySelectorAll("input"); inputs.forEach(function(input){ input.addEventListener("blur", funct

我正在使用
querySelectorAll
input
字段添加事件侦听器,我想知道当表单“error”发生时,如何在适当的范围内显示错误消息

我已经找到了一个看起来很有希望的帖子,但我不知道它是否适合我目前的职位

const inputs = document.querySelectorAll("input");
inputs.forEach(function(input){
    input.addEventListener("blur", function (){
        if(input.validity.valueMissing){
            //select appropriate span
        }
    })
})




不相关-此外,我想为电子邮件/电话/etc输入字段显示不同的错误消息。。。我不知道是否可以在一个“函数”中滚动所有这些内容。

由于您的
span
是您的
输入的兄弟,您可以向前扫描到它:

let span = input.nextSiblingelement;
while (span && !span.classList.contains("error")) {
    span = span.nextSiblingElement;
}
if (span) {
    span.textContent = /*...*/;
}
理想情况下,如果您可以更改标记,我会将它们改为同一容器元素的子元素:



然后您可以使用
最近的
查询选择器
找到它,这可能会让您在不更改JavaScript的情况下更灵活地更改HTML:

const span=input.closest(“div”).querySelector(“错误”);
如果(跨度){
span.textContent=/*…*/;
}
您可以使用
id
s,因为您正在这些元素上使用
id
s:

const span = document.getElementById("e_" + input.id);
if (span) {
    span.textContent = /*...*/;
}

…但如果您可以从结构上执行此操作,则无需管理大量
id
值。

由于您的
span
是您的
输入的同级,您可以向前扫描到它:

let span = input.nextSiblingelement;
while (span && !span.classList.contains("error")) {
    span = span.nextSiblingElement;
}
if (span) {
    span.textContent = /*...*/;
}
理想情况下,如果您可以更改标记,我会将它们改为同一容器元素的子元素:



然后您可以使用
最近的
查询选择器
找到它,这可能会让您在不更改JavaScript的情况下更灵活地更改HTML:

const span=input.closest(“div”).querySelector(“错误”);
如果(跨度){
span.textContent=/*…*/;
}
您可以使用
id
s,因为您正在这些元素上使用
id
s:

const span = document.getElementById("e_" + input.id);
if (span) {
    span.textContent = /*...*/;
}

…但如果您可以从结构上执行此操作,则无需管理大量
id
值。

由于
.error
span
id
的前缀是
“e_”
,后跟字段名,因此您可以使用以下方法进行查找:

document.querySelector(`e#u${input.getAttribute('name')}`)
我还想用
^
(行开始)和
$
(行结束):
^[A-Za-z]{2,15}$
,来包装您的模式,因为如果没有,您可以允许名称长度超过15个字符

如果希望这是隐式的,可以在
RegExp
构造函数调用中添加它们:

pattern:input=>
(模式=>
模式?新的RegExp(`^{pattern}$`).test(input.value):true)
(input.getAttribute('pattern'))
例子
const验证\u规则={
必需:输入=>
(必需=>
必需的| |(必需和&input.value.length>0))
(input.hasAttribute('required')),
模式:输入=>
(模式=>
模式?新的RegExp(模式).test(输入.value):true)
(input.getAttribute('pattern'))
};
常量validateRules=(输入,规则)=>
rules.reduce((acc,rule)=>acc&&VALIDATION_rules[rule](输入),true);
常数onInputBlur=e=>{
常数
输入=e.target,
valid=validateRules(输入,['必需','模式]];
document.querySelector(`e#e${input.getAttribute('name')}`)
.classList.toggle('show',!valid');
}
const inputs=document.querySelectorAll('input').forEach(input=>
input.addEventListener('blur',onInputBlur))
。错误{显示:无;颜色:红色;字体大小:较小;}
.error.show{display:block;}


请输入有效值

由于您的
.error
span
id
前缀为
“e_uquot
,后跟字段名,因此您可以使用以下方法查找该字段:

document.querySelector(`e#u${input.getAttribute('name')}`)
我还想用
^
(行开始)和
$
(行结束):
^[A-Za-z]{2,15}$
,来包装您的模式,因为如果没有,您可以允许名称长度超过15个字符

如果希望这是隐式的,可以在
RegExp
构造函数调用中添加它们:

pattern:input=>
(模式=>
模式?新的RegExp(`^{pattern}$`).test(input.value):true)
(input.getAttribute('pattern'))
例子
const验证\u规则={
必需:输入=>
(必需=>
必需的| |(必需和&input.value.length>0))
(input.hasAttribute('required')),
模式:输入=>
(模式=>
模式?新的RegExp(模式).test(输入.value):true)
(input.getAttribute('pattern'))
};
常量validateRules=(输入,规则)=>
rules.reduce((acc,rule)=>acc&&VALIDATION_rules[rule](输入),true);
常数onInputBlur=e=>{
常数
输入=e.target,
valid=validateRules(输入,['必需','模式]];
document.querySelector(`e#e${input.getAttribute('name')}`)
.classList.toggle('show',!valid');
}
const inputs=document.querySelectorAll('input').forEach(input=>
input.addEventListener('blur',onInputBlur))
。错误{显示:无;颜色:红色;字体大小:较小;}
.error.show{display:block;}


请输入有效值

快速提问。我从innerHTML切换到append/remove textNode,因为有人向我指出innerHTML不安全。textContent“安全”吗?@WeAreDoomed-我想你是在说XSS攻击之类的。是的,
textContent
在这方面是安全的,如果分配给它的是用户派生的内容,
innerHTML
则不是。快速提问。我从innerHTML切换到append/remove textNode,因为有人向我指出innerHTML不安全。textContent“安全”吗?@WeAreDoomed-我想你是在说XSS攻击之类的。是的,
textContent
在该r中是安全的