个人不可能这么可爱(APP打开有惊喜)

<input /> 标签是咱们平常开发中很是常见的替换元素了,可是最近在刷 whattwgMDN 的时候发现 跟 <input /> 有不少相关的属性,选择器都没怎么用过,因此就开篇文章来整理一下一些比较有趣或者实用的知识点。javascript

本篇文章默认你们已经知道 <input /> 标签的基本用法,不会作过多的基础说明~css

没想到,这些选择器竟然跟 input ...

到写文章为止,根据最新的 drafts 指出,一共有3大类,16种跟 input 相关的选择。其实都挺有用的,善用它们,会让咱们的用户体验更加美好。html

下面咱们来分享一下这3大类选择器的做用:java

第一类:控制系(Input Control States)

选择器 做用
:enabled 选择可以使用状态的 <input /> 元素
:disabled 选择不可以使用状态的 <input /> 元素
:read-only 选择不可编辑状态的元素(不只仅是 <input />
:read-write 选择可编辑状态的元素(不只仅是 <input />
:placeholder-shown 选择 placeholder text 显示时的元素
:default 选择在 <button><input type="checkbox" /><input type="radio" />, 以及 <option> 上的默认状态

第二类:输出系(Input Value States)

选择器 做用
:checked 选择处于选中状态的 <input type="radio" />
:indeterminate 选择状态不肯定的表单元素与 <progress>

第三类:侦查系(Input Value-checking)

选择器 做用
:blank 选择处于空值时的 <input>,暂未被浏览器支持
:valid 选择验证经过的表单元素
:invalid 选择验证不经过的表单元素
:in-range 选择处于指定范围内的 <input />
:out-of-range 选择不处于指定范围内的 <input />
:required 选择必填的表单元素
:optional 选择选填的表单元素
:user-invalid 选择用户输入但值非法时的 <input />,暂未被浏览器支持

可怕,除了选择器,竟然还跟这些属性有关系

<input> 除了有不少相关的选择器,结合不一样的type还有不一样的属性能够供使用。他们的做用以下:git

属性 做用
maxlength 可输入的最大长度
minlength 可输入的最小长度
size 输入框的长度
readonly 输入框是否只读
required 输入框是否必填
multiple 输入框是否能够多选
pattern 输入框验证规则
min 可输入的最小值
max 可输入的最大值
step 输入框每次的增量
list 输入框绑定的可选值数据
placeholder 输入框预选文字

实战

经过上面的三类说明,咱们大体了解了 <input /> 标签的相关信息,可是大家觉得我是来列list的吗?github

固然不是,还有实操啊~api

纯CSS实现表单提交功能

首先咱们来看个效果图promise

上面的效果就是一个纯CSS实现的表单提交功能,这是怎么实现的呢?下面咱们直接看源码,而后一步一步地来分拆(不想看的能够直接CV下面的源码本身作测试~)浏览器

<style> :root { --error-color: red; } .form > input { margin-bottom: 10px; } .form > .f-tips { color: var(--error-color); display: none; } input[type="text"]:invalid ~ input[type="submit"], input[type="password"]:invalid ~ input[type="submit"] { display: none; } input[required]:focus:invalid + span { display: inline; } input[required]:empty + span { display: none; } input[required]:invalid:not(:placeholder-shown) + span { display: inline; } </style>
<form class="form" id="form" method="get" action="/api/form">
    帐号:
    <input data-title="帐号" placeholder="请输入正确的帐号" pattern="\w{6,10}" name="account" type="text" required />
    <span class="f-tips">请输入正确的帐号</span>
    <br />
    密码:
    <input data-title="密码" placeholder="请输入正确的密码" pattern="\w{6,10}" name="password" type="password" required />
    <span class="f-tips">请输入正确的密码</span>
    <br />
    <input name="button" type="submit" value="提交" />
</form>
复制代码

第一步:写好基础结构

首先咱们来把基础结构给写好,代码以下:微信

<style> :root { --error-color: red; } .form > input { margin-bottom: 10px; } .form > .f-tips { color: var(--error-color); display: none; } </style>
<form class="form" id="form" method="get" action="/api/form">
    帐号:
    <input data-title="帐号" placeholder="请输入正确的帐号" pattern="\w{6,10}" name="account" type="text" required />
    <span class="f-tips">请输入正确的帐号</span>
    <br />
    密码:
    <input data-title="密码" placeholder="请输入正确的密码" pattern="\w{6,10}" name="password" type="password" required />
    <span class="f-tips">请输入正确的密码</span>
    <br />
    <input name="button" type="submit" value="提交" />
</form>
复制代码

扫一眼,嗯,挺简单的,都是经常使用的东西。咦,不对,这个 pattern 是什么东西?

在这里咱们重点分享下 pattern 这个属性,这是一个用来验证 input[value] 是否合法的属性,里面的内容就是匹配value的,语法即是正则的语法,例子以下:

<label>
    <!-- 当前pattern的内容就是验证input[name="part"]的value的,其规则如同里面的正则同样,匹配input[name="part"]的value是不是一个数字+3个大写字母 -->
    <input pattern="[0-9][A-Z]{3}" name="part" />
</label>
复制代码

固然,不一样的 input[type] 也会默认带有相应的 pattern ,例如 input[type="email"] 就是默认匹配了如下规则:

/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/
复制代码

第二步:重点功能

input[type="text"]:invalid ~ input[type="submit"],
input[type="password"]:invalid ~ input[type="submit"] {
    display: none;
}
input[required]:focus:invalid + span {
    display: inline;
}
input[required]:empty + span {
    display: none;
}
input[required]:invalid:not(:placeholder-shown) + span {
    display: inline;
}
复制代码

上面即是核心交互的实现。

首先第一个class就是保证了在两个输入框不经过的时候隐藏,就是当输入框值为空或者不符合验证规则,则隐藏提交按钮。

第二个,第三个class则是控制当用户在输入框输入内容时,若是不符合验证规则,则显示错误信息,不然则隐藏。

第四个class则是用过 placeholder 是否存在来控制错误信息的显隐,若是 placeholder 不显示,则证实用户正在输入,错误信息则根据用户输入的值来判断是否显隐,不然则隐藏。

状态切换

上面咱们有提到一个选择器 :indeterminate ,这个是用于选择状态不肯定的表单元素与 <progress> ,玩过扫雷的人都知道,右击除了能够选择红旗,还能够选择问号,就是选中,但不肯定;又跟 promisepending 状态类型,介于 resolvereject 之间。

多了 :indeterminate 会给咱们带来不少颇有趣的体验。

首先咱们来看看它的使用案例。

基础使用法

先看效果

代码以下:

<style> body { background: #333; color: #fff; padding: 20px; text-align: center; } input { margin-right: .25em; width: 30px; height: 30px; } label { position: relative; top: 1px; font-size: 30px; } </style>
<form>
    <input type="checkbox" id="checkbox">
    <label for="option">点击左边</label>
</form>
<script> 'use strict'; checkbox.addEventListener('click', ev => { if (ev.target.readOnly) { ev.target.checked = ev.target.readOnly = false; } else if (!ev.target.checked) { ev.target.readOnly = ev.target.indeterminate = true; }; }); </script>
复制代码

这里面其实没有什么复杂的实现,只是作了个中间态的判断,就很是轻松的实现了radio的三种状态切换。

秀到头皮发麻法

先看效果

(此天秀效果来自于 Ben Szabo 的 codepen,有兴趣的能够仔细研究下,我什么时候才能有大佬这么优秀,嘤嘤嘤~)

输入框绑定的可选值

先看效果

其实代码很简单:

<input type="text" list="names" multiple />
<datalist id="names">
    <option value="kris">
    <option value="陈大鱼头">
    <option value="深圳金城武">
</datalist>

<input type="email" list="emails" multiple />
<datalist id="emails">
    <option value="chenjinwen77@foxmail.com" label="kris">
    <option value="chenjinwen77@gmail.com" label="kris">
</datalist>

<input type="date" list="dates" />
<datalist id="dates">
    <option value="2019-09-03">
</datalist>
复制代码

这里原理就是经过 <input list="dates" /> 来绑定须要下拉显示的数据列表 <datalist id="dates">

那么当咱们要实现输入联想的时候,也能够经过修改 <datalist id="dates"> 的子元素来实现,而不是再写一大堆的操做函数来实现。

总结

其实 <input /> 标签还有不少有趣的功能是能够挖掘的,不一样的类型,结合不一样的选择器与属性,是能够有更多让人为之惊叹的体验的。若是你有兴趣的话,不妨多开开脑洞,亲自动手实现一些有趣的功能,或者有什么有趣的想法也能够在下方给鱼头留言或者加鱼头微信 “krisChans95” 来畅谈。

彩蛋

经由掘友跟微友们提醒,才发现一个比较有趣的彩蛋,感受我这篇文章应该更名为《震惊,一篇文章竟然引起出掘金跟微信的。。。》



若是你、喜欢探讨技术,或者对本文有任何的意见或建议,你能够扫描下方二维码,关注微信公众号“ 鱼头的Web海洋”,随时与鱼头互动。欢迎!衷心但愿能够碰见你。

相关文章
相关标签/搜索