延迟HTML5的:invalid伪类直到第一个事件

93

我最近发现:invalid伪类会立即应用于required表单元素,即使在页面加载时。例如,如果你有以下代码:

<style>
input:invalid { background-color: pink; color: white; }
input:valid { background-color: white; color: black; }
</style>
…
<input name="foo" required />

然后您的页面将显示一个空的粉色输入框。内置HTML5验证非常好,但我认为大多数用户不希望在他们有机会输入任何值之前进行表单验证。是否有任何方法可以延迟伪类的应用,直到第一个影响该元素的事件(表单提交、失去焦点、更改或其他适当的事件)?是否可以在不使用JavaScript的情况下实现这一点?


我无法评论,因此我会在@user3284463的补充中添加以下内容。makeDirty不应该切换脏类,而应该在未来(蓝色,无效,有效)事件上保持它。函数makeDirty(e){ if (!e.target.classList.contains('dirty')) e.target.classList.add('dirty'); } - Abir Stolov
理想情况下,我希望CSS允许在表单元素上使用:visited来实现这一点。 - matty
14个回答

1

在使用HTML5表单验证时,尽量使用浏览器检测无效提交/字段,而不是重新发明轮子。

监听invalid事件,将一个'class'为“invalid”的类添加到您的表单。添加了'invalid'类后,您可以使用CSS3 :pseudo选择器来设计您的表单样式。

例如:

// where myformid is the ID of your form
var myForm = document.forms.myformid;

var checkCustomValidity = function(field, msg) {
    if('setCustomValidity' in field) {
        field.setCustomValidity(msg);
    } else {
        field.validationMessage = msg;
    }
};

var validateForm = function() {

    // here, we're testing the field with an ID of 'name'
    checkCustomValidity(myForm.name, '');

    if(myForm.name.value.length < 4) {
        checkCustomValidity(
            // alerts fields error message response
            myForm.name, 'Please enter a valid Full Name, here.'
        );
    }
};

/* here, we are handling your question above, by adding an invalid
   class to the form if it returns invalid.  Below, you'll notice
   our attached listener for a form state of invalid */
var styleInvalidForm = function() {
    myForm.className = myForm.className += ' invalid';
}

myForm.addEventListener('input', validateForm, false);
myForm.addEventListener('keyup', validateForm, false);
myForm.addEventListener('invalid', styleInvalidForm, true);

现在,根据我们附加的“invalid”类别,简单地为您的表单添加样式。
例如:
form.invalid input:invalid,
form.invalid textarea:invalid {
    background: rgba(255, 0, 0, .05);
    border-color: #ff6d6d;
    -webkit-box-shadow: 0 0 6px rgba(255, 0, 0, .35);
    box-shadow: 0 0 6px rgba(255, 0, 0, .35);
}

7
这不是比问题本身更多地重新发明轮子了吗? - Ry-

0
这是我避免任何未聚焦输入默认样式为无效的方法,你只需要添加一个简单的js命令onFocus,让网页识别focusedunfocused输入,这样所有输入在第一次出现时都不会以无效的样式显示。
<style>
input.focused:required:invalid { background-color: pink; color: white; }
input:valid { background-color: white; color: black; }
</style>
…
<input name="foo" class="notfocused" onFocus="document.activeElement.className='focused';" required />

请在下面自行尝试:

input.focused:required:invalid {
  background-color: pink;
  color: white;
}

input:required:valid {
  background-color: darkseagreen;
  color: black;
}
<label>At least 1 charater:</label><br />
<input type="text" name="foo" class="notfocused" onFocus="document.activeElement.className='focused';" required />


0
自从CSS选择器4级,现在你可以使用`:user-invalid`选择器,大大简化了这个过程。
`:user-invalid`和`:user-valid`伪类分别表示具有错误或正确输入的元素,但只有在用户与之有重要交互之后才会生效。

https://www.w3.org/TR/selectors-4/#user-pseudos

input:user-invalid {
  background-color: pink;
  color: white;
}
<form>
  <input name="foo" required />
  <button type="submit">Submit</button>
</form>


0

我无法评论,但是要使用@Carl的非常有用的答案,关于使用:not(:placeholder-shown)。正如另一个评论提到的那样,如果您没有占位符(因为某些表单设计需要),这仍会显示无效状态。

为了解决这个问题,只需添加一个空占位符即可,像这样

<input type="text" name="username" placeholder=" " required>

然后你的CSS,类似于

:not(:placeholder-shown):invalid{ background-color: #ff000038; }

对我有效!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接