我尝试在function errMsg()
中使用setTimeout,但没有任何作用。
我只想在错误的条目上保留红色边界,但没有消息。。。
const formFrEu = document.getElementById('converter-form')
, v_Euro = 6.55957
, regNum = /^d+.d+?$/
;
formFrEu.onsubmit = e => e.preventDefault();
formFrEu.oninput = e =>
{
// formFrEu.Franc.setCustomValidity('') // try changed by 2s delay
// formFrEu.Euro.setCustomValidity('')
switch (e.target.name)
{
case 'Franc':
if (formFrEu.Franc.reportValidity())
formFrEu.Euro.value = (parseFloat(formFrEu.Franc.value) / v_Euro).toFixed(2)
break;
case 'Euro':
if (formFrEu.Euro.reportValidity())
formFrEu.Franc.value = (parseFloat(formFrEu.Euro.value) * v_Euro).toFixed(2)
break;
}
}
formFrEu.Euro.oninvalid = errMsg;
formFrEu.Franc.oninvalid = errMsg;
function errMsg(e)
{
if (regNum.test(e.target.value))
{
e.target.setCustomValidity('sonly 2 digits after the decimal point !')
}
else
{
e.target.setCustomValidity('Please enter a numeric value !')
}
setTimeout(() => { e.target.setCustomValidity(''); }, 2000); // not working!!
}
<form id="converter-form">
<h2>Converter Euros <-> Francs </h2>
<label>
<h4>Euros</h4>
<input type="text" name="Euro" placeholder="Enter the amount in Euros" pattern="[0-9]+([.][0-9]{0,2})?" autocomplete=off>
</label>
<label>
<h4>Francs</h4>
<input type="text" name="Franc" placeholder="Enter the amount in Francs" pattern="[0-9]+([.][0-9]{0,2})?" autocomplete=off>
</label>
</form>
我找到了一个解决方案,但它只让我满意一半:我让你自己判断:/
function errMsg(e)
{
let otherTarget = (e.target.name==='Franc') ? formFrEu.Euro : formFrEu.Franc
if ( regNum.test(e.target.value) )
{ e.target.setCustomValidity('Only 2 digits after the decimal point !') }
else
{ e.target.setCustomValidity('Please enter a numeric value !') }
setTimeout(()=>
{
if (document.activeElement===e.target) // if still on the same place
{
otherTarget.focus(); // double flip focus
e.target.focus(); // will remove message bubble
}
}, 2000);
}
附言:由于我主要使用Firefox,我没有意识到在Chromium下,消息会在几秒钟后自行消失,但它不会在边框上添加任何颜色效果。。。
完整的测试页面(我对原来的帖子做了一些小改动(
const formFrEu = document.getElementById('converter-form')
, v_Euro = 6.55957
, inPatt = '[0-9]+([.][0-9]{0,2})?'
, regNum = /^d+.d+?$/
;
formFrEu.querySelectorAll('input').forEach(inp=>
{
inp.pattern = inPatt
inp.autocomplete = 'off'
})
formFrEu.onsubmit=e=>e.preventDefault()
;
formFrEu.oninput=e=>
{
formFrEu.Francs.setCustomValidity('')
formFrEu.Euros.setCustomValidity('')
let noStrVal = (e.target.value.trim()==='')
switch (e.target.name)
{
case 'Francs':
if ( formFrEu.Francs.reportValidity() )
{
formFrEu.Euros.value = noStrVal? '' : (parseFloat(formFrEu.Francs.value) / v_Euro).toFixed(2)
}
break;
case 'Euros':
if ( formFrEu.Euros.reportValidity() )
{
formFrEu.Francs.value = noStrVal? '' : (parseFloat(formFrEu.Euros.value) * v_Euro).toFixed(2)
}
break;
}
}
formFrEu.Euros.oninvalid = errMsg
formFrEu.Francs.oninvalid= errMsg
function errMsg(e)
{
let otherTarget = (e.target.name==='Francs') ? formFrEu.Euros : formFrEu.Francs
if ( regNum.test(e.target.value) )
{ e.target.setCustomValidity('Only 2 digits after the decimal point !') }
else
{ e.target.setCustomValidity('Please enter a numeric value !') }
setTimeout(()=>
{
if (document.activeElement===e.target) // if still on the same place
{
otherTarget.focus(); // double flip focus
e.target.focus(); // will remove message bubble
}
}, 2000);
}
input:invalid { border-color: crimson; }
<form id="converter-form" >
<h3>Converters Euros <=> Francs </h3>
<label>
<h4>Euros</h4>
<input type="text" name="Euros" placeholder="Enter the amount in Euros" autocomplete="off" >
</label>
<label>
<h4>Francs</h4>
<input type="text" name="Francs" placeholder="Enter the amount in Francs" autocomplete="off" >
</label>
</form>