JS魔法堂:LINK元素深入详解
一、前言
我们一般使用方式为 <link type="text/css" rel="stylesheet" href="text.css"> 来引入外部层叠式样式文件,但LINK元素各属性的具体含义、资源加载行为等方面却了解不多,本文打算稍微深入一下。
由于内容较多,特设目录一坨:
二、到底有没有结束标签?
三、普通属性介绍
四、属性disabled详解
1. Attribute和Property的disabled
2. disabled为true还会加载样式文件吗?
3. disabled为true还会触发onload、onerror和onreadystatechange事件吗?
4. CSS解析
5. 渲染
五、属性rel介绍
六、动态创建LINK元素
七、与资源加载相关的属性和事件
八、资源加载实验
1. IE下的结论
2. Chrome下的结论
3. FF下的结论
九、总结
十、参考
二、到底有没有结束标签?
也许我们常常会看到一下两种写法
<!-- 无结束标签 -->
<link type="text/css" rel="stylesheet" href="test.css">
<!-- 闭合标签 -->
<link type="text/css" rel="stylesheet" href="test.css"/>
参考官网可知:
在 HTML 中,<link> 标签没有结束标签。
在 XHTML 中,<link> 标签必须被正确地关闭。
三、普通属性介绍
1. 属性media ,指定该样式应用到的显示设备(媒介类型),默认值为all,还有值screen(显示器)和print(打印机)被浏览器支持。另外还有一堆为成为事实标准的值。
2. HTML5属性sizes ,用于指定网页图标高宽(格式: 高x宽 或默认值 any ),需要同时配置 rel="icons" ,示例:
<link type="images/png" href="fsjohnhuang.png" rel="icons" sizes="16x16"/>
3. 属性type ,引入的资源MIME类型,注意:不规定必须为text/css。
四、属性disabled详解
下列内容主要参考《HTML中Link元素disable属性详解》的内容,并补充一些实践过程中踩过的坑。
1. Attribute和Property的disabled(若想了解更多属性、特性的信息可参考《JS魔法堂:属性、特性,傻傻分不清楚》)
<link type="text/css" rel="stylesheet" href="text.css" disabled="true"/>
2. FF中需要静态或动态引入LINK元素时,都必须等LINK元素被添加到渲染树中后才可以通过点方式修改disabled,否则修改无效,disabled值一直为false。
// FF下
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'test.css';
console.log(link.disabled); // false
link.disabled = true;
console.log(link.disabled); // false
// 加入DOM树,还未加入渲染树
document.body.appendChild(link);
link.disabled = true;
setTimeout(function(console.log(link.disabled); // false link.disabled = true;console.log(link.disabled); // true
), 0);
2. disabled为true还会加载样式文件吗?
仅Chrome在disabled为true时,不加载样式文件。其他浏览器均依然继续加载文件资源。
3. disabled为true还会触发onload、onerror和onreadystatechange事件吗?
由于FF下通过Attribute方式设置disabled为true,和在LINK元素未加入渲染树前修改disabled为true均无 效,因此仅FF下会触发onload和onerror事件。其他浏览器均不会触发onload、onerror和onreadystatechange事 件。
由于FF下存在上述特性,因此可以通过如下手段设置FF下的样式的disabled为true。
<link id="test" type="text/css" rel="stylesheet" href="test.css" onload="this.disabled=true;"/>
4. CSS解析
首先需要理解的是CSS解析到底是什么?
其实就是在成功加载样式文件后,将样式文件中的样式添加到样式表document.styleSheets中。而应用到元素渲染的样式则为document.styleSheets的子集。
由于对于disabled为true的LINK元素,Chrome将不加载其样式文件,因此也无法将文件中的样式添加到 document.styleSheets中;也只有Chrome在将disabled属性从false动态修改为true时,会从 document.styleSheets中删除该样式文件的样式。其他浏览器只要成功加载样式文件就会将其中的样式添加到 document.styleSheets中,无论disabled属性值是什么。
5. 渲染(页面元素与CSS属性结合呈现到页面上)
只要LINK元素的点方式的disabled为true,那么它所关联的样式规则均不生效。(FF则需要经过上述的特殊处理)
对于想通过样式文件书写样式规则,但又想通过document.styleSheets按需提取应用样式的情况,由于Chrome采用直接不加载样式文件的处理方式,因此需要通过如下手段处理:
<link id="test" type="text/css" rel="stylesheet" href="test.css" onload="this.disabled=true;"/>
五、属性rel介绍
属性rel用于规定当前文档与被加载的资源之间的关系。
1. 定义网站收藏夹图标
<link rel="shortcut icon" href="http://paranimage.com/wp-content/themes/v5/images/favicon.ico" type="images/x-icon"/>
<link rel="icon" href="http://paranimage.com/wp-content/themes/v5/images/favicon.png" type="images/png"/>
IE下rel必须为 shortcut icon ,而且图标必须为 .ico格式 。而其他浏览器的rel只需写为 icon ,图标不一定需要使用 .ico格式 。
2. 定义苹果桌面上的网站图标
<link rel="apple-touch-icon" href="http://paranimage.com/wp-content/themes/v5/images/apple-touch-icon.png" />
3. RSS地址和Pingback地址
<link rel="alternate" type="application/rss+xml" title=" RSS Feed" href="rss.html" />
<link rel="alternate" type="application/atom+xml" title="Atom Feed" href="atom.html" />
<link rel="pingback" href="pingback.html" />
六 、动态创建LINK元素
动态创建元素一般有两种方式,分别是document.createElement方法和innerHTML+firstChild。对于LINK元素, 在IE9+和其他现代浏览器中可使用innerHTML+firstChild方式创建LINK元素,而在IE5~8中则需要使用 document.createElement方式创建。下面代码为简单的实现方式:
var $ = function(){// 提取tagName、attributes整体和innerHTMLvar rTag = /<([a-z]+)\s*([^>]*)(?:\/>|>([^<]*)<\/\1>)/ig,// 提取attribute的键值rAttrs = /\s*([a-z]+)\s*=("|')([^'"]*)\2\s*/ig;// IE9+和其他浏览器的DOM对象生成工厂var factory = document.createElement('div');return function(html){var el = (factory.innerHTML = html, factory.firstChild);if (!el){var baseInfo = rTag.exec(html);try{el = document.createElement(baseInfo[1]);var innerHTML = baseInfo[baseInfo.length - 1];if (innerHTML !== null && typeof innerHTML !== 'undefined' && innerHTML !== '')el.innerHTML = innerHTML;var attrStr = baseInfo[2];var groups;while(groups = rAttrs.exec(attrStr))el.setAttribute(groups[1], groups[3]);}catch(e){return null;}// 重置正则表达式rTag.compile(rTag);rAttrs.compile(rAttrs);}return el;};
}();
七、与资源加载相关的属性和事件
资源加载首先当然是确定资源位置的 href属性 ,随之就是资源加载成功与否的 onload事件 和 onerror事件 ,对于IE5~8还多了一个 onreadystatechange事件 和与之相关的 readyState属性
onload事件 ,当资源加载完成后触发(注意:即使资源类型与LINK元素的type属性值不符,只要资源加载完成就会触发onload事件)。
onerror事件 ,当找不到资源时会触发(注意:IE5~11无论任何情况均不会触发该事件)
onreadystatechange事件 ,IE5~10下readyState变化就会触发该事件。
readyState属性 ,用于表示LINK元素当前的资源装载状态,默认值为"uninitialized",资源加载中为"loading",资源加载完成为"complete"(注意:资源加载完成不代表资源被成功加载)
八、资源加载实验
本次实验将创建 LINK元素 并对其的 href属性 分别赋予以下内容 test.css 、 fsjohnhuang.png 、 :0 、 空字符串 、 空白字符串 、 //:0 、 javascript:void 0 和 data:image/png,foo 。并订阅img元素的onload和onerror事件,IE5~10下还订阅了onreadystatechange事件,统计整理其在IE5~11、Chrome和FF下的行为特点和事件响应延时。具体实验统计如下:
测试环境:
1. 测试页面地址为http://localhost:9000/test.html
2. 图片fsjohnhuang.png的大小为12KB
3. test.css的大小为0KB
4. LINK元素已加入渲染树,rel属性值为stylesheet,disabled属性为false(注意:FF下disabled为true,依然会触发事件)
LINK元素加载资源的前提是加入到渲染树,rel属性值有效(Chrome下则还需要disabled为false)。
5. 通过DOM 0方式订阅事件
符号说明:
N/A 表示该列事件不触发
href属性值 | 备注 | Chrome | FireFox | IE5~11 | |||||||
onload事件 | onerror事件 | 备注 | onload事件 | onerror事件 | 备注 |
IE11 onload事件 |
IE11 onerror事件 |
IE5~10 on ready state change |
备注 | ||
test.css |
有效URI, URI自动补全为 http://localhost :9000/test.css |
首次延时为5ms | N/A | 后续读取缓存为0~1ms | 首次延时为5ms | N/A | 后续读取缓存为0~1ms | 首次onload延时9ms,后续读取缓存则为0~1ms | N/A |
1. 首次加载时,先触 发两次onreadystate change事件,从"uninitialized"->"loading"-> "complete"。然后 触发onload事件。 2. 后续则从缓存中加载 资源,先触发一次onreadystatechange 事件,从"unitialized"->"complete"。然后触 发onload事件。 |
|
fsjohnhuang.png |
有效URI, URI自动补全为 http://localhost :9000/fsjohnhu ang.png |
首次延时为4ms | N/A | 后续读取缓存为0~2ms | N/A | 延时为3~7ms | 不会缓存资源 | 延时为7~33ms | N/A |
IE9~10中 触发两次onreadystatechange 事件(延时0~2ms, 10~12ms), "unintialized"-> "loading"-> "complete", 。然后 触发onload事件 (延时为6~22ms) 不会对资源进行缓存 IE5~8中 1.首次加载会发起请求, 会触发两次onreadystatechange 事件,"uninitialized"- >"loading"-> "complete"。然后 在触发onload事件,缓存资源; 2.后续加载会从缓存 读取资源,触发一次onreadystatechange 事件,"uninitialized" ->"complete"。然后 在触发onload事件。 |
|
:0 |
无效URI, URI自动补全为http://localhost :9000/:0 |
N/A | 延迟为6~300ms | 发起网络请求,返回404 HTTP状态码 | N/A | 延迟为13~30ms | 发起网络请求,返回404 HTTP状态码 | 延迟为10ms左右 | N/A |
触发两次onreadystatechange 事件(延时0~2ms, 10~12ms), "unintialized"-> "loading"-> "complete",然后在 触发onload事件(延时11~13ms) |
发起网络请求,返回404 HTTP状态码 |
空字符串,"" | 无效URI | N/A | N/A | 不发起请求 | N/A | N/A | 不发起请求 | 延时为0~1ms | N/A |
IE9~10中 1.首次加载,仅会触发onreadystatechange 事件,且仅从 "unitialized"-> "loading"; 2.后续加载, 先触发两次onreadystatechange 事件,且从 "unitialized"->"complete", 然后再触发onload事件 IE5~8中 1.首次加载,仅会触发 onreadystatechange 事件,且仅从 "unitialized"-> "loading"; 2.后续加载, 先触发一次onreadystatechang e事件,且从 "unitialized"->"complete", 然后再触发onload事 |
不发起网络请求 |
空白字符串," " | 无效URI | N/A | N/A | 不发起请求 | N/A | 延时为3~7ms | 不会对资源进行缓存 | 延时为5~22ms | N/A |
IE9~10中 触发一次onreadystatechange 事件, "uninitialized"- >"loading"-> "complete"。 然后在触发onload事件。不会缓存资源 IE5~8中 1.首次加载会发起请求, 会触发两次onreadystatechange 事件,"uninitialized"- >"loading"-> "complete"。然后 在触发onload事件,缓存资源; 2.后续加载会从缓存 读取资源,触发一次onreadystatechange 事件,"uninitialized" ->"complete"。然后 在触发onload事件。 |
|
//:0 | 无效URI,会自动补全为http://:0/ | N/A | N/A | 不发起请求 | N/A | 延时为1~4ms | 不会对资源进行缓存 | 延时为0~1ms | N/A |
IE9~10中 触发两次onreadystatechange 事件(延时0~2ms, 5~8ms),readyState 均为"complete", 然后在触发onload事件 (延时5~9ms) IE5~8中 触发一次onreadystatechange 事件(延时3ms),readyState为 "complete", 然后在触发 onload事件 (延时5~8ms) |
不会缓存资源 |
javascript:void 0 | 无效的JavaScript URI Scheme | N/A | 延时为0~8ms | 发起网络请求,但浏览器会取消该请求 | N/A | 延时为0~3ms | 发起网络请求,但浏览器会取消该请求 | N/A | N/A |
IE8~10中 会触发一次onreadystatechage 事件(2~4ms), "uninitialized" ->"loading" IE5~7中 每次加载均会在设置 `link.href= "javascript:void 0";` 时会报“无法设置href 属性。已中止操作”的 异常,但后面依然会 触发一次onreadystatechage 事件(2~4ms), "uninitialized"->"loading" |
资源一直处于加载未完成的状态 |
data:image/png,f | 无效的Data URI Scheme | 延时为0~7ms | N/A | 不会触发网络请求 | N/A | 延时为0~2ms | 不会触发网络请求 | 延时为0~1ms | N/A |
IE9~10中 触发两次onreadystatechange事件(延时1~2ms, 5~8ms),readyState均为"complete",然后在触发onload事件(延时5~9ms) IE5~8中 触发一次onreadystatechange事件(延时3ms),readyState为"complete",然后在触发onload事件(延时5~8ms) |
不会触发网络请求 |
从表格数据得到以下规律:
IE下
1. onerror绝对不会被触发;
2. IE5~8中的onload事件均在readyState为"complete"且onreadystatechange事件触发后才触发,对于IE11 中没有readyState属性和onreadystatechange事件,则参考IE5~8中的readyState,若能转换 为"complete"则会触发onload事件。
3. 对于有效样式资源(如test.css),首次加载readyState值 从"uninitialized"->"loading"->"complete",然后缓存资源;后续对加载同一资源时则从缓存读 取,readyState值从"uninitialized"->"complete"。
4. 对于与资源MIME类型与type属性值不符的资源(如fsjohnhuang.png,空白字符串),IE9~11均不会对资源进行缓存,且 readyState值从"uninitialized"->"loading"->"complete";而IE5~8则会对资源进行缓 存,readyState值从"uninitialized"->"complete"。
5. 对于无效路径的HTTP URI Scheme资源(如:0),IE5~11均不会对资源进行缓存,readyState值从"uninitialized"->"loading"->"complete";
6. 对于空字符串,IE行为十分诡异,IE9~10中首次加载readyState值从"uninitialized"->"loading",后续加 载则触发两次onreadystatechange事件,且readyState值 从"unintialized"->"complete"->"complete"。IE5~8中首次加载readyState值 从"uninitialized"->"loading",后续加载则触发一次onreadystatechange事件,readyState值 从"unintialized"->"complete"。
7. 对于//:0,IE会取消网络请求,IE9~10中会触发两次onreadystatechange事件,且readyState值 从"unintialized"->"complete"->"complete"。IE5~8中触发一次 onreadystatechange事件,且readyState值从"unintialized"->"complete"。
8. 对于JavaScript URI Scheme资源(如javascript:void 0),IE行为较为统一,均触发一次onreadystatechange事件,且readyState值 从"unintialized"->"loading"。而IE5~7会在执行a.href='javascript:void 0'时报"无法设置href属性。已中止操作”的异常。
9. 对于Data URI Scheme资源(如data:image/png,f),IE行为较为统一,均会触发onreadystatechange事件,且 readyState值从"unintialized"->"complete"。区别在于IE9~10触发两次事件,IE5~8触发一次。
Chrome下
1. 对于有效路径资源(如test.css,fsjohnhuang.png),均加载并缓存起来,然后触发onload事件;
2. 对于空字符串、空白字符串和//:0,均不作为;
3. 对于无效路径的HTTP URI Scheme资源(如:0),触发onerror事件;
4. 对于JavaScript URI Scheme资源(如javascript:void 0),浏览器会取消其网络请求,触发onerror事件;
5. 对于Data URI Scheme资源(如data:image/png,f),不管资源是否有效均触发onload事件。
FF下
1. 对于有效路径资源且资源类型与type属性值匹配的(如test.css),将加载并缓存起来,然后触发onload事件;
2. 对于无效路径资源或资源类型与type属性值不匹配的(如fsjohnhuang.png,:0,//:0,空白字符串),则触发onerror事件;
3. 对于空字符串,则不作为;
4. 对于JavaScript URI Scheme资源(如javascript:void 0),浏览器会取消其网络请求,触发onerror事件;
5. 对于Data URI Scheme资源(如data:image/png,f),资源有效则触发onload事件,无效则触发onerror事件。
九、总结
若有纰漏请各位指正,谢谢!
JS魔法堂:LINK元素深入详解相关推荐
- 【转】Java魔法堂:String.format详解
Java魔法堂:String.format详解 目录 一.前言 二.重载方法 三.占位符 四.对字符.字符串进行格式化 五.对整数进行格式化 六.对 ...
- bash魔法堂:History用法详解
Brief 又要敲那条长到没朋友的命令了,真心不再爱了... 有了history这条命令我想大家可以再爱一次了吧! >history 语法: history [n | -c | -raw his ...
- Java魔法堂:枚举类型详解
一.前言 Java的枚举类型相对C#来说具有更灵活可配置性,Java的枚举类型可以携带更多的信息. // C# enum MyColor{RED = 0,BLUE = 1 } Console.Writ ...
- Java魔法堂:注解用法详解——@SuppressWarnings
一.前言 编码时我们总会发现如下变量未被使用的警告提示: 上述代码编译通过且可以运行,但每行前面的"感叹号"就严重阻碍了我们判断该行是否设置的断点了.这时我们可以在方法前添加 @S ...
- Java魔法堂:注解用法详解——@SuppressWarnings(转)
一.前言 编码时我们总会发现如下变量未被使用的警告提示: 上述代码编译通过且可以运行,但每行前面的"感叹号"就严重阻碍了我们判断该行是否设置的断点了.这时我们可以在方法前添加 @S ...
- JS魔法堂:初探传说中的setImmediate函数
一.前言 由于JavaScript程序为单线程,因此在执行长时间的操作时(如循环和递归操作)到导致UI线程长期被阻塞,无法响应用户操作请求(如点击按钮等),让用户体验大打折扣.于是想到将一个长时间 ...
- JS魔法堂:属性、特性,傻傻分不清楚
一.前言 或许你和我一样都曾经被下面的代码所困扰 var el = document.getElementById('dummy'); el.hello = "test"; con ...
- JS魔法堂:不完全国际化本地化手册 之 拓展篇
前言 最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求--国际化&本地化.熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已. ...
- JS魔法堂:判断节点位置关系
一.前言 在polyfill querySelectorAll 和写弹出窗时都需要判断两个节点间的位置关系,通过jQuery我们可以轻松搞定,但原生JS呢?下面我将整理各种判断方法,以供日后查阅. 二 ...
- JS魔法堂:doctype我们应该了解的基础知识
一.前言 什么是doctype?其实我们一直使用,却很少停下来看清楚它到底是什么,对网页有什么作用.本篇将和大家一起探讨那个默默无闻的doctype吧! 二.什么是doctype doctype或DT ...
最新文章
- LeetCode简单题之数组异或操作
- java cpu过高排查_CPU使用率过高,访问页面的速度越来越慢?今天我教你解决
- MySQL—数据库表的完整性约束(非外键约束)
- A 子类继承父类,子类的构造函数会覆盖父类的构造函数
- 获取某一条_想获取流量?这几种工具是必须要有的,能帮你获客快人一步!
- Java常用设计模式————单例模式
- Spring整合Mybatis和JUnit
- XOR and Favorite Number(CF-617E)
- 笔记本vm系统的分辨率不好调整_苹果笔记本电脑怎么设置使用今声优盒
- Swift:带有私有设置方法的公有属性
- Bailian2689 大小写字母互换【文本】(POJ NOI0107-14)
- Windows远程访问Linux (Ubuntu)服务器
- FIT2CLOUD飞致云旗下多云管理平台完成华为FusionCompute兼容性测试
- Ember.js 初学指南
- 亚马逊广告投放策略卖家们知多少?
- 3.知识图谱业务落地技术推荐之国内知识图谱平台汇总(竞品)[阿里、腾讯、华为等】
- linux ps aux tty,linux ps命令中的tty表示什么意思?
- CGroup的原理和使用
- 阿里云将在2018云栖大会·重庆峰会上推出重磅物联网平台
- catia高级拔模_解读CATIA拔模的秘密
热门文章
- SQL server 远程连接 1326错误
- C# 查询集合中某个元素里的值
- easyui combobox自动搜索提示功能
- js 调用 php,利用js调用后台php进行数据处理原码
- LINUX文件图标变化:有时右键菜单刷新可以,有时需要重启机器
- sofia-sip-ua >= 1.12.12… configure: error: no usable sofia-sip; please install sofia-sip-ua devel pa
- 重新编译Telepresence,谈如何写编译脚本
- 坐高铁只能用身份证了?
- 只能用光盘启动怎么办?
- tcp 裸流 发送 html,ffmpeg 命令学习