You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

206 lines
9.2 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# HTML替换型元素为什么link一个CSS要用href而引入js要用src呢
你好我是winter。我们今天来讲讲替换型元素。
我们都知道一个常识,一个网页,它是由多个文件构成的,我们在之前的课程中,已经学过了一种引入文件的方案:链接。
这节课我们要讲的替换型元素,就是另一种引入文件的方式了。替换型元素是把文件的内容引入,替换掉自身位置的一类标签。
我们首先来看一种比较熟悉的标签script标签。
## script
我们之所以选择先讲解script标签是因为script标签是为数不多的既可以作为替换型标签又可以不作为替换型标签的元素。
我们先来看看script标签的两种用法
```HTML
<script type="text/javascript">
console.log("Hello world!");
</script>
<script type="text/javascript" src="my.js"></script>
```
这个例子中我们展示了两种script标签的写法一种是直接把脚本代码写在script标签之间另一种是把代码放到独立的js文件中用src属性引入。
这两种写法是等效的。我想这种等效性可以帮助你理解替换型元素的“替换”是怎么一回事。
这里我们就可以回答标题中的问题了凡是替换型元素都是使用src属性来引用文件的而我们之前的课程中已经讲过链接型元素是使用href标签的。
虽然我不知道当初是怎么设计的但是style标签并非替换型元素不能使用src属性这样我们用link标签引入CSS文件当然就是用href标签啦。
接下来我们再看看别的替换型元素先来了解一下img标签。
## img
毫无疑问我们最熟悉的替换型标签就是img标签了几乎每个前端都会日常使用img标签。
img标签的作用是引入一张图片。这个标签是没有办法像script标签那样作为非替换型标签来使用的它必须有src属性才有意义。
如果一定不想要引入独立文件可以使用data uri我们来看个实际的例子
```HTML
<img src='data:image/svg+xml;charset=utf8,<svg version="1.1" xmlns="http://www.w3.org/2000/svg"><rect width="300" height="100" style="fill:rgb(0,0,255);stroke-width:1;stroke:rgb(0,0,0)"/></svg>'/>
```
这个例子中我们使用了data uri作为图片的src这样并没有产生独立的文件客观上做到了和内联相同的结果这是一个常用的技巧。
img标签可以使用width和height指定宽度和高度。也可以只指定其中之一。我们看个例子
```HTML
<img src='data:image/svg+xml;charset=utf8,<svg width="600" height="400" version="1.1"
xmlns="http://www.w3.org/2000/svg"><ellipse cx="300" cy="150" rx="200" ry="80"
style="fill:rgb(200,100,50);
stroke:rgb(0,0,100);stroke-width:2"/></svg>' width="100"/>
```
这个例子中,为了方便你理解,我们把图片换成了椭圆,我们可以看到,当我们指定了宽度后,图片被**等比例缩放了**。这个特性非常重要,适用于那种我们既要限制图片尺寸,又要保持图片比例的场景。
如果从性能的角度考虑,建议你同时给出图片的宽高,因为替换型元素加载完文件后,如果尺寸发生变换,会触发重排版(这个概念我们在浏览器原理部分已经讲过,可以复习一下)。
此处要重点提到一个属性alt属性这个属性很难被普通用户感知对于视障用户非常重要可以毫不夸张地讲给img加上alt属性已经做完了可访问性的一半。
img标签还有一组重要的属性那就是srcset和sizes它们是src属性的升级版所以我们前面讲img标签必须有src属性这是不严谨的说法
这两个属性的作用是在不同的屏幕大小和特性下使用不同的图片源。下面一个例子也来自MDN它展示了srcset和sizes的用法
```JavaScript
<img srcset="elva-fairy-320w.jpg 320w,
elva-fairy-480w.jpg 480w,
elva-fairy-800w.jpg 800w"
sizes="(max-width: 320px) 280px,
(max-width: 480px) 440px,
800px"
src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
```
srcset提供了根据屏幕条件选取图片的能力但是其实更好的做法是使用picture元素。
## picture
picture元素可以根据屏幕的条件为其中的img元素提供不同的源它的基本用法如下
```HTML
<picture>
<source srcset="image-wide.png" media="(min-width: 600px)">
<img src="image-narrow.png">
</picture>
```
picture元素的设计跟audio和video保持了一致稍后我会为你讲解这两个元素它跟img搭配srcset和sizes不同它使用source元素来指定图片源并且支持多个。
这里的media属性是media query跟CSS的@media规则一致。
## video
在HTML5早期的设计中video标签跟img标签类似也是使用src属性来引入源文件的不过我想应该是考虑到了各家浏览器支持的视频格式不同现在的video标签跟picture元素一样也是提倡使用source的。
下面例子是一个古典的video用法
```HTML
<video controls="controls" src="movie.ogg">
</video>
```
这个例子中的代码用src来指定视频的源文件。但是因为一些历史原因浏览器对视频的编码格式兼容问题分成了几个派系这样对于一些兼容性要求高的网站我们使用单一的视频格式是不合适的。
现在的video标签可以使用source标签来指定接入多个视频源。
```HTML
<video controls="controls" >
<source src="movie.webm" type="video/webm" >
<source src="movie.ogg" type="video/ogg" >
<source src="movie.mp4" type="video/mp4">
You browser does not support video.
</video>
```
从这个例子中我们可以看到source标签除了支持media之外还可以使用type来区分源文件的使用场景。
video标签的内容默认会被当做不支持video的浏览器显示的内容吗因此如果要支持更古老的浏览器还可以在其中加入object或者embed标签这里就不详细展开了。
video中还支持一种标签track。
track是一种播放时序相关的标签它最常见的用途就是字幕。track标签中必须使用 srclang 来指定语言此外track具有kind属性共有五种。
* subtitles就是字幕了不一定是翻译也可能是补充性说明。
* captions报幕内容可能包含演职员表等元信息适合听障人士或者没有打开声音的人了解音频内容。
* descriptions视频描述信息适合视障人士或者没有视频播放功能的终端打开视频时了解视频内容。
* chapters用于浏览器视频内容。
* metadata给代码提供的元信息对普通用户不可见。
一个完整的video标签可能会包含多种track和多个source这些共同构成了一个视频播放所需的全部信息。
## audio
接下来我们来讲讲audio跟picture和video两种标签一样audio也可以使用source元素来指定源文件。我们看一下例子
```HTML
<audio controls>
<source src="song.mp3" type="audio/mpeg">
<source src="song.ogg" type="audio/ogg">
<p>You browser does not support audio.</p>
</audio>
```
但比起videoaudio元素的历史问题并不严重所以使用src也是没有问题的。
## iframe
最后我们来讲一下iframe这个标签能够嵌入一个完整的网页。
不过在移动端iframe受到了相当多的限制它无法指定大小里面的内容会被完全平铺到父级页面上。
同时很多网页也会通过http协议头禁止自己被放入iframe中。
iframe标签也是各种安全问题的重灾区。opener、window.name、甚至css的opacity都是黑客可以利用的漏洞。
因此在2019年当下这个时间点任何情况下我都不推荐在实际开发中用以前的iframe。
当然不推荐使用是一回事因为没人能保证不遇到历史代码我们还是应该了解一下iframe的基本用法
```HTML
<iframe src="http://time.geekbang.org"></iframe>
```
这个例子展示了古典的iframe用法。
在新标准中为iframe加入了sandbox模式和srcdoc属性这样给iframe带来了一定的新场景。我们来看看例子
```HTML
<iframe sandbox srcdoc="<p>Yeah, you can see it <a href="/gallery?mode=cover&amp;amp;page=1">in my gallery</a>."></iframe>
```
这个例子中使用srcdoc属性创建了一个新的文档嵌入在iframe中展示并且使用了sandbox来隔离。
这样这个iframe就不涉及任何跨域问题了。
## 总结
这节课我们又认识了一组HTML元素替换型元素。它们的特点是引入一个外部资源来进入页面替换掉自身的位置。
我们通过对script、img、picture、audio、video、iframe几个标签的讲解了解了不同的资源引入方式
* src属性
* srcset属性
* source标签
* srcdoc属性。
这中间我们也介绍了一些小技巧比如src属性的好朋友data uri这在实际开发中非常有用。
最后留给你一个小问题请查资料总结一下在多数现代浏览器兼容的范围内src属性支持哪些协议的uri如http和我们提到的data