Javascript 下一个兄弟姐妹
Javascript Next Sibling
我有一个示例 fiddle 说明了我要完成的任务:
https://jsfiddle.net/qscL4gjh/1/
输入框必须是“文本”输入(不是“数字”),并且只能输入空白值或 8 位数字。我有那部分工作。
但如果用户输入的键值不符合要求,我想显示一个错误块(在输入下方)- 由于某种原因 我无法 javascript识别错误块。我希望错误块出现 3 秒然后淡出。
function validateObj(obj, evt) {
var key = (evt.which) ? evt.which : evt.keyCode
var b = (!(key > 31 && (key < 48 || key > 57)) && obj.value.length < 9);
if (!b) {
var a = obj.getAttribute("data-errorid");
console.log("Error Block Id: " + a);
var $err = document.querySelector(a) || obj.nextElementSibling;
if ($err.length) {
console.log("Found error note");
$err.style.visibility = "visible";
$err.style.opacity = "1";
$err.style.transition = "3s";
$err.style.opacity = "0";
}
else {
console.error("Could not find error block");
}
}
return b;
}
<label>Test 1</label>
<input type="text" id="num" value="" onkeypress="return validateObj(this, event)" data-errorid="#error_note1" value=""/>
<div id="error_note1" class="error_note">
Must be empty or 8 numeric digits
</div>
<br><br>
<label>Test2</label>
<input type="text" id="num" value="" onkeypress="return validateObj(this, event)" data-errorid="#error_note2" value=""/>
<div id="error_note2" class="error_note">
Must be empty or 8 numeric digits
</div>
function validateObj(obj, evt) {
var key = evt.which ? evt.which : evt.keyCode;
var b = !(key > 31 && (key < 48 || key > 57)) && obj.value.length < 9;
if (!b) {
var a = obj.getAttribute("data-errorid");
console.log("Error Block Id: " + a);
var $err = document.querySelector(a) || obj.nextElementSibling;
if ($err.length) {
alert("Found error note");
$err.style.visibility = "visibile";
$err.style.opacity = "1";
$err.style.transition = "3s";
$err.style.opacity = "0";
} else {
document.querySelector(a).style.display = "block";
setTimeout(function () {
document.querySelector(a).style.display = "none";
}, 3000);
}
}
return b;
}
在下面的例子中:
所有内容都包含在 <form id='UI'>
中,并通过 .forms
属性.
引用
const UI = document.forms.UI;
不使用内联属性事件,inline event handlers are garbage. Use onevent properties or .addEventListener()
. If you have multiple <input>
s, register events on an ancestor tag like <form>
, <body>
, document
, or window
. Read about events and event delegation
onkeypress="return validateObj(this, event)" //
.addEventListener(event, event handler, capture)
UI.addEventListener('keydown', resetVal); //
UI.addEventListener('keyup', valData, true); //
/* ☝ certain events require the capture phase instead of the bubbling phase
(see previous link to "event") */
或一个事件属性
UI.onkeydown = resetVal; //
UI.onkeyup = valData; //
/* "keyup" events actually fire on the capture phase that's why
.addEventListener() is recommended */
要始终引用用户当前正在输入的 <input>
,请使用 Event.target
属性.
const inp = e.target; // Refers >inp< as the <input> the user is typing into
if (inp.matches('input')) {... // Delegate event to >inp< only
.value
的 <input>
是一个字符串,正在验证 <input>
的 [pattern]
属性,它是 RegExp。
<input id='test1' pattern='\d{8}'>
const data = inp.value;
const error = inp.nextElementSibling;
const pattern = inp.pattern;
const rgx = new RegExp(pattern, 'gm');
const match = rgx.test(data);
所有样式均来自 class via .classList
属性.
if (!match) {
inp.classList.add('red');
error.classList.add('flash');
} else {
inp.classList.remove('red');
error.classList.remove('flash');
}
这个例子几乎可以容纳无限数量的 <input>
(静态和动态),稍作修改也可以接受来自 <textarea>
或 contenteditable
的标签([data-pattern]
属性和 .textContent
和 .dataset
属性)。
注意: 闪烁的错误消息并不是很好的用户体验,因此我添加了红色文本作为持续提醒用户该文本仍然无效。
const UI = document.forms.UI;
UI.addEventListener('keydown', resetVal);
UI.addEventListener('keyup', valData, true);
function resetVal(e) {
const inp = e.target;
if (inp.matches('input')) {
inp.nextElementSibling.classList.remove('flash');
if (inp.value.length < 1) {
inp.classList.remove('red');
}
}
};
function valData(e) {
const inp = e.target;
if (inp.matches('input') && inp.value.length > 0) {
const data = inp.value;
const error = inp.nextElementSibling;
const pattern = inp.pattern;
const rgx = new RegExp(pattern, 'gm');
const match = rgx.test(data);
if (!match) {
inp.classList.add('red');
error.classList.add('flash');
} else {
inp.classList.remove('red');
error.classList.remove('flash');
}
}
};
label {
display: block;
}
.error {
display: block;
width: 30ch;
margin: 3px 0 6px 0;
visibility: hidden;
text-align: center;
}
.flash {
visibility: visible;
opacity: 1;
animation: fade 3s forwards;
}
@keyframes fade {
0%,
100% {
opacity: 0
}
50% {
opacity: 1
}
}
.red {
color: red;
}
<form id='UI'>
<label>Test 1 <input id="test1" pattern='\d{8}'>
<output class="error">
Must have 8 numeric digits
</output></label>
<label>Test 2 <input id="test2" pattern='^[a-zA-Z]+$'>
<output class="error">
Must only have letters
</output></label>
<label>Test 3 <input id="test3" pattern='^[^\-\^\\]()@#$%&*_+=~;:]+$'>
<output class="error">
Cannot have special characters
</output></label>
</form>
我有一个示例 fiddle 说明了我要完成的任务: https://jsfiddle.net/qscL4gjh/1/
输入框必须是“文本”输入(不是“数字”),并且只能输入空白值或 8 位数字。我有那部分工作。
但如果用户输入的键值不符合要求,我想显示一个错误块(在输入下方)- 由于某种原因 我无法 javascript识别错误块。我希望错误块出现 3 秒然后淡出。
function validateObj(obj, evt) {
var key = (evt.which) ? evt.which : evt.keyCode
var b = (!(key > 31 && (key < 48 || key > 57)) && obj.value.length < 9);
if (!b) {
var a = obj.getAttribute("data-errorid");
console.log("Error Block Id: " + a);
var $err = document.querySelector(a) || obj.nextElementSibling;
if ($err.length) {
console.log("Found error note");
$err.style.visibility = "visible";
$err.style.opacity = "1";
$err.style.transition = "3s";
$err.style.opacity = "0";
}
else {
console.error("Could not find error block");
}
}
return b;
}
<label>Test 1</label>
<input type="text" id="num" value="" onkeypress="return validateObj(this, event)" data-errorid="#error_note1" value=""/>
<div id="error_note1" class="error_note">
Must be empty or 8 numeric digits
</div>
<br><br>
<label>Test2</label>
<input type="text" id="num" value="" onkeypress="return validateObj(this, event)" data-errorid="#error_note2" value=""/>
<div id="error_note2" class="error_note">
Must be empty or 8 numeric digits
</div>
function validateObj(obj, evt) {
var key = evt.which ? evt.which : evt.keyCode;
var b = !(key > 31 && (key < 48 || key > 57)) && obj.value.length < 9;
if (!b) {
var a = obj.getAttribute("data-errorid");
console.log("Error Block Id: " + a);
var $err = document.querySelector(a) || obj.nextElementSibling;
if ($err.length) {
alert("Found error note");
$err.style.visibility = "visibile";
$err.style.opacity = "1";
$err.style.transition = "3s";
$err.style.opacity = "0";
} else {
document.querySelector(a).style.display = "block";
setTimeout(function () {
document.querySelector(a).style.display = "none";
}, 3000);
}
}
return b;
}
在下面的例子中:
所有内容都包含在
引用<form id='UI'>
中,并通过.forms
属性.const UI = document.forms.UI;
不使用内联属性事件,inline event handlers are garbage. Use onevent properties or
.addEventListener()
. If you have multiple<input>
s, register events on an ancestor tag like<form>
,<body>
,document
, orwindow
. Read about events and event delegationonkeypress="return validateObj(this, event)" //
.addEventListener(event, event handler, capture)
UI.addEventListener('keydown', resetVal); // UI.addEventListener('keyup', valData, true); // /* ☝ certain events require the capture phase instead of the bubbling phase (see previous link to "event") */
或一个事件属性
UI.onkeydown = resetVal; // UI.onkeyup = valData; // /* "keyup" events actually fire on the capture phase that's why .addEventListener() is recommended */
要始终引用用户当前正在输入的
<input>
,请使用Event.target
属性.const inp = e.target; // Refers >inp< as the <input> the user is typing into if (inp.matches('input')) {... // Delegate event to >inp< only
.value
的<input>
是一个字符串,正在验证<input>
的[pattern]
属性,它是 RegExp。<input id='test1' pattern='\d{8}'>
const data = inp.value; const error = inp.nextElementSibling; const pattern = inp.pattern; const rgx = new RegExp(pattern, 'gm'); const match = rgx.test(data);
所有样式均来自 class via
.classList
属性.if (!match) { inp.classList.add('red'); error.classList.add('flash'); } else { inp.classList.remove('red'); error.classList.remove('flash'); }
这个例子几乎可以容纳无限数量的 <input>
(静态和动态),稍作修改也可以接受来自 <textarea>
或 contenteditable
的标签([data-pattern]
属性和 .textContent
和 .dataset
属性)。
注意: 闪烁的错误消息并不是很好的用户体验,因此我添加了红色文本作为持续提醒用户该文本仍然无效。
const UI = document.forms.UI;
UI.addEventListener('keydown', resetVal);
UI.addEventListener('keyup', valData, true);
function resetVal(e) {
const inp = e.target;
if (inp.matches('input')) {
inp.nextElementSibling.classList.remove('flash');
if (inp.value.length < 1) {
inp.classList.remove('red');
}
}
};
function valData(e) {
const inp = e.target;
if (inp.matches('input') && inp.value.length > 0) {
const data = inp.value;
const error = inp.nextElementSibling;
const pattern = inp.pattern;
const rgx = new RegExp(pattern, 'gm');
const match = rgx.test(data);
if (!match) {
inp.classList.add('red');
error.classList.add('flash');
} else {
inp.classList.remove('red');
error.classList.remove('flash');
}
}
};
label {
display: block;
}
.error {
display: block;
width: 30ch;
margin: 3px 0 6px 0;
visibility: hidden;
text-align: center;
}
.flash {
visibility: visible;
opacity: 1;
animation: fade 3s forwards;
}
@keyframes fade {
0%,
100% {
opacity: 0
}
50% {
opacity: 1
}
}
.red {
color: red;
}
<form id='UI'>
<label>Test 1 <input id="test1" pattern='\d{8}'>
<output class="error">
Must have 8 numeric digits
</output></label>
<label>Test 2 <input id="test2" pattern='^[a-zA-Z]+$'>
<output class="error">
Must only have letters
</output></label>
<label>Test 3 <input id="test3" pattern='^[^\-\^\\]()@#$%&*_+=~;:]+$'>
<output class="error">
Cannot have special characters
</output></label>
</form>