好吧,在阅读了 MDN 上的 CSS Pseudo Class 文档之后,似乎没有任何伪类组合可以串在一起来模拟使这种行为正常工作的各种状态。因此,在玩了一会儿并查看了 Alex Schaeffer 建议的 Bootstrap 验证链接,但决定我不想添加我并不真正需要的额外依赖项/样式表之后,这是我想出的解决方案,它添加了最少的额外 CSS和 JavaScript。
首先,红色边框确实是一个盒子阴影,所以我可以通过将它添加到我的 (S)CSS 中来覆盖它:
.form__input-text {
/* default input styling goes here */
box-shadow: none;
}
接下来,我向我的组件添加了一些状态,以跟踪表单是否已经过验证。我使用的是 Svelte,所以这就像在组件的 <script> 标记内添加一个布尔变量一样简单,如下所示:
let wasValidated = false;
然后我在我的 HTML/JSX 中添加了一个条件类。如果您使用其他框架或 jQuery/vanilla JS,您可能需要使用连接到事件处理程序的函数显式执行此操作,但在 Svelte 中,我只需将我的标记更改为:
<label for="addressLine1" class="form__label">
Address Line 1
</label>
<input
type="text"
required aria-required="true"
class="form__input-text"
class:wasValidated="{wasValidated}"
id="addressLine1"
/>
如果/当wasValidated 变量为真时,class:wasValidated="{wasValidated}" 位所做的所有事情都是有条件地将.wasValidated 类添加到该输入元素。
然后,回到我的 (S)CSS 中,我添加了以下内容以应用我的“无效”样式(此时只是将边框颜色更改为红色阴影),仅当表单至少经过一次验证时,并且仅限于无效元素:
input.wasValidated:invalid {
border-color: $red;
}
然后我将一个简单的onClick 函数连接到提交按钮,当单击按钮时,该按钮将wasValidated 变量更改为true:
HTML/JSX
<button on:click|preventDefault={onClick} class="form__submit-button" type="submit">
Search
</button>
JS
const onClick = e => {
wasValidated = true;
};
该函数需要连接到点击事件而不是提交事件,因为如果表单验证失败,则永远不会触发提交事件。
所以现在,当页面第一次加载时,所有表单输入都显示默认样式,无论有效性如何,因为wasValidated 设置为false。然后,当单击提交按钮wasValidated 切换到true 时,.wasValidated 类将应用于任何必需的元素,如果它们无效,则显示“无效”样式。否则,如果表单提交成功,连接到表单的onSubmit 函数会从那里处理事情。
编辑:事实证明,在 Svelte 中,您可以在事件第一次触发后取消绑定事件处理程序。所以我的提交按钮标记现在看起来像这样:
<button on:click|preventDefault|once={onClick} class="form__submit-button" type="submit">
Search
</button>
将|once 修饰符添加到on:click 会在第一次单击按钮时取消绑定onClick 函数,因此如果用户尝试多次提交无效数据,该函数不会不必要地继续触发。