这是我参与「第五届青训营 」笔记创作活动的第5天,之前都在实习,就没有发布笔记。 下面就和大家分享一下我学习前端以及HTML的第五份笔记吧
1.2.2 视频和音频内容
web 中的音频和视频
web 开发者们一直以来想在 Web 中使用音频和视频,自 21 世纪初以来,我们的带宽开始能够支持任意类型的视频(视频文件比文本和图片要大的多)。在早些时候,传统的 web 技术(如 HTML)不能够在 Web 中嵌入音频和视频,所以一些像 Flash (后来有 Silverlight ) 的专利技术在处理这些内容上变得很受欢迎。这些技术能够正常的工作,但是却有着一系列的问题,包括无法很好的支持 HTML/CSS 特性、安全问题,以及可行性问题。
传统的解决方案能够解决许多这样的问题,前提是它能够正确的工作。幸运的是,几年之后 HTML5 标准提出,其中有许多的新特性,包括 <video> 和 <audio> 标签,以及一些 JavaScript 和 APIs 用于对其进行控制。在这里,我们不讨论有关 JavaScript 的问题,仅仅讲解有关 HTML 的基础。
备注: 在你开始之前,你应当了解一些 OVPs (在线视频提供商) 例如 YouTube 、Dailymotion 、Vimeo、Bilibili等,以及在线音频提供商例如 Soundcloud。这些公司提供方便、简单的方式来支持视频,所以你不必担心庞大的带宽消耗。OVPS 甚至提供现成的代码用于为你的 web 网页嵌入视频/音频。如果你使用这样的服务,你便可以避免在这篇文章中我们将讨论的一些难题。在下一篇文章中,我们将会再讨论这样的服务。
元素
<video> 允许你轻松地嵌入一段视频。一个简单的例子如下:
<video src="rabbit320.webm" controls>
<p>你的浏览器不支持 HTML5 视频。可点击<a href="rabbit320.mp4">此链接</a>观看</p>
</video>
当中的一些属性如下:
src
同 <img> 标签使用方式相同,src 属性指向你想要嵌入网页当中的视频资源,他们的使用方式完全相同。
controls
用户必须能够控制视频和音频的回放功能。你可以使用 controls 来包含浏览器提供的控件界面,同时你也可以使用合适的 JavaScript API 创建自己的界面。界面中至少要包含开始、停止以及调整音量的功能。
<video> 标签内的内容
这个叫做后备内容 — 当浏览器不支持 <video> 标签的时候,就会显示这段内容,这使得我们能够对旧的浏览器提供回退内容。你可以添加任何后备内容,在这个例子中我们提供了一个指向这个视频文件的链接,从而使用户至少可以访问到这个文件,而不会局限于浏览器的支持。
已嵌入视频文件的网页样式如下:
使用多个播放源以提高兼容性
以上的例子中有一个问题,你可能已经注意到了,如果你尝试使用像 Safari 或者 Internet Explorer 这些浏览器来访问上面的链接。视频并不会播放,这是因为不同的浏览器对视频格式的支持不同。幸运的是,你有办法防止这个问题发生。
媒体文件的内容
我们先来快速的了解一下术语。像 MP3、MP4、WebM 这些术语叫做容器格式。他们定义了构成媒体文件的音频轨道和视频轨道的储存结构,其中还包含描述这个媒体文件的元数据,以及用于编码的编码译码器等等。
一个格式为 WebM 的电影包含视频轨道,音频轨道和文本轨道,其中视频轨道包含一个主视频轨道和一个可选的 Angle 轨道;音频轨道包含英语和西班牙语的音频轨道,还有一个英语评论的音频轨道;文字轨道包含英语和西班牙语的字幕轨道,如下图所示:
为了编解码器(codec)编码媒体,容器中的音频和视频轨道以适合的格式保存。音频轨道和视频轨道使用不同的格式。每个音频轨道都使用音频编解码器 (en-US)进行编码,而视频轨道则使用视频编解码器进行编码。如前所述,不同的浏览器支持不同的视频和音频格式,以及不同的容器格式(如 MP3、MP4 和 WebM,这些格式又可以包含不同类型的视频和音频)。
例如:
- WebM 容器通常包括了 Opus 或 Vorbis 音频和 VP8/VP9 视频。这在所有的现代浏览器中都支持,除了他们的老版本。
- MP4 容器通常包括 AAC 以及 MP3 音频和 H.264 视频。这在所有的现代浏览器中都支持,还有 Internet Explorer。
- 老式的 Ogg 容器往往支持 Ogg Vorbis 音频和 Ogg Theora 视频。主要在 Firefox 和 Chrome 当中支持,不过这个容器已经被更强大的 WebM 容器所取代。
有一些特殊情况。例如,对于某些类型的音频,通常编解码器的数据存储没有容器或简化容器。其中一个例子就是 FLAC 编解码器,它通常存储在 FLAC 文件中,FLAC 文件只是 FLAC 的原始轨迹。
另一种情况是一直流行的 MP3 文件。“MP3 文件”实际上是存储在 MPEG 或 MPEG-2 容器中的 MPEG-1 音频层 III(MPEG-1 Audio Layer III,MP3)音频轨道。这一点特别有趣,因为尽管大多数浏览器不支持在<video>和<audio>元素中使用 MPEG 媒体,但由于 MP3 的流行,它们可能仍然支持 MP3。
音频播放器将会直接播放音频文件,例如 MP3 和 Ogg 文件。这些不需要容器。
浏览器所支持的媒体文件
你也许会疑惑为什么会有这样的情况存在。MP3 (音频格式) 和 MP4/H.264 (视频格式) 是被广泛支持的两种格式,并且质量良好。然而,他们却有专利的阻碍 — MP3 的专利会持续到 2017 年(就在我翻译这篇文章的当天,MP3 专利解除了),而 H.264 会持续到 2027 年早期。意思也就是说浏览器若想要支持这些格式,就得支付高额的费用。此外,许多人反对软件技术垄断,支持开放的格式。这就是为什么我们需要准备不同的格式来兼容不同的浏览器。
刚刚所说的格式主要用于将音频和视频压缩成可管理的文件(原始的音频和视频文件非常大)。浏览器包含了不同的 Codecs,,如 Vorbis 和 H.264,它们用来将已压缩的音频和视频转化成二进制数字。不同的编码器和不同的容器都有各自的优缺点,在你更了解它们后,你可以自己选择使用哪个编码器和容器。
浏览器并不全支持相同的 codecs,所以你得使用几个不同格式的文件来兼容不同的浏览器。如果你使用的格式都得不到浏览器的支持,那么媒体文件将不会播放。
要使你的媒体文件在不同平台,不同设备的浏览器上都可观看,这需要多种编码器组合使用,但是这是一种非常麻烦的事,所以可以参考选择合适的容器来选择最适合的容器格式,同样地,参考选择视频编解码器和选择音频编解码器 (en-US)选择编码格式
需要记住的另一件事:同一款浏览器,移动版与桌面版支持的格式可能会有不同。最重要的是,它们都可以减轻媒体播放的处理负担(对于所有媒体或仅针对其内部无法处理的特定类型)。这意味着设备的媒体支持还部分取决于用户安装了什么软件。
我们该怎么做呢?请看如下例子(你可以点击这里查看网页,或者点击这里查看源代码):
<video controls>
<source src="rabbit320.mp4" type="video/mp4">
<source src="rabbit320.webm" type="video/webm">
<p>你的浏览器不支持 HTML5 视频。可点击<a href="rabbit320.mp4">此链接</a>观看</p>
</video>
现在我们将 src 属性从 <video> 标签中移除,转而将它放在几个单独的标签 <source> 当中。在这个例子当中,浏览器将会检查 <source> 标签,并且播放第一个与其自身 codec 相匹配的媒体。你的视频应当包括 WebM 和 MP4 两种格式,这两种在目前已经足够支持大多数平台和浏览器。
每个 <source> 标签页含有一个 type 属性,这个属性是可选的,但是建议你添加上这个属性 — 它包含了视频文件的 MIME types ,同时浏览器也会通过检查这个属性来迅速的跳过那些不支持的格式。如果你没有添加 type 属性,浏览器会尝试加载每一个文件,直到找到一个能正确播放的格式,这样会消耗掉大量的时间和资源。
备注: 你可以在这里(HTML 媒体格式支持 (en-US))查看有关 MIME types 的支持。
其他 特性
这里有许多你可以用在 HTML5 <video> 上的特性,请看我们的第三个例子:
<video controls width="400" height="400"
autoplay loop muted
poster="poster.png">
<source src="rabbit320.mp4" type="video/mp4">
<source src="rabbit320.webm" type="video/webm">
<p>你的浏览器不支持 HTML5 视频。可点击<a href="rabbit320.mp4">此链接</a>观看</p>
</video>
这串代码将会给我们呈现出如下页面:
新的特性:
width 和 height
你可以用属性控制视频的尺寸,也可以用 CSS 来控制视频尺寸。无论使用哪种方式,视频都会保持它原始的长宽比 — 也叫做纵横比。如果你设置的尺寸没有保持视频原始长宽比,那么视频边框将会拉伸,而未被视频内容填充的部分,将会显示默认的背景颜色。
autoplay
这个属性会使音频和视频内容立即播放,即使页面的其他部分还没有加载完全。建议不要应用这个属性在你的网站上,因为用户们会比较反感自动播放的媒体文件。
loop
这个属性可以让音频或者视频文件循环播放。同样不建议使用,除非有必要。
muted
这个属性会导致媒体播放时,默认关闭声音。
poster
这个属性指向了一个图像的 URL,这个图像会在视频播放前显示。通常用于粗略的预览或者广告。
preload
这个属性被用来缓冲较大的文件,有 3 个值可选:
"none":不缓冲"auto":页面加载后缓存媒体文件"metadata":仅缓冲文件的元数据
你可以点击这里查看以上的例子,也可以点击这里查看源代码。注意我们并没有使用 autoplay 属性在这个版本的例子中 — 如果当页面一加载就开始播放视频的话,就不会看到 poster 属性的效果了。
标签
<audio> 标签与 <video> 标签的使用方式几乎完全相同,有一些细微的差别比如下面的边框不同,一个典型的例子如下:
<audio controls>
<source src="viper.mp3" type="audio/mp3">
<source src="viper.ogg" type="audio/ogg">
<p>你的浏览器不支持 HTML5 音频,可点击<a href="viper.mp3">此链接</a>收听。</p>
</audio>
这串代码将会产生如下的效果:
音频播放器所占用的空间比视频播放器要小,由于它没有视觉部件 — 你只需要显示出能控制音频播放的控件。一些与 HTML5 <video> 的差异如下:
<audio>标签不支持width/height属性 — 由于其并没有视觉部件,也就没有可以设置width/height的内容。- 同时也不支持
poster属性 — 同样,没有视觉部件。
除此之外,<audio> 标签支持所有 <video> 标签拥有的特性 — 你可以回顾上面的章节来了解更多的有关信息。
重新播放媒体
任何时候,你都可以在 Javascript 中调用 load() 方法来重置媒体。如果有多个由 <source> 标签指定的媒体来源,浏览器会从选择媒体来源开始重新加载媒体。
const mediaElem = document.getElementById("my-media-element");
mediaElem.load();
音轨增删事件
你可以监控媒体元素中的音频轨道,当音轨被添加或删除时,你可以通过监听相关事件来侦测到。具体来说,通过监听 AudioTrackList (en-US) 对象的 addtrack 事件(即 HTMLMediaElement.audioTracks 对象),你可以及时对音轨的增加做出响应。
const mediaElem = document.querySelector("video");
mediaElem.audioTracks.onaddtrack = function(event) {
audioTrackAdded(event.track);
}
你可以在我们的 TrackEvent (en-US) 文档中找到更多有用的信息。
显示音轨文本
现在,我们将讨论一个略微先进的概念,这个概念将会十分的有用。许多人不想(或者不能)听到 Web 上的音频/视频内容,至少在某些情况下是这样的,比如:
- 许多人患有听觉障碍(通常来说是很难听清声音的人,或者聋人),所以他们不能听见音频中的声音。
- 另外的情况可能是由于人们并不能听音频,可能是因为他们在一个非常嘈杂的环境当中(比如在一个拥挤的酒吧内恰好赶上了球赛),也可能是由于他们并不想打扰到其他人(比如在一个十分安静的地方,例如图书馆)。
- 有一些人他们不说音频当中的语言,所以他们听不懂,因此他们想要一个副本或者是翻译来帮助他们理解媒体内容。
给那些听不懂音频语言的人们提供一个音频内容的副本岂不是一件很棒的事情吗?所以,感谢 HTML5 <video> 使之成为可能,有了 WebVTT (en-US) 格式,你可以使用 <track> 标签。
WebVTT 是一个格式,用来编写文本文件,这个文本文件包含了众多的字符串,这些字符串会带有一些元数据,它们可以用来描述这个字符串将会在视频中显示的时间,甚至可以用来描述这些字符串的样式以及定位信息。这些字符串叫做 cues ,你可以根据不同的需求来显示不同的样式,最常见的如下:
- subtitles
通过添加翻译字幕,来帮助那些听不懂外国语言的人们理解音频当中的内容。
- captions
同步翻译对白,或是描述一些有重要信息的声音,来帮助那些不能听音频的人们理解音频中的内容。
- timed descriptions
将文字转换为音频,用于服务那些有视觉障碍的人。
一个典型的 WebVTT 文件如下:
1
00:00:22.230 --> 00:00:24.606
第一段字幕
2
00:00:30.739 --> 00:00:34.074
第二段
...
让其与 HTML 媒体一起显示,你需要做如下工作:
- 以 .vtt 后缀名保存文件。
- 用
<track>标签链接 .vtt 文件,<track>标签需放在<audio>或<video>标签当中,同时需要放在所有<source>标签之后。使用kind属性来指明是哪一种类型,如 subtitles、captions、descriptions。然后,使用srclang来告诉浏览器你是用什么语言来编写的 subtitles。
如下:
<video controls>
<source src="example.mp4" type="video/mp4">
<source src="example.webm" type="video/webm">
<track kind="subtitles" src="subtitles_en.vtt" srclang="en">
</video>
上面这串代码会显示一段带有字幕的视频,如下:
如果你想了解更多细节,你可以阅读 Adding captions and subtitles to HTML5 video。在 Github 上你可以找到与本文相关的样例,他们由 Ian Devlin 编写,点击这里可以查看该样例,或者点击这里查看源代码。这个样例使用了 JavaScript 代码,它使得用户可以选择不同的字幕。注意,若想要显示字幕,你需要点击 "CC" 按钮,并且选择一种语言 — English, Deutsch, 或 Español。
备注: 文本轨道会使你的网站更容易被搜索引擎抓取到(SEO),由于搜索引擎的文本抓取能力非常强大,使用文本轨道甚至可以让搜索引擎通过视频的内容直接链接。
1.2.3 从对象到 iframe - 其他嵌入技术
嵌入的简史
很久以前,很流行在网络上使用框架创建网站——网站的一小部分存储于单独的 HTML 页面中。这些被嵌入在一个称为框架集的主文档中,它允许你指定每个框架能够填充在屏幕上的区域,非常像调整表格的列和行的大小。这些做法在 90 年代中期至 90 年代后期被认为是比较酷的,有证据表明,将网页分解成较小的块,这样有利于下载速度——尤其是在那时网络连接速度太慢的情况下更为明显。然而,这些技术有很多问题,随着网络速度越来越快,这些技术带来的问题远超过它们带来的积极因素,所以你再也看不到它们被使用了。
一小段时间之后(20 世纪 90 年代末,21 世纪初),插件技术变得非常受欢迎,例如 Java Applet 和 Flash——这些技术允许网络开发者将丰富的内容嵌入到网页中,例如视频和动画等,这些内容不能通过 HTML 单独实现。嵌入这些技术是通过诸如 <object> 和较少使用的 <embed> 元素来实现的,当时它们非常有用。由于许多问题,包括无障碍、安全性、文件大小等,它们已经过时了; 如今,大多数移动设备不再支持这些插件,桌面端也逐渐不再支持。
最后,<iframe> 元素出现了(连同其他嵌入内容的方式,如 <canvas>、<video> 等),它提供了一种将整个 web 页嵌入到另一个网页的方法,看起来就像那个 web 页是另一个网页的一个 <img> 或其它元素一样。<iframe> 现在经常被使用。
了解完历史之后,让我们继续往下看以了解如何使用它们。
Iframe 详解
是不是很简单又有趣呢?<iframe> 元素旨在允许你将其他 Web 文档嵌入到当前文档中。这很适合将第三方内容嵌入你的网站,你可能无法直接控制,也不希望实现自己的版本——例如来自在线视频提供商的视频,Disqus 等评论系统,在线地图提供商,广告横幅等。你通过本课程使用的实时可编辑示例就是使用 <iframe> 实现的。
我们会在后面提到,关于 <iframe> 有一些严重的安全隐患需要考虑,但这并不意味着你不应该在你的网站上使用它们——它只需要一些知识和仔细地思考。让我们更详细地探索这些代码。假设你想在其中一个网页上加入 MDN 词汇表,你可以尝试以下方式:
<iframe src="https://developer.mozilla.org/zh-CN/docs/Glossary"
width="100%" height="500" frameborder="0"
allowfullscreen sandbox>
<p> <a href="https://developer.mozilla.org/zh-CN/docs/Glossary">
Fallback link for browsers that don't support iframes
</a> </p>
</iframe>
此示例包括使用以下所需的 <iframe> 基本要素:
allowfullscreen
如果设置,<iframe>则可以通过全屏 API 设置为全屏模式(稍微超出本文的范围)。
frameborder
如果设置为 1,则会告诉浏览器在此框架和其他框架之间绘制边框,这是默认行为。0 删除边框。不推荐这样设置,因为在 CSS 中可以更好地实现相同的效果。border``: none;
src
该属性与 <video> / 元素表示文档中的图像。<img>一样包含指向要嵌入文档的 URL 路径。
width 和 height
这些属性指定你想要的 iframe 的宽度和高度。
备选内容
与 <video> 等其它类似元素相同,你可以在 <iframe></iframe> 标签之间包含备选内容,如果浏览器不支持 <iframe>,将会显示备选内容,这种情况下,我们已经添加了一个到该页面的链接。现在你几乎不可能遇到任何不支持 <iframe> 的浏览器。
sandbox
该属性需要在已经支持其它 <iframe> 功能(例如 IE 10 及更高版本)但稍微更现代的浏览器上才能工作,该属性可以提高安全性设置;我们将在下一节中更加详细地谈到。
备注: 为了提高速度,在主内容完成加载后,使用 JavaScript 设置 iframe 的
src属性是个好主意。这使你的页面可以更快地被使用,并减少你的官方页面加载时间(重要的 SEO 指标)。
安全隐患
以上我们提到了安全问题——现在我们来详细介绍一下这一点。我们并不期望你第一次就能完全理解所有内容; 我们只想让你意识到这一问题,在你更有经验并开始考虑在你的实验和工作中使用 <iframe> 时为你提供参考。此外,没有必要害怕和不使用 <iframe>——你只需要谨慎一点。继续看下去吧...
浏览器制造商和 Web 开发人员了解到网络上的坏人(通常被称为黑客,或更准确地说是破解者),如果他们试图恶意修改你的网页或欺骗人们进行不想做的事情时常把 iframe 作为共同的攻击目标(官方术语:攻击向量),例如显示用户名和密码等敏感信息。因此,规范工程师和浏览器开发人员已经开发了各种安全机制,使<iframe>更加安全,这有些最佳方案值得我们考虑——我们将在下面介绍其中的一些。
备注: 单击劫持是一种常见的 iframe 攻击,黑客将隐藏的 iframe 嵌入到你的文档中(或将你的文档嵌入到他们自己的恶意网站),并使用它来捕获用户的交互。这是误导用户或窃取敏感数据的常见方式。
一个快速的例子——尝试在浏览器中加载上面的例子——你也可以 在 Github 上找到它(参见源代码)。你将不会看到任何内容,但如果你点击浏览器开发者工具中的控制台,你会看到一条消息,告诉你为什么没有显示内容。在 Firefox 中,你会被告知:“X-Frame-Options 拒绝加载 https://developer.mozilla.org/zh-CN/docs/Glossary。这是因为构建 MDN 的开发人员已经在网站页面的服务器上设置了一个不允许被嵌入到<iframe>的设置(请参阅配置 CSP 指令)这是有必要的——整个 MDN 页面被嵌入在其它页面中没有多大意义,除非你想要将其嵌入到你的网站上并将其声称为自己的内容,或尝试通过单击劫持来窃取数据,这都是非常糟糕的事情。此外,如果每个人都这样做,所有额外的带宽将花费 Mozilla 很多资金。
只有在必要时嵌入
有时嵌入第三方内容(例如 YouTube 视频和地图)是有意义的,但如果你只在完全需要时嵌入第三方内容,你可以省去很多麻烦。网络安全的一个很好的经验法则是“你怎么谨慎都不为过,如果你决定要做这件事,多检查一遍;如果是别人做的,在被证明是安全的之前,都假设这是危险的。 ”
除了安全问题,你还应该意识到知识产权问题。无论在线内容还是离线内容,绝大部分内容都是有版权的,甚至是一些你没想到有版权的内容(例如,Wikimedia Commons 上的大多数图片)。不要在网页上展示一些不属于你的内容,除非你是所有者或所有者给了你明确的、书面的许可。对于侵犯版权的惩罚是严厉的。再说一次,你再小心也不为过。
如果内容获得许可,你必须遵守许可条款。例如,MDN 上的内容是在 CC-BY-SA 下许可的,这意味着,如果你要引用我们的内容,就必须用适当的方式注明来源,即使你对内容做了实质性的修改。
使用 HTTPS
HTTPS 是 HTTP 的加密版本。你应该尽可能使用 HTTPS 为你的网站提供服务:
- HTTPS 减少了远程内容在传输过程中被篡改的机会,
- HTTPS 防止嵌入式内容访问你的父文档中的内容,反之亦然。
使用 HTTPS 需要一个安全证书,这可能是昂贵的(尽管 Let's Encrypt 让这件事变得更容易),如果你没有,可以使用 HTTP 来为你的父文档提供服务。但是,由于 HTTPS 的第二个好处,无论成本如何,你绝对不能使用 HTTP 嵌入第三方内容(在最好的情况下,你的用户的 Web 浏览器会给他们一个可怕的警告)。所有有声望的公司,例如 Google Maps 或 Youtube,当你嵌入内容时,<iframe> 将通过 HTTPS 提供——查看 <iframe> src 属性内的 URL。
备注: Github 页面允许默认情况下通过 HTTPS 提供内容,因此对托管内容很有用。如果你正在使用不同的托管,并且不确定,请向你的托管服务商询问。
始终使用 sandbox 属性
想尽可能减少攻击者在你的网站上做坏事的机会,那么你应该给嵌入的内容仅能完成自己工作的权限。当然,这也适用于你自己的内容。一个允许包含在其里的代码以适当的方式执行或者用于测试,但不能对其他代码库(意外或恶意)造成任何损害的容器称为沙盒。
未沙盒化(Unsandboxed)内容可以做得太多(执行 JavaScript,提交表单,弹出窗口等)默认情况下,你应该使用没有参数的 sandbox 属性来强制执行所有可用的限制,如我们前面的示例所示。
如果绝对需要,你可以逐个添加权限(sandbox=""属性值内)——请参阅 sandbox 所有可用选项的参考条目。其中重要的一点是,你永远不应该同时添加 allow-scripts 和 allow-same-origin 到你的 sandbox 属性中——在这种情况下,嵌入式内容可以绕过阻止站点执行脚本的同源安全策略,并使用 JavaScript 完全关闭沙盒。
备注: 如果攻击者可以欺骗人们直接访问恶意内容(在 iframe 之外),则沙盒无法提供保护。如果某些内容可能是恶意的(例如,用户生成的内容),请保证其是从不同的域向你的主站点提供的。
配置 CSP 指令
CSP 代表 内容安全策略,它提供一组 HTTP 标头(由 web 服务器发送时与元数据一起发送的元数据),旨在提高 HTML 文档的安全性。在 <iframe> 的安全性方面,你可以*将服务器配置为发送适当的 X-Frame-Options 标题*。这样做可以防止其他网站在其网页中嵌入你的内容(这将导致点击劫持和一系列其他攻击),正如我们之前看到的那样,MDN 开发人员已经做了这些工作。
备注: 你可以阅读 Frederik Braun 的帖子在 X-Frame-Options 安全性标头上来获取有关此主题的更多背景信息。显然,在这篇文章中已经解释得很清楚了。
和 元素
<embed> 和 <object> 元素的功能不同于 <iframe>——这些元素是用来嵌入多种类型的外部内容的通用嵌入工具,其中包括像 Java 小程序和 Flash,PDF(可在浏览器中显示为一个 PDF 插件)这样的插件技术,甚至像视频,SVG 和图像的内容!
备注: 插件是一种对浏览器原生无法读取的内容提供访问权限的软件。
然而,你不太可能使用这些元素——Applet 几年来一直没有被使用;由于许多原因,Flash 不再受欢迎(见下面的插件案例);PDF 更倾向于被链接而不是被嵌入;其他内容,如图像和视频都有更优秀、更容易元素来处理。插件和这些嵌入方法真的是一种传统技术,我们提及它们主要是为了以防你在某些情况下遇到问题,比如内部网或企业项目等。
如果你发现自己需要嵌入插件内容,那么你至少需要一些这样的信息:
<embed> 和 <object> 元素的功能不同于 <iframe>——这些元素是用来嵌入多种类型的外部内容的通用嵌入工具,其中包括像 Java 小程序和 Flash,PDF(可在浏览器中显示为一个 PDF 插件)这样的插件技术,甚至像视频,SVG 和图像的内容!备注: 插件是一种对浏览器原生无法读取的内容提供访问权限的软件。
| 嵌入内容的网址 | src | data |
| 嵌入内容的准确媒体类型 | type | type |
| 由插件控制的框的高度和宽度(以 CSS 像素为单位) | height width | height width |
| 名称和值,将插件作为参数提供 | 具有这些名称和值的 ad hoc 属性 | 单标签元素,包含在内 |
| 独立的 HTML 内容作为不可用资源的回退 | 不支持(已过时) | 包含在元素之后 |
备注:
<object>需要data属性,type属性或两者。如果你同时使用这两个,你也可以使用该typemustmatch属性(仅在 Firefox 中实现,在本文中)。typemustmatch保持嵌入文件不运行,除非type属性提供正确的媒体类型。typemustmatch因此,当你嵌入来自不同来源的内容(可以防止攻击者通过插件运行任意脚本)时,可以赋予重要的安全优势。
下面是一个使用该<embed>元素嵌入 Flash 影片的示例(请参阅此处的Github,并检查源代码):
<embed src="whoosh.swf" quality="medium"
bgcolor="#ffffff" width="550" height="400"
name="whoosh" align="middle" allowScriptAccess="sameDomain"
allowFullScreen="false" type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer">
很可怕,不是吗。Adobe Flash 工具生成的 HTML 往往更糟糕,使用嵌入<object>元素的<embed>元素来覆盖所有的基础(查看一个例子)。甚至有一段时间,Flash 被成功地用作 HTML5 视频的备用内容,但是这种情况越来越被认为是不必要的。
现在来看一个 <object> 将 PDF 嵌入一个页面的例子(参见实例和源代码):
<object data="mypdf.pdf" type="application/pdf"
width="800" height="1200" typemustmatch>
<p>You don't have a PDF plugin, but you can <a href="myfile.pdf">download the PDF file.</a></p>
</object>
PDF 是纸与数据之间重要的阶梯,但它们在无障碍上有些问题,并且可能难以在小屏幕上阅读。它们在一些圈子中仍然受欢迎,我们最好是用链接指向它们,而不是将其嵌入到网页中,以便它们可以在单独的页面上被下载或被阅读。
针对插件的情况
以前,插件在网络上是不可或缺的。还记得你必须安装 Adobe Flash Player 才能在线观看电影的日子吗?并且你还会不断地收到关于更新 Flash Player 和 Java 运行环境的烦人警报。Web 技术已经变得更加强大,那些日子已经结束了。对于大多数应用程序,现在是停止依赖插件传播内容,开始利用 Web 技术的时候了。
- 扩大你对大家的影响力。每个人都有一个浏览器,但插件越来越少,特别是在移动用户中。由于 Web 在很大程度上不需要依赖插件而运行,所以人们宁愿只是去竞争对手的网站而不是安装插件。
- 从 Flash 和其他插件附带的额外的无障碍问题中摆脱。
- 避免额外的安全隐患。即使经过无数次补丁, Adobe Flash 也是非常不安全的。2015 年,Facebook 的首席安全官 Alex Stamos 甚至要求 Adobe 停止 Flash。
那你该怎么办?如果你需要交互性,HTML 和JavaScript可以轻松地为你完成工作,而不需要 Java 小程序或过时的 ActiveX / BHO 技术。你可以使用 HTML5 视频来满足媒体需求,矢量图形SVG,以及复杂图像和动画画布。彼得·埃尔斯特(Peter Elst)几年前已经提到,对于工作 Adobe Flash 极少是正确的工具,除了专门的游戏和商业应用。对于 ActiveX,即使微软的Edge浏览器也不再支持。
1.2.4 在网页中添加矢量图形
什么是矢量图形?
在网上,你会和两种类型的图片打交道 — 位图和矢量图:
- 位图使用像素网格来定义 — 一个位图文件精确得包含了每个像素的位置和它的色彩信息。流行的位图格式包括 Bitmap (
.bmp), PNG (.png), JPEG (.jpg), and GIF (.gif.) - 矢量图使用算法来定义 — 一个矢量图文件包含了图形和路径的定义,电脑可以根据这些定义计算出当它们在屏幕上渲染时应该呈现的样子。 SVG 格式可以让我们创造用于 Web 的精彩的矢量图形。
此外,矢量图形相较于同样的位图,通常拥有更小的体积,因为它们仅需储存少量的算法,而不是逐个储存每个像素的信息。
SVG 是什么?
SVG 是用于描述矢量图像的XML语言。它基本上是像 HTML 一样的标记,只是你有许多不同的元素来定义要显示在图像中的形状,以及要应用于这些形状的效果。SVG 用于标记图形,而不是内容。非常简单,你有一些元素来创建简单图形,如<circle> 和<rect>。更高级的 SVG 功能包括 <feColorMatrix>(使用变换矩阵转换颜色)<animate> (矢量图形的动画部分)和 <mask>(在图像顶部应用模板)
作为一个简单的例子,以下代码创建一个圆和一个矩形:
<svg version="1.1"
baseProfile="full"
width="300" height="200"
xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="black" />
<circle cx="150" cy="100" r="90" fill="blue" />
</svg>
这将创建以下输出:
从上面的例子可以看出,SVG 很容易手工编码。是的,您可以在文本编辑器中手动编写简单的 SVG,但是对于复杂的图像,这很快就开始变得非常困难。为了创建 SVG 图像,大多数人使用矢量图形编辑器,如 Inkscape 或 Illustrator。这些软件包允许您使用各种图形工具创建各种插图,并创建照片的近似值(例如 Inkscape 的跟踪位图功能)。
SVG 除了迄今为止所描述的以外还有其他优点:
- 矢量图像中的文本仍然可访问(这也有利于 SEO)。
- SVG 可以很好地适应样式/脚本,因为图像的每个组件都是可以通过 CSS 或通过 JavaScript 编写的样式的元素。
那么为什么会有人想使用光栅图形而不是 SVG?其实 SVG 确实有一些缺点:
- SVG 非常容易变得复杂,这意味着文件大小会增加; 复杂的 SVG 也会在浏览器中占用很长的处理时间。
- SVG 可能比栅格图像更难创建,具体取决于您尝试创建哪种图像。
- 旧版浏览器不支持 SVG,因此如果您需要在网站上支持旧版本的 IE,则可能不适合(SVG 从 IE9 开始得到支持)。
由于上述原因,光栅图形更适合照片那样复杂精密的图像。
备注: 在 Inkscape 中,将文件保存为纯 SVG 以节省空间。另请参阅如何为 Web 准备 SVG。
将 SVG 添加到页面
在本节中,我们将介绍将 SVG 矢量图形添加到网页的不同方式。
快捷方式:<img>
要通过 <img>元素嵌入 SVG,你只需要按照预期的方式在 src 属性中引用它。你将需要一个height或width属性(或者如果您的 SVG 没有固有的宽高比)。如果您还没使用过元素,请阅读HTML 中的图片教程。
<img
src="equilateral.svg"
alt="triangle with all three sides equal"
height="87px"
width="100px" />
优点
- 快速,熟悉的图像语法与
alt属性中提供的内置文本等效。 - 可以通过在
<a>元素嵌套<img>,使图像轻松地成为超链接。
缺点
- 无法使用 JavaScript 操作图像。
- 如果要使用 CSS 控制 SVG 内容,则必须在 SVG 代码中包含内联 CSS 样式。 (从 SVG 文件调用的外部样式表不起作用)
- 不能用 CSS 伪类来重设图像样式(如
:focus)。
疑难解答和跨浏览器支持
对于不支持 SVG(IE 8 及更低版本,Android 2.3 及更低版本)的浏览器,您可以从src属性引用 PNG 或 JPG,并使用srcset属性 只有最近的浏览器才能识别)来引用 SVG。在这种情况下,仅支持浏览器将加载 SVG - 较旧的浏览器将加载 PNG:
<img src="equilateral.png" alt="triangle with equal sides" srcset="equilateral.svg">
您还可以使用 SVG 作为 CSS 背景图像,如下所示。在下面的代码中,旧版浏览器会坚持他们理解的 PNG,而较新的浏览器将加载 SVG:
background: url("fallback.png") no-repeat center;
background-image: url("image.svg");
background-size: contain;
像上面描述的<img>方法一样,使用 CSS 背景图像插入 SVG 意味着它不能被 JavaScript 操作,并且也受到相同的 CSS 限制。
如果 SVG 根本没有显示,可能是因为你的服务器设置不正确。如果是这个问题,这篇文章将告诉你正确方向。
如何在 HTML 中引入 SVG 代码
你还可以在文本编辑器中打开 SVG 文件,复制 SVG 代码,并将其粘贴到 HTML 文档中 - 这有时称为将SVG 内联或内联 SVG。确保您的 SVG 代码在<svg></svg>标签中(不要在外面添加任何内容)。这是一个非常简单的示例,您可以粘贴到文档中:
<svg width="300" height="200">
<rect width="100%" height="100%" fill="green" />
</svg>
优点
- 将 SVG 内联减少 HTTP 请求,可以减少加载时间。
- 您可以为 SVG 元素分配
class和id,并使用 CSS 修改样式,无论是在 SVG 中,还是 HTML 文档中的 CSS 样式规则。实际上,您可以使用任何 SVG 外观属性 作为 CSS 属性。 - 内联 SVG 是唯一可以让您在 SVG 图像上使用 CSS 交互(如
:focus)和 CSS 动画的方法(即使在常规样式表中)。 - 您可以通过将 SVG 标记包在
<a>元素中,使其成为超链接。
缺点
- 这种方法只适用于在一个地方使用的 SVG。多次使用会导致资源密集型维护(resource-intensive maintenance)。
- 额外的 SVG 代码会增加 HTML 文件的大小。
- 浏览器不能像缓存普通图片一样缓存内联 SVG。
- 您可能会在
<foreignObject>元素中包含回退,但支持 SVG 的浏览器仍然会下载任何后备图像。你需要考虑仅仅为支持过时的浏览器,而增加额外开销是否真的值得。
如何使用 <iframe> 嵌入 SVG
您可以在浏览器中打开 SVG 图像,就像网页一样。因此,使用<iframe>嵌入 SVG 文档就像我们在 从对象到 iframe - 其他嵌入技术 中进行研究一样。
这是一个快速回顾:
<iframe src="triangle.svg" width="500" height="500" sandbox>
<img src="triangle.png" alt="Triangle with three unequal sides" />
</iframe>
这绝对不是最好的方法:
缺点
-
如你所知,
iframe有一个回退机制,如果浏览器不支持iframe,则只会显示回退。 -
此外,除非 SVG 和您当前的网页具有相同的 origin,否则你不能在主页面上使用 JavaScript 来操纵 SVG。