技巧

input输入验证

我们通常会使用JavaScript来校验表单,比如:

function validateForm() {
    const inputText = document.forms["form-name"]["input-name"].value;
    if (!inputText) {

    } else {

    }
}

以上是使用原生JavaScript实现的,现在很多项目都是使用React、Vue等框架来实现,表单校验可能稍微简单一些

HTML提供的原生检验方式

验证内容使用说明示例
必填强制必须输入内容<input required="true">
正则按照正则表达式规则校验<input pattern="^1\d{10}$">
类型强制输入内容类型<input type="number">
大小限制输入数字大小<input type="number" min="0" max="5">
输入间隔规定输入数字的间隔<input type="number" step="1">

meta自动刷新/跳转

  1. 假设要实现一个类似 PPT 自动播放的效果,你可能会想到使用 JavaScript 定时器控制页面跳转来实现。但其实有更加简洁的实现方法,比如通过 meta 标签来实现:
<meta http-equiv="Refresh" content="5; URL=page2.html">

上面的代码会在 5s 之后自动跳转到同域下的 page2.html 页面。要实现 PPT 自动播放的功能,只需要在每个页面的 meta 标签内设置好下一个页面的地址即可。

  1. 另一种场景,比如每隔一分钟就需要刷新页面的大屏幕监控,也可以通过 meta 标签来实现,只需去掉后面的 URL 即可:
<meta http-equiv="Refresh" content="60">
  1. 可以看到,这样做又方便又快捷,那为什么这种用法比较少见呢?

一方面是因为不少人对 meta 标签用法缺乏深入了解,另一方面也是因为在使用它的时候,刷新和跳转操作是不可取消的,所以对刷新时间间隔或者需要手动取消的,还是推荐使用 JavaScript 定时器来实现。但是,如果只是想实现页面的定时刷新或跳转(比如某些页面缺乏访问权限,在 x 秒后跳回首页这样的场景)建议可以实践下 meta 标签的用法。

title消息提醒

消息提醒功能实现比较困难,HTML5 标准发布之前,浏览器没有开放图标闪烁、弹出系统消息之类的接口,只能借助一些 Hack 的手段,比如修改 title 标签来达到类似的效果(HTML5 下可使用 Web Notifications API 弹出系统消息)。

  1. 通过定时修改 title 标签内容,模拟了类似消息提醒的闪烁效果:
let msgNum = 1 // 消息条数
let cnt = 0 // 计数器
const inerval = setInterval(() => {
    cnt = (cnt + 1) % 2
    if(msgNum===0) {
        // 通过DOM修改title
        document.title += `聊天页面`
        clearInterval(interval)
        return
    }
    const prefix = cnt % 2 ? `新消息(${msgNum})` : ''
    document.title = `${prefix}聊天页面`
}, 1000)

定时修改 title 标签内容,除了用来实现闪烁效果之外,还可以制作其他动画效果,比如文字滚动,但需要注意浏览器会对 title 标签文本进行去空格操作。

动态修改 title 标签的用途不仅在于消息提醒,还可以将一些关键信息显示到标签上(比如下载时的进度、当前操作步骤),从而提升用户体验。

script调整加载顺序提升渲染速度

由于浏览器的底层运行机制,渲染引擎在解析 HTML 时,若遇到 script 标签引用文件,则会暂停解析过程,同时通知网络线程加载文件,文件加载后会切换至 JavaScript 引擎来执行对应代码,代码执行完成之后切换至渲染引擎继续渲染页面。

在这一过程中可以看到,页面渲染过程中包含了请求文件以及执行文件的时间,但页面的首次渲染可能并不依赖这些文件,这些请求和执行文件的动作反而延长了用户看到页面的时间,从而降低了用户体验。

