Web网页基础
用浏览器访问不同的网站时,呈现的页面各不相同,你有没有想过为何会这样呢?本节我们就来了解一下网页的组成、结构和节点等内容。
网页的组成
网页可以分为三大部分——HTML、CSS 和 JavaScript。如果把网页比作一个人,那么 HTML 相当于骨架、JavaScript 相当于肌肉、CSS 相当于皮肤,这三者结合起来才能形成一个完善的网页。下面我们分别介绍一下这三部分的功能。
HTML
HTML(HypertextMarkupLanguage)中文翻译为超文本标记语言,但我们通常不会用中文翻译来称呼它,一般就叫 HTML。
HTML 是一种用来描述网页的语言。网页包括文字、按钮、图片和视频等各种复杂的元素,其基础架构就是 HTML。网页通过不同类型的标签来表示不同类型的元素,如用img标签表示图片、用 video 标签表示视频、用p标签表示段落,这些标签之间的布局常由布局标签 div 嵌套组合而成,各种标签通过不同的排列和嵌套形成最终的网页框架。
那 HTML 长什么样子呢?我们可以随意打开一个网站,比如淘宝网首页,然后单击鼠标右键选择 “检查元素” 菜单或者按 F12,即可打开浏览器开发者工具,接着切换到 Elements 面板,这时候呈现的就是淘宝网首页对应的 HTML,它包含了一系列标签,浏览器解析这些标签后,便会在网页中将它们染成一个个节点,这便形成了我们平常看到的网页。比如在图 1-9 中可以看到一个输入框就对应一个 input 标签,可以用于输入文字。
不同标签对应不同的功能,这些标签定义的节点相互嵌套和组合形成了复杂的层次关系,就形成了网页的架构。
CSS
HTML 定义了网页的架构,但是只有 HTML 的页面布局并不美观,有可能只是节点元素的简单排列。为了让网页更好看一些,可以借助 CSS 来实现。
CSS,全称叫作 Cascading Style Sheets,即层叠样式表。“层叠” 是指当 HTML 中引用了多个样式文件,并且样式发生冲突时,浏览器能够按照层叠顺序处理这些样式。“样式” 指的是网页中的文字大小、颜色、元素间距、排列等格式。CSS 是目前唯一的网页页面排版样式标准,有了它的帮助,页面才会变得更为美观。
在图 1-9 中,Styles 面板呈现的就是一系列 CSS 样式,我们摘抄一段:
#head_wrapper.s-ps-islite .s-p-top {
position: absolute;
bottom: 40px;
width: 100%;
height: 181px;
}
这就是一个 CSS 样式。大括号前面是一个 CSS 选择器,此选择器的意思是首先选中 id 为 head_wrapper 且 class 为 s-ps-islite 的节点,然后选中此节点内部的 class 为 s-p-top 的节点。大括号的内部就是一条条样式规则,position 指定了这个节点的布局方式为绝对布局,bottom 指定节点的下边距为 40 像素,width 指定了宽度为 100%,表示占满父节点,height 则指定了节点的高度。也就是说,我们将位置、宽度、高度等样式配置统一写成这样的形式,然后用大括号括起来,接着在开头加上 CSS 选择器,这就代表这个样式对 CSS 选择器选中的节点生效,节点就会根据此样式来展示了。
在网页中,一般会统一定义整个网页的样式规则,并写入 CSS 文件中(其后缀为 css)。在 HTML 中,只需要用 link 标签即可引入写好的 CSS 文件,这样整个页面就会变得美观、优雅。
JavaScript
JavaScript 简称 JS,是一种脚本语言。HTML 和 CSS 组合使用,提供给用户的只是一种静态信息缺乏交互性。我们在网页里还可能会看到一些交互和动画效果,如下载进度条、提示框、轮播图等,这通常就是 JavaScript 的功劳。JavaScript 的出现使得用户与信息之间不只是一种浏览与显示的关系,还实现了一种实时、动态、交互的页面功能。
JavaScript 通常也是以单独的文件形式加载的,后缀为 js,在 HTML 中通过 script 标签即可引入,例如:
<script src="jquery-2.1.0.js"></script>
综上所述,HTML 定义了网页的内容和结构,CSS 描述了网页的样式,JavaScript 定义了网页的行为。
网页的结构
我们首先用例子来感受一下 HTML 的基本结构。新建一个文本文件,名称叫作 test.html,内容如下:
这就是一个最简单的 HTML 实例。开头用 DOCTYPE 定义了文档类型,其次最外层是 html 标签,代码最后有对应的结束标签表示闭合。html 标签内部是 head 标签和 body 标签,分别代表网页头和网页体,它们同样需要结束标签。head 标签内定义了一些对页面的配置和引用,上述代码中的 <meta charset="UTF-8"> 指定了网页的编码为 UTF-8。
title 标签则定义了网页的标题,标题会显示在网页的选项卡中,不会显示在正文中。body 标签内的内容是要在网页正文中显示的。div 标签定义了网页中的区块,此处区块的 id 是 container,id 是一个非常常用的属性,其内容在网页中是唯一的,通过它可以获取这个区块。然后在此区块内又有一个 div 标签,它的 class 为 wrapper,这也是一个非常常用的属性,经常与 css 配合使用来设定样式。然后此区块内部又有一个 h2 标签,代表一个二级标题;另外还有一个 p 标签,代表一个段落。若想在网页中呈现某些内容,直接把内容写入 h2 标签和 p 标签中间即可,这两者也有各自的 class 属性。
将代码保存后,双击该文件在浏览器中打开,可以看到如图 1-10 所示的内容。
可以看到,选项卡上显示 This is a Demo 字样,这是我们在 head 标签中的 title 里定义的文字。网页正文则是由 body 标签内部定义的各个元素生成的,可以看到这里显示了二级标题和段落。
这个实例便是网页的一般结构。一个网页的标准形式是 html 标签内嵌套 head 标签和 body 标签,head 标签内定义网页的配置和引用,body 标签内定义网页的正文。
节点树及节点间的关系
在 HTML 中,所有标签定义的内容都是节点,这些节点构成一个 HTML 节点树,也叫 HTML DOM 树。先来看一下什么是 DOM。DOM 是 W3C(万维网联盟)的标准,英文全称是 Document Object Model,即文档对象模型。它定义了访问 HTML 和 XML 文档的标准。根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点。
-
整个网站文档是一个文档节点。
-
每个 html 标签对应一个根节点,即上例中的 html 标签,它属于一个根节点。
-
节点内的文本是文本节点,比如 a 节点代表一个超链接,它内部的文本也被认为是一个文本节点。
-
每个节点的属性是属性节点,比如 a 节点有一个 href 属性,它就是一个属性节点。
-
注释是注释节点,在 HTML 中有特殊的语法会被解析为注释,它也会对应一个节点。
因此,HTML DOM 将 HTML 文档视作树结构,这种结构被称为节点树,如图 1-11 所示。
通过 HTML DOM,节点树中的所有节点均可通过 JavaScript 访问,所有 HTML 节点元素均可被修改、创建或删除。
节点树中的节点彼此拥有层级关系。我们常用父(parent)、子(child)和兄弟(sibling)等术语描述这些关系。父节点拥有子节点,同级的子节点被称为兄弟节点。
在节点树中,顶端节点称为根(root)。除了根节点之外,每个节点都有父节点,同时可拥有任意数量的子节点或兄弟节点。图 1-12 展示了节点树以及树中节点间的关系。
选择器
我们知道,网页由一个个节点组成,CSS 选择器会为不同的节点设置不同的样式规则,那么怎样定位节点呢?
在 CSS 中,使用 CSS 选择器来定位节点。例如,“网页的结构” 一节的例子中 div 节点的 id 为 container,那么这个节点就可以表示为 #container,其中以 # 开头代表选择 id,其后紧跟的是 id 的名称。如果想选择 class 为 wrapper 的节点,则可以使用 .wrapper,这里以 . 开头代表选择 class,其后紧跟的是 class 的名称。除了这两种,还有一种选择方式,就是根据标签名,例如想选择二级标题,直接用 h2 即可。这些是最常用的三种方式,分别是根据 id、class、标签名选择,请牢记它们的写法。
另外,CSS 选择器还支持嵌套选择,利用空格把各个选择器分隔开便可以代表嵌套关系,如 #container .wrapper p 代表先选择 id 为 container 的节点,然后选择其内部 class 为 wrapper 的节点,再进一步选择该节点内部的 P 节点。要是各个选择器之间不加空格,则代表并列关系,如 div#container.wrapper p.text 代表先选择 id 为 container 的 div 节点,然后选择其内部 class 为 wrapper 的节点,再进一步选择这个节点内部的 class 为 text 的 p 节点。这就是 CSS 选择器,其筛选功能还是非常强大的。
我们可以在浏览器中测试 CSS 选择器的效果,依然还是打开浏览器的开发者工具,然后按快捷键 Ctrl+F(如果你用的是 Mac,则是 Command+F),这时候左下角便会出现一个搜索框,如图 1-13 所示。
这时候我们输入 .title 就是选中了 class 为 title 的节点,该节点会被选中并在网页中高亮显示,如图 1-14 所示。
输入 div#container .wrapper p.text 就逐层选中了 id 为 container 的节点中 class 为 wrapper 的节点中的 p 节点,如图 1-15 所示。
CSS 选择器还有一些其他语法规则,具体如表 1-5 所示。
选择器 | 例子 | 例子描述 |
---|---|---|
.class |
.intro |
选择 class="intro" 的所有节点 |
#id |
#firstname |
选择 id="firstname" 的所有节点 |
* |
* |
选择所有节点 |
element |
p |
选择所有p节点 |
element,element |
div,p |
选择所有div节点和所有p节点 |
element element |
div p |
选择div节点内部的所有p节点 |
element>element |
div>p |
选择父节点为div节点的所有p节点 |
element+element |
div+p |
选择紧接在div节点之后的所有p节点 |
[attribute] |
[target] |
选择带有target属性的所有节点 |
[attribute=value] |
[target=blank] |
选择target="blank"的所有节点 |
[attribute~=value] |
[title~=flower] |
选择title属性包含单词flower的所有节点 |
:link |
a:link |
选择所有未被访问的链接 |
:visited |
a:visited |
选择所有已被访问的链接 |
:active |
a:active |
选择活动链接 |
:hover |
a:hover |
选择鼠标指针位于其上的链接 |
:focus |
input:focus |
选择获得焦点的input节点 |
::first-letter |
p::first-letter |
选择每个p节点的首字母 |
::first-line |
p::first-line |
选择每个p节点的首行 |
:first-child |
p:first-child |
选择属于父节点的第一个子节点的所有p节点 |
::before |
p::before |
在每个p节点的内容之前插人内容 |
::after |
p::after |
在每个p节点的内容之后插入内容 |
:lang(language) |
p:lang(it) |
选择带有以it开头的lang属性值的所有p节点 |
element1~element2 |
p~ul |
选择前面有p节点的所有ul节点 |
[attribute^=value] |
a[src^"https"] |
选择src属性值以https开头的所有a节点 |
[attribute$=value] |
a[src$=".pdf"] |
选择src属性值以·pdf结尾的所有a节点 |
[attribute*=value] |
a[src*="abc"] |
选择src属性值中包含abc子串的所有a节点 |
:first-of-type |
p:first-of-type |
选择属于对应父节点的首个p节点的所有p节点 |
:last-of-type |
p:last-of-type |
选择属于对应父节点的最后一个p节点的所有p节点 |
:only-of-type |
p:only-of-type |
选择属于对应父节点的唯一p节点的所有p节点 |
:only-child |
p:only-child |
选择属于对应父节点的唯一子节点的所有p节点 |
:nth-child(n) |
p:nth-child(2) |
选择属于对应父节点的第二个子节点的所有p节点 |
:nth-last-child(n) |
p:nth-last-child(2) |
同上,不过是从最后一个子节点开始计数 |
:nth-of-type(n) |
p:nth-of-type(2) |
选择属于对应父节点的第二个p节点的所有p节点 |
:nth-last-of-type(n) |
p:nth-last-of-type(2) |
同上,不过是从最后一个子节点开始计数 |
:last-child |
p:last-child |
选择属于对应父节点的最后一个子节点的所有p节点 |
:root |
:root |
选择文档的根节点 |
:empty |
p:empty |
选择没有子节点的所有p节点(包括文本节点) |
:target |
#news:target |
选择当前活动的#news节点 |
:enabled |
input:enabled |
选择每个启用的input节点 |
:disabled |
input:disabled |
选择每个禁用的input节点 |
:checked |
input:checked |
选择每个被选中的input节点 |
:not(selector) |
:not |
选择非p节点的所有节点 |
::selection |
::selection |
选择被用户选取的节点部分 |
另外,还有一种比较常用的选择器 XPath,这种选择方式后面会详细介绍。