<link />
只能在 <head />
中插入么?
不是。在某些情况下 <link />
也能插入到 <body />
中,具体情况取决于当前 <link />
是否有一个 body-ok 的链接类型。例如,在日常开发中,会使用
<link rel="stylesheet" href="main.css" />
来链接样式表;<link rel="icon" href="favicon.ico" />
来链接网站的图标。
但是只有 stylesheet 类型才是 body-ok 可以插入到 <body />
中,其他类型见 HTML Standard。
我们可以这么使用(极其不推荐)
// index.html
<head>
<link rel="stylesheet" href="./styles/head.css">
</head>
<body>
<!-- demo 1 -->
<link rel="stylesheet" href="./styles/body.css">
<h5 class="title">Hello world</h5>
<!-- 此时 body.css 会覆盖 .head.css -->
</body>
复制代码
但是这不是一种好的可遵循的实践方式;更合理的方式是,将你的 <link>
元素从你的 body 内容中分离出来,将其放在 <head>
中。
<link />
标签的 media
属性
在日常开发中,有时候会碰到需要媒体查询的情况,例如
// screen width 从 600px 到 900px 时,样式生效
@media screen and (max-width: 900px) {
.title {
color: red;
}
}
// screen width 从 0 到 600px 时,样式生效
@media screen and (max-width: 600px) {
.title {
color: green;
}
}
复制代码
业务不复杂的情况,可以选择这样实现,但是当样式很多时,会造成当前样式表复杂且不不清晰。我们可以借助 <link rel="stylesheet" media="(max-width: 600px)" href="example.css" />
来分离样式,这个属性规定了外部资源适用的媒体类型。
<link />
的 disabled
属性
常用于启用或禁用样式表,例如
document.querySelector('link[href="red.css"]').disabled = false;
复制代码
可以使得 red.css
失效,一般可以配合 <link />
的 title
、rel
来实现网站换肤功能,具体见
利用 disabled 实现网站换肤 link rel=alternate网站换肤功能最佳实现.
利用 <link />
标签完成游览器预加载机制
在优化页面的首屏的时候,首先要做的就是限制首次请求的资源大小以及资源数,但是这样会使得每次跳转至一个未缓存资源的页面时,都需要重新加载。如果在页面加载时候可以满足
- 首屏需要的资源作为即刻资源,希望在页面加载的早期就开始获取,在浏览器的主渲染机制介入前就进行预加载;
- 当首屏加载完成之后,在加载其他页面的资源,这样既不占有首屏的时间,也可以优化其他页面。
<link />
标签的 rel
的属性值 preload
就可以实现这一功能,来指明哪些资源是在页面加载完成后即刻需要的。为了完成基本的配置,你还需要通过 href
和as
属性指定需要被预加载资源的资源路径及其类型,具体实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="preload" href="style.css" as="style">
<link rel="preload" href="main.js" as="script">
<link rel="stylesheet" href="style.css">
</head>
<body>
<h5 class="title">Hello world</h5>
<!-- hello world 代码片段 * 2048 -->
<script src="main.js"></script>
</body>
</html>
复制代码
在使用预加载时候,waterfall 如下
在不使用预加载的时候
从图中很明显可以看出 main.js 的加载实际又很明显的分别,也就是预加载的好处。也就实现了,我们对首屏资 源的预加载,而其他资源的加载时机,我们可以通过脚本化来控制,通过新建 HTMLLinkElement
元素来实现。
// 当首页完成的时候
window.onload = () => {
// 完成对其他资源的预加载
var preloadLink = document.createElement("link");
preloadLink.href = "myscript.js";
preloadLink.rel = "preload";
preloadLink.as = "script";
document.head.appendChild(preloadLink);
}
复制代码
<link />
的 onload 事件
与 window.onload
事件一样,它赋予了我们监听样式表加载完成的(但是还未应用到内容),也可以通过 error 来监听是否在加载期间发生了异常。
<script>
function sheetLoaded() {
// Do something interesting; the sheet has been loaded
}
function sheetError() {
alert("An error occurred loading the stylesheet!");
}
</script>
<link rel="stylesheet" href="mystylesheet.css" onload="sheetLoaded()" onerror="sheetError()">
复制代码