为了减少这些时间损耗,可以借助 script 标签的 3 个属性来实现。

  1. async 属性: 立即请求文件,但不阻塞渲染引擎,而是文件加载完毕后阻塞渲染引擎并立即执行文件内容。

  2. defer 属性: 立即请求文件,但不阻塞渲染引擎,等到解析完 HTML 之后再执行文件内容。

  3. HTML5 标准 type 属性: 对应值为“module”。让浏览器按照 ECMA Script 6 标准将文件当作模块进行解析,默认阻塞效果同 defer,也可以配合 async 在请求完成后立即执行。

link通过预处理提升渲染速度

在对大型单页应用进行性能优化时,也许会用到按需懒加载的方式,来加载对应的模块,但如果能合理利用 link 标签的 rel 属性值来进行预加载,就能进一步提升渲染速度。

  1. dns-prefetch:当 link 标签的 rel 属性值为“dns-prefetch”时,浏览器会对某个域名预先进行 DNS 解析并缓存。这样,当浏览器在请求同域名资源的时候,能省去从域名查询 IP 的过程,从而减少时间损耗。

  2. preconnect:让浏览器在一个 HTTP 请求正式发给服务器前预先执行一些操作,这包括 DNS 解析、TLS 协商、TCP 握手,通过消除往返延迟来为用户节省时间。

  3. prefetch/preload: 两个值都是让浏览器预先下载并缓存某个资源,但不同的是,prefetch 可能会在浏览器忙时被忽略,而 preload 则是一定会被预先下载。

  4. prerender: 浏览器不仅会加载资源,还会解析执行页面,进行预渲染。

link减少重复

有时候为了用户访问方便或者出于历史原因,对于同一个页面会有多个网址,又或者存在某些重定向页面,比如:

  • baidu.com/a.html
  • baidu.com/detail?....

那么在这些页面中可以这样设置:

<link href="https://baidu.com/a.html" rel="canonical">

这样可以让搜索引擎避免花费时间抓取重复网页。不过需要注意的是,它还有个限制条件,那就是指向的网站不允许跨域。

当然,要合并网址还有其他的方式,比如使用站点地图,或者在 HTTP 请求响应头部添加 rel="canonical"。

figure标记图片

<figure>标签可以用于标记图片,其可以包含一个<figcaption>元素,用来描述图片:

<figure>
    <img src="https://t7.baidu.com/it/u=2604797219,1573897854&fm=193&f=GIF" alt="Swat Kats" style="width:500px">
    <figcaption>风景图</figcaption>
</figure>

picture响应式图像

picture标签可以根据屏幕匹配的不同尺寸显示不同图片,如果没有匹配到或浏览器不支持 picture 属性则使用 img 元素:

<picture>
   <source media="(min-width: 968px)" srcset="large_img.jpg">
   <source media="(min-width: 360px)" srcset="small_img.jpg">
   <img src="default_img.jpg" alt="avatar">
</picture>

该标签一般用于响应式元素,可以让图片资源的调整更加灵活。如果浏览器不支持该属性也会显示<img>元素的的图片。

oncontextmenu禁用右键

当我们给某个元素设置oncontextmenu属性时,就会禁用右键点击。如果给body元素设置这个属性,整个页面就会被禁用右键点击:

<p oncontextmenu="return false">Hello</p>
<body oncontextmenu="return false">....</body>

input颜色选择器

nput标签是支持很多类型的元素,我们可以使将input定义成一个颜色选择器:

<input type="color" id="color-picker"  name="color-picker" value="#e66465">

base在新标签页打开

我们可以将base元素的target属性设置为_black,这样当用户单击链接时,它始终会在新选项卡中打开。如果想避免用户无意中离开某个页面,这样做会很有用。

<head>
    <base target="_blank">
</head>

<div>
    <a href="https://www.baidu.com/">百度一下</a>
</div>

placeholder样式,光标颜色

可以使用placeholder属性设置占位符文本

<input type="text" placeholder="你的名字" />
::placeholder {
    color: #210065;
    opacity: 0.7;
    font-size: 16px;
}

input {
    caret-color: red;
}
贡献者: mankueng