三剑客前端教程

前端教程

  • 结构层(html)
  • 表现层(css)
  • 行为层(javascript)

HTML 超文本标记语言)

HTML(超文本标记语言——HyperText Markup Language)是构成 Web 世界的一砖一瓦。它定义了网页内容的含义和结构。除 HTML 以外的其他技术则通常用来描述一个网页的表现与展示效果(如 CSS),或功能与行为(如 JavaScript)。

“超文本”(hypertext)是指连接单个网站内或多个网站间的网页的链接

HTML 使用“标记”(markup)来注明文本、图片和其他内容,以便于在 Web 浏览器中显示。HTML 标记包含一些特殊“元素”如  、、、<header>、<footer>、<article>、<section>、<p>、<div>、<span>、<img/>、</span><aside>、、、、、、<nav>、、、、<ul>、<ol>、<li>等等。</li></ol></ul></nav></aside></div></p> </section></article></footer></header>

标签分类

文档声明、文档结构、功能标签

HTML/HTML5 骨架相关基础标签

分类标签名称描述
文档声明<!DOCTYPE>用于告诉浏览器此文档的类型是什么 处于标签之前。用于告诉浏览器此文档的类型是什么。目前开发中常用的声明是,表示声明一个 HTML5 文档。 它不属于 HTML 标签,而是一条指令
文档结构标签html,head,title,body(1)html 标签:每创建一个 HTML 文件,都需要创建 html 标签对。除了声明文档类型的代码,其他的所有内容都存放在 html 标签对中; (2) head 标签:定义文档的头部,用来包含网页的配置(例如网页的标题 title,网页的基础配置 meta 都放在 head 中); (3)title 标签:定义网页的标题,标题内容会显示在浏览器的标签栏上 (4)body 标签:定义网页的主体,例如:网页中的图片、文字等
功能标签meta元标签,用来表示网页的基础配置

属性分类

行元素 inline

不能设置宽高,宽高取决于自身内容,不独占一行,多个行内元素左右排列,一行显示不下时会自动换行

a, span,link
块元素 block

独占一行,可以设置宽高,如果不设置宽高则默认宽默认为父级标签宽度,高度由内容撑开,若没有内容,则高度为空

div,标题元素h1-h6, 段落标签 p,pre,section,nav, header,footer, address, 表格标签
行内块元素 inline-block

不能设置宽高,宽高取决于自身内容,不独占一行,多个行内元素左右排列,一行显示不下时会自动换行

img,button, input

常用标签

块元素

h1~h6:标题标签,用于标记网页中的大标题,依次从大到小
p:用于标记网页中的段落性文字,默认占满横向区域
div:划分,分隔,作用是就是将页面划分为不同的区域,不设置宽高时,高度有内容撑开,宽度和父级元素一样宽
section:区段,是用来定义文档的某个区域,章节
nav:标签定义导航链接的部分,提示:如果文档中有“前后”按钮,则应该把它放到nav元素中。
header:标签定义文档的页眉
footer:标签定义文档或节的页脚,页脚通常包含文档的作者、版权信息、使用条款链接、联系信息等等
pre:格式标签,被包围在pre元素中的文本通常会保留空格和换行符,而文本也会呈现为等宽字体。
address: 标签定义文档或文章的作者/拥有者的联系信息,元素中的文本通常呈现为斜体,大多数浏览器会在 address 元素前后添加折行
audio:音频使用,背景音乐播放,属性autoplay自动播放,loop循环播放,src要播放的音频,controls为音频提供播放控件,比如播放按钮。preload规定是否在页面加载后载入音频,如果设置了 autoplay 属性,则忽略该属性。
/ 表格标签 /
table:用于显示一个表格,不能设置宽高,宽高被内容撑开,设置宽度而内部的td没有宽度时,td会按照内容长度的比例拉伸
thead:表头,用于显示一列的名称,一般省略不写,浏览器在解析时会自动添加
tbody:表主体,一般省略不写,浏览器在解析时会自动添加
tr:表示一行
th:表头中的第一个单元格
td:表示主体中的单元格,有属性rowspan合并单元格,合并行。colspan合并列
/ 有序列表,无序列表 /
ul:无序列表
ol:有序列表
li:列表项
dl:定义列表,用于描述类表中的项目(dt(dd))

行元素

span:是超文本标记语言(HTML)的行内标签,被用来组合文档中的行内元素,span没有固定的格式表现,当对它应用样式时,它会产生视觉上的变化

a:标记网页中的超链接,点击可以打开或者跳转到另一个网页,也可以链接到一个要下载的文件
有属性:href:要链接到的资源地址,target:打开的链接方式,值_blank:表示新打开一个窗口打开目标地址
strong:标记页面中的粗体文本,语义化标签,除了文本加粗之外,还有强调的预期,表示标签中的内容是页面中需要重点关注的内容
i: 斜体
b:标记网页中的粗体文本,仅仅将文本加粗,标签中的内容不再强调
s:删除线,仅仅是删除的效果
del:具有删除语义,delete删除
em:强调文本,斜体展示
sup:上标
sub:下标

行内块元素

img:用于标记网页中的图像 ,有属性src:图片资源路径 ,alt:提示信息 当图片加载失败 ,以指定文本形式代替图片显示
button:按钮
input:输入框,有属性type输入框类型,有属性值(text表示文本输入框,file文件选择器,password密码输入框,email邮箱输入框,number数字输入框,button按钮)。placeholder占位字符,用于提示输入框应该输入的内容。value表示输入框中的内容。name和后台服务器交互时,必须携带name属性,发送请求时的参数名。

单选 type=“radio” 表示一个单选选项处于同一组单选框只能选中一个值,将多个radio的name属性值设置为相同的值
type="checkbox"复选框

label:和input标签绑定到一块使用,有属性for,属性值就是input输入框的id值。checked属性为标签选中状态
select:下拉列表
option:下拉选项

行元素和块元素不是绝对不变的,任何元素都可以通过display样式来改变布局方式类型,块元素block,行元素inline,行内块元素inline-block

表格标签

标签名描述
table表格标签
tr表格行
td表格列
th标签,可替代 td 标签,用来设置表格的标题
thead定义表格头部
tbody定义表格主体内容
tfoot定义表格尾部
caption设置表格的标题

标签属性

标签中的属性

属性名描述
langhtml 标签的属性,用来标记网页的语言; 常见属性值有:“en"和"zh”;en 代表英语, zh 代表中文
charsetmeta 标签的属性,声明页面文档使用的字符编码类型。 常用的属性值有:UTF-8 和 GB2312
type修改无序列表与有序列表默认的前导样式(已被废弃,了解即可) 1、type 属性写在无序列表中,属性值有: (1)disc:默认值,实心圆样式 (2)circle: 空心圆样式 (3)square:实心方块样式 2、type 属性写在无序列表中,属性值有: (1)1:默认值,数字编号 (2)A:大写英文编号 (3)i:小写罗马数字编号 (4)I:大写罗马数字编号 (5)a:小写英文编号
start有序列表的属性,指定列表编号的起始值,能修改有序列表标签默认的前导样式(不常用,了解即可)
reversed有序列表的属性,指定列表中的条目是否倒序排列的(不常用,了解即可)
src(1)img 标签的属性,指定图片的路径 (2)audio 标签和 video 标签也可以设置 src 属性,指定音频、视频的路径
altimg 标签的属性,用来对引入的图片进行文本描述
width规定元素的宽度。此属性不常用,了解即可。后续学习 css,会使用 css 样式设置元素宽度
height规定元素的高度。此属性不常用,了解即可。后续学习 css,会使用 css 样式设置元素高度。 注意,height 或者 width 如果省略其中一个属性,则按照图片原始比例缩放图片
hrefa 标签属性,规定该链接要跳转到目标页面的地址
titlea 标签属性,设置鼠标悬停的文本
targeta 标签属性,规定在何处打开链接文档; 如果属性值为 blank 或_blank,会打开新的标签页
controlsaudio/video 的属性,用于显示播放控件
autoplayaudio/video 的属性,设置音频/视频自动播放
loopaudio/video 的属性,设置音频/视频可以循环播放
class所有标签都可以使用这个属性,用来定义元素的类名(后续学习 css,会有详细的讲解)
actionform 标签的属性,用来设置 form 表单的数据要提交到哪个地址。提交到哪个地址,后端开发会告诉我们(不常用,了解一下。提交数据常用 ajax,后面会学习到的)
methodform 标签的属性,用来设置表单的提交方式,常用的方式有 get 或 post(不常用,了解即可)
rowstextarea 标签属性,设置多行文本框有多少列
colstextarea 标签属性,设置多行文本框有多少行
listdatalist 控件的属性,二者结合,可以与输入框绑定,为输入框设置备选项(不常用,了解即可)
border边框属性,可为 table 添加边框
border-collapsecss 样式,通常给表格设置 border-collapse:collapse;让表格边框合并,成为单线表格;
colspan表格标签的属性,实现跨列合并的效果,用来设置 td 或 th 跨列合并
rowspan表格标签的属性,实现跨列合并的效果,用来设置 td 或 th 跨行合并
cellspacing设置表格单元格内容与边框之间的间隙(不常用,了解即可)
cellpadding设置两个单元格之间的间隙(不常用,了解即可)

input 元素中的属性

属性名称描述
type用来定义表单元素的类型。属性值如下: (1)text:单行文本输入框 (2)radio:单选按钮 (3)checkbox:复选框 (4)password:密码框 (5)button:普通按钮,也可以直接写成 button 按钮,例如: (6)submit:提交按钮 (7)reset:重置按钮 (8)color:颜色控件(不常用,了解即可) (9)date:日期控件 (10)time:时间控件 (11)email:电子邮件输入控件 (12)file:文件选择控件,需要上传本地文件时,可以使用它 (13)number:表示数字输入控件 (14)range:表示拖拽条(不常用,了解即可) (15)search:t 表示搜索框(不常用,了解即可)(16)url:表示网址输入控件
value用于为 input 元素设定值,value 值一般是给后端发送数据时使用,后续学习了相关课程就会了解
name规定 input 元素的名称
checked用来设置单选按钮、多选按钮的默认选中项
placeholder表示提示文本,用来设置输入框的提示信息,告诉用户该输入框需要输入什么内容
disabled用于禁用 input 元素,表示只读
maxmax 表示最大值,表示数字输入控件(即 type="number"的 input 元素)允许输入的最大值
minmin 表示最小值,最小值,表示数字输入控件(即 type="number"的 input 元素)允许输入的最小值
require表示必填字段,约束某项内容是必填项,比如规定”用户名“项,是必填项

CSS 层叠样式表

层叠样式表(Cascading Style Sheets,缩写为 CSS)是一种样式表语言,用来描述 HTML 或 XML(包括如 SVGMathML 或 XHTML 之类的 XML 分支语言)文档的呈现方式。CSS 描述了在屏幕、纸质、音频等其他媒体上的元素应该如何被渲染的问题。

CSS 用来干什么?

CSS 是用来指定文档如何展示给用户的一门语言——如网页的样式、布局、等等

CSS 可以用于给文档添加样式——比如改变标题和链接的颜色大小。它也可用于创建布局——比如将一个单列文本变成包含主要内容区域和存放相关信息的侧边栏区域的布局。它甚至还可以用来做一些特效,比如动画

CSS 语法

CSS 是一门基于规则的语言——你能定义用于你的网页中特定元素样式的一组规则。

h1 {
  color: red;
  font-size: 5em;
}

语法由一个 选择器(selector)起头。它选择了我们将要用来添加样式的 HTML 元素。在这个例子中我们为一级标题(主标题`` (en-US))添加样式。

接着输入一对大括号 { }。在大括号内部定义一个或多个形式为属性(property)—(value)对的声明。每个声明都指定了我们所选择元素的一个属性,之后跟一个我们想赋给这个属性的值。

冒号之前是属性,冒号之后是值。不同的 CSS 属性对应不同的合法值。

层叠、优先级与继承

层叠

样式表层叠——简单的说,就是 CSS 规则的顺序很重要;当应用两条同级别的规则到一个元素的时候,写在后面的就是实际使用的规则。

<h1>This is my heading.</h1>

h1 {
  color: red;
}
h1 {
  color: blue;
}
优先级

浏览器是根据优先级来决定当多个规则有不同选择器对应相同的元素的时候需要使用哪个规则

一个选择器的优先级可以说是由三个不同的值(或分量)相加,可以认为是百(ID)十(类)个(元素)——三位数的三个位数:

  • ID:选择器中包含 ID 选择器则百位得一分。

  • :选择器中包含类选择器、属性选择器或者伪类则十位得一分。

  • 元素:选择器中包含元素、伪元素选择器则个位得一分。

    备注: 通用选择器(*)、组合符(+>~、’ ')和调整优先级的选择器(:where())不会影响优先级。

    选择器ID元素优先级
    h10010-0-1
    h1 + p::first-letter0030-0-3
    li > a[href*="en-US"] > .inline-warning0220-2-2
    #identifier1001-0-0
    button:not(#mainBtn, .cta)1011-0-1
内联样式

内联样式,即 style 属性内的样式声明,优先于所有普通的样式,无论其优先级如何。这样的声明没有选择器,但它们的优先级可以理解为 1-0-0-0;即无论选择器中有多少个 ID,它总是比其他任何优先级的权重都要高。

!important

有一个特殊的 CSS 可以用来覆盖所有上面所有优先级计算,不过需要很小心的使用——!important。用于修改特定属性的值,能够覆盖普通规则的层叠。

备注: 了解 !important 是为了在阅读别人代码的时候知道有什么作用。但是,强烈建议除了非常情况不要使用它。!important 改变了层叠的常规工作方式,它会使调试 CSS 问题非常困难,特别是在大型样式表中。

继承

继承也需要在上下文中去理解——一些设置在父元素上的 CSS 属性是可以被子元素继承的,有些则不能。

CSS 选择器

标签、类以及 ID 选择器

标签选择器顾名思义就是html代码中的标签

<div class="box"></div>
div {
    width: 100px;
}

类选择器跟id有点相似,任何的标签元素都可以添加类(class),但是不同的是类是可以重复,有“归类”的概念,并且同一个标签中可以携带多个类,用空格隔开。

<div class="box"></div>
.box{
    width: 100px;
}

ID好比是每个人的身份证号一样,每个人都有身份证,并且身份证号是不一样的。在网页中所有的标签都可以设置id,并且id不能重复。

<div id="box"></div>
#box{
    width: 100px;
}

属性选择器

通过元素的属性选择 HTML 元素。属性选择器可以根据属性名和属性值进行选择。

如下代码,input[type=“text”] 选择器将选择所有 type 属性为 “text” 的 元素

input[type="text"] {
  border: 1px solid gray;
}
存否和值选择器

这些选择器允许基于一个元素自身是否存在(例如href)或者基于各式不同的按属性值的匹配,来选取元素。

选择器示例描述
[*attr*]a[title]匹配带有一个名为attr的属性的元素——方括号里的值。
[*attr*=*value*]a[href="https://example.com"]匹配带有一个名为attr的属性的元素,其值正为value——引号中的字符串。
[*attr*~=*value*]p[class~="special"]匹配带有一个名为attr的属性的元素,其值正为value,或者匹配带有一个attr属性的元素,其值有一个或者更多,至少有一个和value匹配。注意,在一列中的好几个值,是用空格隔开的。
`[attr=value]``div[lang

伪类与伪元素

:last-child
:only-child
:invalid

:hover——上面提到过,只会在用户将指针挪到元素上的时候才会激活,一般就是链接元素。

:focus——只会在用户使用键盘控制,选定元素的时候激活。

伪元素是啥?

伪元素以类似方式表现,不过表现得是像你往标记文本中加入全新的 HTML 元素一样,而不是向现有的元素上应用类。伪元素开头为双冒号::

::pseudo-element-name
::before
::after
伪类
选择器描述
:active在用户激活(例如点击)元素的时候匹配。
:any-link匹配一个链接的:link:visited状态。
:blank匹配空输入值的``元素
:checked匹配处于选中状态的单选或者复选框。
:current (en-US)匹配正在展示的元素,或者其上级元素。
:default匹配一组相似的元素中默认的一个或者更多的 UI 元素。
:dir基于其方向性(HTMLdir属性或者 CSSdirection属性的值)匹配一个元素。
:disabled匹配处于关闭状态的用户界面元素
:empty匹配除了可能存在的空格外,没有子元素的元素。
:enabled匹配处于开启状态的用户界面元素。
:first匹配分页媒体的第一页。
:first-child匹配兄弟元素中的第一个元素。
:first-of-type匹配兄弟元素中第一个某种类型的元素。
:focus当一个元素有焦点的时候匹配。
:focus-visible当元素有焦点,且焦点对用户可见的时候匹配。
:focus-within匹配有焦点的元素,以及子代元素有焦点的元素。
:future (en-US)匹配当前元素之后的元素。
:hover当用户悬浮到一个元素之上的时候匹配。
:indeterminate匹配未定态值的 UI 元素,通常为复选框
:in-range用一个区间匹配元素,当值处于区间之内时匹配。
:invalid匹配诸如<input>的位于不可用状态的元素。
:lang基于语言(HTMLlang属性的值)匹配元素。
:last-child匹配兄弟元素中最末的那个元素。
:last-of-type匹配兄弟元素中最后一个某种类型的元素。
:left分页媒体中,匹配左手边的页。
:link匹配未曾访问的链接。
:local-link (en-US)匹配指向和当前文档同一网站页面的链接。
:is()匹配传入的选择器列表中的任何选择器。
:not匹配作为值传入自身的选择器未匹配的物件。
:nth-child匹配一列兄弟元素中的元素——兄弟元素按照an+b形式的式子进行匹配(比如 2n+1 匹配元素 1、3、5、7 等。即所有的奇数个)。
:nth-of-type匹配某种类型的一列兄弟元素(比如,<p>元素)——兄弟元素按照an+b形式的式子进行匹配(比如 2n+1 匹配元素 1、3、5、7 等。即所有的奇数个)。
:nth-last-child匹配一列兄弟元素,从后往前倒数。兄弟元素按照an+b形式的式子进行匹配(比如 2n+1 匹配按照顺序来的最后一个元素,然后往前两个,再往前两个,诸如此类。从后往前数的所有奇数个)。
:nth-last-of-type匹配某种类型的一列兄弟元素(比如,<p>元素),从后往前倒数。兄弟元素按照an+b形式的式子进行匹配(比如 2n+1 匹配按照顺序来的最后一个元素,然后往前两个,再往前两个,诸如此类。从后往前数的所有奇数个)。
:only-child匹配没有兄弟元素的元素。
:only-of-type匹配兄弟元素中某类型仅有的元素。
:optional匹配不是必填的 form 元素。
:out-of-range按区间匹配元素,当值不在区间内的的时候匹配。
:past (en-US)匹配当前元素之前的元素。
:placeholder-shown匹配显示占位文字的 input 元素。
:playing匹配代表音频、视频或者相似的能“播放”或者“暂停”的资源的,且正在“播放”的元素。
:paused匹配代表音频、视频或者相似的能“播放”或者“暂停”的资源的,且正在“暂停”的元素。
:read-only匹配用户不可更改的元素。
:read-write匹配用户可更改的元素。
:required匹配必填的 form 元素。
:right分页媒体中,匹配右手边的页。
:root匹配文档的根元素。
:scope匹配任何为参考点元素的的元素。
:valid匹配诸如<input>元素的处于可用状态的元素。
:target匹配当前 URL 目标的元素(例如如果它有一个匹配当前URL 分段的元素)。
:visited匹配已访问链接。
伪元素
选择器描述
::after匹配出现在原有元素的实际内容之后的一个可样式化元素。
::before匹配出现在原有元素的实际内容之前的一个可样式化元素。
::first-letter匹配元素的第一个字母。
::first-line匹配包含此伪元素的元素的第一行。
::grammar-error匹配文档中包含了浏览器标记的语法错误的那部分。
::selection匹配文档中被选择的那部分。
::spelling-error匹配文档中包含了浏览器标记的拼写错误的那部分。

关系选择器

后代选择器

**后代选择器(Descendant Selector):**通过指定元素的后代关系选择 HTML 元素。

后代选择器使用空格分隔元素名称。

如下代码,div p 选择器将选择所有在

元素内的

元素。

<div><p></p></div>
div p {
  font-weight: bold;
}
子代关系选择器

子代关系选择器是个大于号(>),只会在选择器选中直接子元素的时候匹配。继承关系上更远的后代则不会匹配。例如,只选中作为<article>的直接子元素的<p>元素:

<div><p></p></div>
div > p {}
邻接兄弟

邻接兄弟选择器(+)用来选中恰好处于另一个在继承关系上同级的元素旁边的物件。例如,选中所有紧随<p>元素之后的<img>元素:

<div></div>
<p></p>

div + p{}
通用兄弟

如果你想选中一个元素的兄弟元素,即使它们不直接相邻,你还是可以使用通用兄弟关系选择器(~)。要选中所有的<p>元素后任何地方<img>元素,我们会这样做:

CSSCopy to Clipboard

<article>
  <h1>A heading</h1>
  <p>I am a paragraph.</p>
  <div>I am a div</div>
  <p>I am another paragraph.</p>
</article>
h1 ~ p {} 所有p的样式
使用关系选择器

你能用关系选择器,将任何在我们前面的学习过程中学到的选择器组合起来,选出你的文档中的一部分。例如如果我们想选中为<ul>的直接子元素的带有“a”类的列表项的话,我可以用下面的代码。

ul > li[class="a"] {}
<ul>
	<li></li>
	<li>
		<div class="a"></div>
	</li>
</ul>

CSS 盒模型

在 CSS 中,所有的元素都被一个个的“盒子(box)”包围着,理解这些“盒子”的基本原理,是我们使用 CSS 实现准确布局、处理元素排列的关键。

块级盒子(Block box)和 内联盒子(Inline box)

在 CSS 中我们广泛地使用两种“盒子”——块级盒子(block box)和内联盒子(inline box)。这两种盒子会在页面流(page flow)和元素之间的关系方面表现出不同的行为:

一个被定义成块级的(block)盒子会表现出以下行为:

  • 盒子会在内联的方向上扩展并占据父容器在该方向上的所有可用空间,在绝大数情况下意味着盒子会和父容器一样宽
  • 每个盒子都会换行
  • widthheight 属性可以发挥作用
  • 内边距(padding), 外边距(margin)和 边框(border)会将其他元素从当前盒子周围“推开”

除非特殊指定,诸如标题 (<h1>等) 和段落 (<p>) 默认情况下都是块级的盒子。

如果一个盒子对外显示为 inline,那么他的行为如下:

  • 盒子不会产生换行。
  • widthheight 属性将不起作用。
  • 垂直方向的内边距、外边距以及边框会被应用但是不会把其他处于 inline 状态的盒子推开。
  • 水平方向的内边距、外边距以及边框会被应用且会把其他处于 inline 状态的盒子推开。
什么是 CSS 盒模型?

完整的 CSS 盒模型应用于块级盒子,内联盒子只使用盒模型中定义的部分内容。模型定义了盒的每个部分——margin、border、padding 和 content——合在一起就可以创建我们在页面上看到的内容。为了增加一些额外的复杂性,有一个标准的和替代(IE)的盒模型。

盒模型的各个部分

CSS 中组成一个块级盒子需要:

  • Content box: 这个区域是用来显示内容,大小可以通过设置 widthheight.
  • Padding box: 包围在内容区域外部的空白区域;大小通过 padding 相关属性设置。
  • Border box: 边框盒包裹内容和内边距。大小通过 border 相关属性设置。
  • Margin box: 这是最外面的区域,是盒子和其他元素之间的空白区域。大小通过 margin 相关属性设置。

如下图:

image.png

Diagram of the box model

标准盒模型

标准盒模型 宽高 = width / height + padding + border

box-sizing:content-box

在标准模型中,如果你给盒设置 widthheight,实际设置的是 content box。padding 和 border 再加上设置的宽高一起决定整个盒子的大小。

替代(IE)盒模型

IE盒模型 宽高 = width / height

box-sizing:border-box

你可能会认为盒子的大小还要加上边框和内边距,这样很麻烦,而且你的想法是对的 ! 因为这个原因,css 还有一个替代盒模型。使用这个模型,所有宽度都是可见宽度,所以内容宽度是该宽度减去边框和填充部分。使用上面相同的样式得到 (width = 350px, height = 150px).

image.png

Showing the size of the box when the alternate box model is being used.

默认浏览器会使用标准模型。如果需要使用替代模型,你可以通过为其设置 box-sizing: border-box 来实现。这样就可以告诉浏览器使用 border-box 来定义区域,从而设定你想要的大小。

CSSCopy to Clipboard

.box {
  box-sizing: border-box;
}

如果你希望所有元素都使用替代模式,而且确实很常用,设置 box-sizing<html> 元素上,然后设置所有元素继承该属性,正如下面的例子。如果想要深入理解,请看 the CSS Tricks article on box-sizing

CSS 布局

正常布局流

正常布局流(normal flow)是指在不对页面进行任何布局控制时,浏览器默认的 HTML 布局方式。让我们快速地看一个 HTML 的例子:

HTMLPlayCopy to Clipboard

<p>I love my cat.</p>

<ul>
  <li>Buy cat food</li>
  <li>Exercise</li>
  <li>Cheer up friend</li>
</ul>

<p>The end!</p>

默认情况下,浏览器的显示如下:

I love my cat.
    Buy cat food
    Exercise
    Cheer up friend
The end!

浮动

应用 float 值,诸如 left 能够让块级元素互相并排成一行,而不是一个堆叠在另一个上面。

浮动元素 会脱离正常的文档布局流,并吸附到其父容器的左边 或右边,不会撑开父元素

div {
    float: left;
    float: right;
}
清除浮动

浮动元素会被移出正常文档流,且其他元素会显示在它的下方。如果我们不想让剩余元素也受到浮动元素的影响,我们需要 停止 它;这是通过添加 clear 属性实现的。

clear 属性接受下列值:

  • left:停止任何活动的左浮动
  • right:停止任何活动的右浮动
  • both:停止任何活动的左右浮动

一个替代的方案是将包裹元素的 overflow 属性设置为除 visible 外的其他值。

弹性盒子

弹性盒子是一种用于按行或按列布局元素的一维布局方法。元素可以膨胀以填充额外的空间,收缩以适应更小的空间。本文将解释所有的基本原理。

Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。

任何一个容器都可以指定为 Flex 布局。

.box{
  display: flex;
}

行内元素也可以使用 Flex 布局。

.box{
  display: inline-flex;
}

Webkit 内核的浏览器,必须加上-webkit前缀。

.box{
  display: -webkit-flex; /* Safari */
  display: flex;
}

注意,设为 Flex 布局以后,子元素的floatclearvertical-align属性将失效。

基本概念

采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。

img

容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end

项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size

容器的属性

以下6个属性设置在容器上。

  • flex-direction
  • flex-wrap
  • flex-flow
  • justify-content
  • align-items
  • align-content
1 flex-direction属性

flex-direction属性决定主轴的方向(即项目的排列方向)。

.box {
  flex-direction: row | row-reverse | column | column-reverse;
}

img

它可能有4个值。

  • row(默认值):主轴为水平方向,起点在左端。
  • row-reverse:主轴为水平方向,起点在右端。
  • column:主轴为垂直方向,起点在上沿。
  • column-reverse:主轴为垂直方向,起点在下沿。
2 flex-wrap属性

默认情况下,项目都排在一条线(又称"轴线")上。flex-wrap属性定义,如果一条轴线排不下,如何换行。

img

.box{
  flex-wrap: nowrap | wrap | wrap-reverse;
}

它可能取三个值。

(1)nowrap(默认):不换行。

img

(2)wrap:换行,第一行在上方。

img

(3)wrap-reverse:换行,第一行在下方。

img

3 flex-flow

flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap

.box {
  flex-flow: <flex-direction> || <flex-wrap>;
}
4 justify-content属性

justify-content属性定义了项目在主轴上的对齐方式。

.box {
  justify-content: flex-start | flex-end | center | space-between | space-around;
}

img

它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。

  • flex-start(默认值):左对齐
  • flex-end:右对齐
  • center: 居中
  • space-between:两端对齐,项目之间的间隔都相等。
  • space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
5 align-items属性

align-items属性定义项目在交叉轴上如何对齐。

.box {
  align-items: flex-start | flex-end | center | baseline | stretch;
}

img

它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。

  • flex-start:交叉轴的起点对齐。
  • flex-end:交叉轴的终点对齐。
  • center:交叉轴的中点对齐。
  • baseline: 项目的第一行文字的基线对齐。
  • stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
6 align-content属性

align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

.box {
  align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

img

该属性可能取6个值。

  • flex-start:与交叉轴的起点对齐。
  • flex-end:与交叉轴的终点对齐。
  • center:与交叉轴的中点对齐。
  • space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
  • space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
  • stretch(默认值):轴线占满整个交叉轴。
项目的属性

以下6个属性设置在项目上。

  • order
  • flex-grow
  • flex-shrink
  • flex-basis
  • flex
  • align-self
1 order属性

order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。

.item {
  order: <integer>;
}

img

2 flex-grow属性

flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。

.item {
  flex-grow: <number>; /* default 0 */
}

img

如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。

3 flex-shrink属性

flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。

.item {
  flex-shrink: <number>; /* default 1 */
}

img

如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。

负值对该属性无效。

4 flex-basis属性

flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。

.item {
  flex-basis: <length> | auto; /* default auto */
}

它可以设为跟widthheight属性一样的值(比如350px),则项目将占据固定空间。

5 flex属性

flex属性是flex-grow, flex-shrinkflex-basis的简写,默认值为0 1 auto。后两个属性可选。

.item {
  flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。

建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。

6 align-self属性

align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch

.item {
  align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

img

该属性可能取6个值,除了auto,其他都与align-items属性完全一致。

网格

一、概述

网格布局(Grid)是最强大的 CSS 布局方案。

它将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局。以前,只能通过复杂的 CSS 框架达到的效果,现在浏览器内置了。

img

上图这样的布局,就是 Grid 布局的拿手好戏。

Grid 布局与 Flex 布局有一定的相似性,都可以指定容器内部多个项目的位置。但是,它们也存在重大区别。

Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局。Grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局。Grid 布局远比 Flex 布局强大。

二、基本概念

学习 Grid 布局之前,需要了解一些基本概念。

2.1 容器和项目

采用网格布局的区域,称为"容器"(container)。容器内部采用网格定位的子元素,称为"项目"(item)。

<div>
  <div><p>1</p></div>
  <div><p>2</p></div>
  <div><p>3</p></div>
</div>

上面代码中,最外层的<div>元素就是容器,内层的三个<div>元素就是项目。

注意:项目只能是容器的顶层子元素,不包含项目的子元素,比如上面代码的<p>元素就不是项目。Grid 布局只对项目生效。

2.2 行和列

容器里面的水平区域称为"行"(row),垂直区域称为"列"(column)。

img

上图中,水平的深色区域就是"行",垂直的深色区域就是"列"。

2.3 单元格

行和列的交叉区域,称为"单元格"(cell)。

正常情况下,n行和m列会产生n x m个单元格。比如,3行3列会产生9个单元格。

2.4 网格线

划分网格的线,称为"网格线"(grid line)。水平网格线划分出行,垂直网格线划分出列。

正常情况下,n行有n + 1根水平网格线,m列有m + 1根垂直网格线,比如三行就有四根水平网格线。

img

上图是一个 4 x 4 的网格,共有5根水平网格线和5根垂直网格线。

三、容器属性

Grid 布局的属性分成两类。一类定义在容器上面,称为容器属性;另一类定义在项目上面,称为项目属性。这部分先介绍容器属性。

3.1 display 属性

display: grid指定一个容器采用网格布局。

div {
  display: grid;
}

img

上图是display: grid效果

默认情况下,容器元素都是块级元素,但也可以设成行内元素。

div {
  display: inline-grid;
}

上面代码指定div是一个行内元素,该元素内部采用网格布局。

img

上图是display: inline-grid效果

注意,设为网格布局以后,容器子元素(项目)的floatdisplay: inline-blockdisplay: table-cellvertical-aligncolumn-*等设置都将失效。

3.2 grid-template-columns 属性, grid-template-rows 属性

容器指定了网格布局以后,接着就要划分行和列。grid-template-columns属性定义每一列的列宽,grid-template-rows属性定义每一行的行高。

.container {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 100px 100px 100px;
}

上面代码指定了一个三行三列的网格,列宽和行高都是100px

img

除了使用绝对单位,也可以使用百分比。

.container {
  display: grid;
  grid-template-columns: 33.33% 33.33% 33.33%;
  grid-template-rows: 33.33% 33.33% 33.33%;
}

(1)repeat()

有时候,重复写同样的值非常麻烦,尤其网格很多时。这时,可以使用repeat()函数,简化重复的值。上面的代码用repeat()改写如下。

.container {
  display: grid;
  grid-template-columns: repeat(3, 33.33%);
  grid-template-rows: repeat(3, 33.33%);
}

repeat()接受两个参数,第一个参数是重复的次数(上例是3),第二个参数是所要重复的值。

repeat()重复某种模式也是可以的。

grid-template-columns: repeat(2, 100px 20px 80px);

上面代码定义了6列,第一列和第四列的宽度为100px,第二列和第五列为20px,第三列和第六列为80px

img

(2)auto-fill 关键字

有时,单元格的大小是固定的,但是容器的大小不确定。如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用auto-fill关键字表示自动填充。

.container {
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
}

上面代码表示每列宽度100px,然后自动填充,直到容器不能放置更多的列。

img

除了auto-fill,还有一个关键字auto-fit,两者的行为基本是相同的。只有当容器足够宽,可以在一行容纳所有单元格,并且单元格宽度不固定的时候,才会有行为差异auto-fill会用空格子填满剩余宽度,auto-fit则会尽量扩大单元格的宽度。

(3)fr 关键字

为了方便表示比例关系,网格布局提供了fr关键字(fraction 的缩写,意为"片段")。如果两列的宽度分别为1fr2fr,就表示后者是前者的两倍。

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
}

上面代码表示两个相同宽度的列。

img

fr可以与绝对长度的单位结合使用,这时会非常方便。

.container {
  display: grid;
  grid-template-columns: 150px 1fr 2fr;
}

上面代码表示,第一列的宽度为150像素,第二列的宽度是第三列的一半。

img

(4)minmax()

minmax()函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值。

grid-template-columns: 1fr 1fr minmax(100px, 1fr);

上面代码中,minmax(100px, 1fr)表示列宽不小于100px,不大于1fr

(5)auto 关键字

auto关键字表示由浏览器自己决定长度。

grid-template-columns: 100px auto 100px;

上面代码中,第二列的宽度,基本上等于该列单元格的最大宽度,除非单元格内容设置了min-width,且这个值大于最大宽度。

(6)网格线的名称

grid-template-columns属性和grid-template-rows属性里面,还可以使用方括号,指定每一根网格线的名字,方便以后的引用。

.container {
  display: grid;
  grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4];
  grid-template-rows: [r1] 100px [r2] 100px [r3] auto [r4];
}

上面代码指定网格布局为3行 x 3列,因此有4根垂直网格线和4根水平网格线。方括号里面依次是这八根线的名字。

网格布局允许同一根线有多个名字,比如[fifth-line row-5]

(7)布局实例

grid-template-columns属性对于网页布局非常有用。两栏式布局只需要一行代码。

.wrapper {
  display: grid;
  grid-template-columns: 70% 30%;
}

上面代码将左边栏设为70%,右边栏设为30%。

传统的十二网格布局,写起来也很容易。

grid-template-columns: repeat(12, 1fr);
3.3 grid-row-gap 属性, grid-column-gap 属性, grid-gap 属性

grid-row-gap属性设置行与行的间隔(行间距),grid-column-gap属性设置列与列的间隔(列间距)。

.container {
  grid-row-gap: 20px;
  grid-column-gap: 20px;
}

上面代码中,grid-row-gap用于设置行间距,grid-column-gap用于设置列间距。

img

grid-gap属性是grid-column-gapgrid-row-gap的合并简写形式,语法如下。

grid-gap: <grid-row-gap> <grid-column-gap>;

因此,上面一段 CSS 代码等同于下面的代码。

.container {
  grid-gap: 20px 20px;
}

如果grid-gap省略了第二个值,浏览器认为第二个值等于第一个值。

根据最新标准,上面三个属性名的grid-前缀已经删除,grid-column-gapgrid-row-gap写成column-gaprow-gapgrid-gap写成gap

3.4 grid-template-areas 属性

网格布局允许指定"区域"(area),一个区域由单个或多个单元格组成。grid-template-areas属性用于定义区域。

.container {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 100px 100px 100px;
  grid-template-areas: 'a b c'
                       'd e f'
                       'g h i';
}

上面代码先划分出9个单元格,然后将其定名为ai的九个区域,分别对应这九个单元格。

多个单元格合并成一个区域的写法如下。

grid-template-areas: 'a a a'
                     'b b b'
                     'c c c';

上面代码将9个单元格分成abc三个区域。

下面是一个布局实例。

grid-template-areas: "header header header"
                     "main main sidebar"
                     "footer footer footer";

上面代码中,顶部是页眉区域header,底部是页脚区域footer,中间部分则为mainsidebar

如果某些区域不需要利用,则使用"点"(.)表示。

grid-template-areas: 'a . c'
                     'd . f'
                     'g . i';

上面代码中,中间一列为点,表示没有用到该单元格,或者该单元格不属于任何区域。

注意,区域的命名会影响到网格线。每个区域的起始网格线,会自动命名为区域名-start,终止网格线自动命名为区域名-end

比如,区域名为header,则起始位置的水平网格线和垂直网格线叫做header-start,终止位置的水平网格线和垂直网格线叫做header-end

3.5 grid-auto-flow 属性

划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是"先行后列",即先填满第一行,再开始放入第二行,即下图数字的顺序。

img

这个顺序由grid-auto-flow属性决定,默认值是row,即"先行后列"。也可以将它设成column,变成"先列后行"。

grid-auto-flow: column;

上面代码设置了column以后,放置顺序就变成了下图。

img

grid-auto-flow属性除了设置成rowcolumn,还可以设成row densecolumn dense。这两个值主要用于,某些项目指定位置以后,剩下的项目怎么自动放置。

下面的例子让1号项目和2号项目各占据两个单元格,然后在默认的grid-auto-flow: row情况下,会产生下面这样的布局。

img

上图中,1号项目后面的位置是空的,这是因为3号项目默认跟着2号项目,所以会排在2号项目后面。

现在修改设置,设为row dense,表示"先行后列",并且尽可能紧密填满,尽量不出现空格。

grid-auto-flow: row dense;

上面代码的效果如下。

img

上图会先填满第一行,再填满第二行,所以3号项目就会紧跟在1号项目的后面。8号项目和9号项目就会排到第四行。

如果将设置改为column dense,表示"先列后行",并且尽量填满空格。

grid-auto-flow: column dense;

上面代码的效果如下。

img

上图会先填满第一列,再填满第2列,所以3号项目在第一列,4号项目在第二列。8号项目和9号项目被挤到了第四列。

3.6 justify-items 属性, align-items 属性, place-items 属性

justify-items属性设置单元格内容的水平位置(左中右),align-items属性设置单元格内容的垂直位置(上中下)。

.container {
  justify-items: start | end | center | stretch;
  align-items: start | end | center | stretch;
}

这两个属性的写法完全相同,都可以取下面这些值。

  • start:对齐单元格的起始边缘。
  • end:对齐单元格的结束边缘。
  • center:单元格内部居中。
  • stretch:拉伸,占满单元格的整个宽度(默认值)。
.container {
  justify-items: start;
}

上面代码表示,单元格的内容左对齐,效果如下图。

img

.container {
  align-items: start;
}

上面代码表示,单元格的内容头部对齐,效果如下图。

img

place-items属性是align-items属性和justify-items属性的合并简写形式。

place-items: <align-items> <justify-items>;

下面是一个例子。

place-items: start end;

如果省略第二个值,则浏览器认为与第一个值相等。

3.7 justify-content 属性, align-content 属性, place-content 属性

justify-content属性是整个内容区域在容器里面的水平位置(左中右),align-content属性是整个内容区域的垂直位置(上中下)。

.container {
  justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
  align-content: start | end | center | stretch | space-around | space-between | space-evenly;  
}

这两个属性的写法完全相同,都可以取下面这些值。(下面的图都以justify-content属性为例,align-content属性的图完全一样,只是将水平方向改成垂直方向。)

  • start - 对齐容器的起始边框。

img

  • end - 对齐容器的结束边框。

img

  • center - 容器内部居中。

img

  • stretch - 项目大小没有指定时,拉伸占据整个网格容器。

img

  • space-around - 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍。

img

  • space-between - 项目与项目的间隔相等,项目与容器边框之间没有间隔。

img

  • space-evenly - 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。

img

place-content属性是align-content属性和justify-content属性的合并简写形式。

place-content: <align-content> <justify-content>

下面是一个例子。

place-content: space-around space-evenly;

如果省略第二个值,浏览器就会假定第二个值等于第一个值。

3.8 grid-auto-columns 属性, grid-auto-rows 属性

有时候,一些项目的指定位置,在现有网格的外部。比如网格只有3列,但是某一个项目指定在第5行。这时,浏览器会自动生成多余的网格,以便放置项目。

grid-auto-columns属性和grid-auto-rows属性用来设置,浏览器自动创建的多余网格的列宽和行高。它们的写法与grid-template-columnsgrid-template-rows完全相同。如果不指定这两个属性,浏览器完全根据单元格内容的大小,决定新增网格的列宽和行高。

下面的例子里面,划分好的网格是3行 x 3列,但是,8号项目指定在第4行,9号项目指定在第5行。

.container {
  display: grid;
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 100px 100px 100px;
  grid-auto-rows: 50px; 
}

上面代码指定新增的行高统一为50px(原始的行高为100px)。

img

3.9 grid-template 属性, grid 属性

grid-template属性是grid-template-columnsgrid-template-rowsgrid-template-areas这三个属性的合并简写形式。

grid属性是grid-template-rowsgrid-template-columnsgrid-template-areasgrid-auto-rowsgrid-auto-columnsgrid-auto-flow这六个属性的合并简写形式。

从易读易写的角度考虑,还是建议不要合并属性,所以这里就不详细介绍这两个属性了。

四、项目属性

下面这些属性定义在项目上面。

4.1 grid-column-start 属性, grid-column-end 属性, grid-row-start 属性, grid-row-end 属性

项目的位置是可以指定的,具体方法就是指定项目的四个边框,分别定位在哪根网格线。

  • grid-column-start属性:左边框所在的垂直网格线
  • grid-column-end属性:右边框所在的垂直网格线
  • grid-row-start属性:上边框所在的水平网格线
  • grid-row-end属性:下边框所在的水平网格线
.item-1 {
  grid-column-start: 2;
  grid-column-end: 4;
}

上面代码指定,1号项目的左边框是第二根垂直网格线,右边框是第四根垂直网格线。

img

上图中,只指定了1号项目的左右边框,没有指定上下边框,所以会采用默认位置,即上边框是第一根水平网格线,下边框是第二根水平网格线。

除了1号项目以外,其他项目都没有指定位置,由浏览器自动布局,这时它们的位置由容器的grid-auto-flow属性决定,这个属性的默认值是row,因此会"先行后列"进行排列。读者可以把这个属性的值分别改成columnrow densecolumn dense,看看其他项目的位置发生了怎样的变化。

下面的例子是指定四个边框位置的效果。

.item-1 {
  grid-column-start: 1;
  grid-column-end: 3;
  grid-row-start: 2;
  grid-row-end: 4;
}

img

这四个属性的值,除了指定为第几个网格线,还可以指定为网格线的名字。

.item-1 {
  grid-column-start: header-start;
  grid-column-end: header-end;
}

上面代码中,左边框和右边框的位置,都指定为网格线的名字。

这四个属性的值还可以使用span关键字,表示"跨越",即左右边框(上下边框)之间跨越多少个网格。

.item-1 {
  grid-column-start: span 2;
}

上面代码表示,1号项目的左边框距离右边框跨越2个网格。

img

这与下面的代码效果完全一样。

.item-1 {
  grid-column-end: span 2;
}

使用这四个属性,如果产生了项目的重叠,则使用z-index属性指定项目的重叠顺序。

4.2 grid-column 属性, grid-row 属性

grid-column属性是grid-column-startgrid-column-end的合并简写形式,grid-row属性是grid-row-start属性和grid-row-end的合并简写形式。

.item {
  grid-column: <start-line> / <end-line>;
  grid-row: <start-line> / <end-line>;
}

下面是一个例子。

.item-1 {
  grid-column: 1 / 3;
  grid-row: 1 / 2;
}
/* 等同于 */
.item-1 {
  grid-column-start: 1;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 2;
}

上面代码中,项目item-1占据第一行,从第一根列线到第三根列线。

这两个属性之中,也可以使用span关键字,表示跨越多少个网格。

.item-1 {
  background: #b03532;
  grid-column: 1 / 3;
  grid-row: 1 / 3;
}
/* 等同于 */
.item-1 {
  background: #b03532;
  grid-column: 1 / span 2;
  grid-row: 1 / span 2;
}

上面代码中,项目item-1占据的区域,包括第一行 + 第二行、第一列 + 第二列。

img

斜杠以及后面的部分可以省略,默认跨越一个网格。

.item-1 {
  grid-column: 1;
  grid-row: 1;
}

上面代码中,项目item-1占据左上角第一个网格。

4.3 grid-area 属性

grid-area属性指定项目放在哪一个区域。

.item-1 {
  grid-area: e;
}

上面代码中,1号项目位于e区域,效果如下图。

img

grid-area属性还可用作grid-row-startgrid-column-startgrid-row-endgrid-column-end的合并简写形式,直接指定项目的位置。

.item {
  grid-area: <row-start> / <column-start> / <row-end> / <column-end>;
}

下面是一个例子

.item-1 {
  grid-area: 1 / 1 / 3 / 3;
}
4.4 justify-self 属性, align-self 属性, place-self 属性

justify-self属性设置单元格内容的水平位置(左中右),跟justify-items属性的用法完全一致,但只作用于单个项目。

align-self属性设置单元格内容的垂直位置(上中下),跟align-items属性的用法完全一致,也是只作用于单个项目。

.item {
  justify-self: start | end | center | stretch;
  align-self: start | end | center | stretch;
}

这两个属性都可以取下面四个值。

  • start:对齐单元格的起始边缘。
  • end:对齐单元格的结束边缘。
  • center:单元格内部居中。
  • stretch:拉伸,占满单元格的整个宽度(默认值)。

下面是justify-self: start的例子。

.item-1  {
  justify-self: start;
}

img

place-self属性是align-self属性和justify-self属性的合并简写形式。

place-self: <align-self> <justify-self>;

下面是一个例子。

place-self: center center;

如果省略第二个值,place-self属性会认为这两个值相等。

定位

一、position 属性的作用

position属性用来指定一个元素在网页上的位置,一共有5种定位方式,即position属性主要有五个值。

  • static
  • relative
  • fixed
  • absolute
  • sticky

下面就依次介绍这五个值。最后一个sticky是2017年浏览器才支持的,本文将重点介绍。

二、static 属性值

staticposition属性的默认值。如果省略position属性,浏览器就认为该元素是static定位。

这时,浏览器会按照源码的顺序,决定每个元素的位置,这称为"正常的页面流"(normal flow)。每个块级元素占据自己的区块(block),元素与元素之间不产生重叠,这个位置就是元素的默认位置。

img

注意,static定位所导致的元素位置,是浏览器自主决定的,所以这时topbottomleftright这四个属性无效。

三、relative,absolute,fixed

relativeabsolutefixed这三个属性值有一个共同点,都是相对于某个基点的定位,不同之处仅仅在于基点不同。所以,只要理解了它们的基点是什么,就很容易掌握这三个属性值。

这三种定位都不会对其他元素的位置产生影响,因此元素之间可能产生重叠。

3.1 relative 属性值

relative表示,相对于默认位置(即static时的位置)进行偏移,即定位基点是元素的默认位置。

img

img

它必须搭配topbottomleftright这四个属性一起使用,用来指定偏移的方向和距离。

img

div {
  position: relative;
  top: 20px;
}

上面代码中,div元素从默认位置向下偏移20px(即距离顶部20px)。

3.2 absolute 属性值

absolute表示,相对于上级元素(一般是父元素)进行偏移,即定位基点是父元素。

它有一个重要的限制条件:定位基点(一般是父元素)不能是static定位,否则定位基点就会变成整个网页的根元素html。另外,absolute定位也必须搭配topbottomleftright这四个属性一起使用。

img

/*
  HTML 代码如下
  <div id="father">
    <div id="son"></div>
  </div>
*/

#father {
  positon: relative;
}
#son {
  position: absolute;
  top: 20px;
}

上面代码中,父元素是relative定位,子元素是absolute定位,所以子元素的定位基点是父元素,相对于父元素的顶部向下偏移20px。如果父元素是static定位,上例的子元素就是距离网页的顶部向下偏移20px

注意,absolute定位的元素会被"正常页面流"忽略,即在"正常页面流"中,该元素所占空间为零,周边元素不受影响。

3.3 fixed 属性值

fixed表示,相对于视口(viewport,浏览器窗口)进行偏移,即定位基点是浏览器窗口。这会导致元素的位置不随页面滚动而变化,好像固定在网页上一样。

img

它如果搭配topbottomleftright这四个属性一起使用,表示元素的初始位置是基于视口计算的,否则初始位置就是元素的默认位置。

div {
  position: fixed;
  top: 0;
}

上面代码中,div元素始终在视口顶部,不随网页滚动而变化。

四、sticky 属性值

sticky跟前面四个属性值都不一样,它会产生动态效果,很像relativefixed的结合:一些时候是relative定位(定位基点是自身默认位置),另一些时候自动变成fixed定位(定位基点是视口)。

因此,它能够形成"动态固定"的效果。比如,网页的搜索工具栏,初始加载时在自己的默认位置(relative定位)。

img

页面向下滚动时,工具栏变成固定位置,始终停留在页面头部(fixed定位)。

img

等到页面重新向上滚动回到原位,工具栏也会回到默认位置。

sticky生效的前提是,必须搭配topbottomleftright这四个属性一起使用,不能省略,否则等同于relative定位,不产生"动态固定"的效果。原因是这四个属性用来定义"偏移距离",浏览器把它当作sticky的生效门槛。

它的具体规则是,当页面滚动,父元素开始脱离视口时(即部分不可见),只要与sticky元素的距离达到生效门槛,relative定位自动切换为fixed定位;等到父元素完全脱离视口时(即完全不可见),fixed定位自动切换回relative定位。

请看下面的示例代码。(注意,除了已被淘汰的 IE 以外,其他浏览器目前都支持sticky。但是,Safari 浏览器需要加上浏览器前缀-webkit-。)

#toolbar {
  position: -webkit-sticky; /* safari 浏览器 */
  position: sticky; /* 其他浏览器 */
  top: 20px;
}

上面代码中,页面向下滚动时,#toolbar的父元素开始脱离视口,一旦视口的顶部与#toolbar的距离小于20px(门槛值),#toolbar就自动变为fixed定位,保持与视口顶部20px的距离。页面继续向下滚动,父元素彻底离开视口(即整个父元素完全不可见),#toolbar恢复成relative定位。

五、 sticky 的应用

sticky定位可以实现一些很有用的效果。除了上面提到"动态固定"效果,这里再介绍两个。

5.1 堆叠效果

堆叠效果(stacking)指的是页面滚动时,下方的元素覆盖上方的元素。下面是一个图片堆叠的例子,下方的图片会随着页面滚动,覆盖上方的图片(查看 demo)。

img

HTML 代码就是几张图片。

<div><img src="pic1.jpg"></div>
<div><img src="pic2.jpg"></div>
<div><img src="pic3.jpg"></div>

CSS 代码极其简单,只要两行。

div {
  position: sticky;
  top: 0;
}

它的原理是页面向下滚动时,每张图片都会变成fixed定位,导致后一张图片重叠在前一张图片上面。详细解释可以看这里

5.2 表格的表头锁定

大型表格滚动的时候,表头始终固定,也可以用sticky实现(查看 demo)。

img

CSS 代码也很简单。

th {
  position: sticky;
  top: 0; 
}

需要注意的是,sticky必须设在<th>元素上面,不能设在<thead><tr>元素,因为这两个元素没有relative定位,也就无法产生sticky效果。详细解释可以看这里

多列布局

CSS3使用columns属性定义多列布局,属性初始值根据元素个别属性而定,适用于不可替换的块元素、行内块元素、单元格,表格除外。

1设置列宽(column-width)

column-width定义单列显示的宽度

column-width:length|auto;

取值说明:
length:长度值,不可为负值。
auto:根据浏览器自动计算设置。

column-width可以与其他多列布局属性配合使用,设计指定固定列数、列宽的布局效果;

单独使用,限制单列宽度,当超出宽度时,则会自动多列显示。

示例:

<STYLE type="text/css" media="all">
/*定义网页列宽为300像素,则网页中每个栏目的最大宽度为300像素*/
body {
    -webkit-column-width:300px;
    -moz-column-width:300px;
    column-width:300px;
}
</STYLE>

在这里插入图片描述

2设置列数(column-count)

column-count定义列数

column-count:integer|auto;

取值说明:
interger:定义栏目的列数,取值为大于零的整数。
auto:根据浏览器计算值自动设置

示例:

<style type="text/css" media="all">

/*定义网页列数为3,这样整个页面总是显示为3列*/
body {
    -webkit-column-count:3;
    -moz-column-count:3;
    column-count:3;
}

</style>

在这里插入图片描述

3设置列间距(column-gap)

column-gap定义两栏之间的间距

column-gap:normal|length;

取值说明:
normal:根据浏览器默认设置进行解析,一般为1em
length:长度值,不可为负值。

示例:

<style type="text/css" media="all">

body {
    /*定义页面内容显示为三列*/
    -webkit-column-count: 3;
    -moz-column-count: 3;
    column-count: 3;
    /*定义列间距为3em,默认为1em*/
    -webkit-column-gap: 3em;
    -moz-column-gap: 3em;
    column-gap: 3em;
    line-height: 1.8em; /* 定义页面文本行高 */
}


</style>

在这里插入图片描述

4设置列边框样式(column-rule)

column-rule定义每列之间边框的宽度、样式和颜色

column-rule:length|style|color|transparent;

示例:

<style type="text/css" media="all">

body {
    /*定义页面内容显示为三列*/
    -webkit-column-count: 3;
    -moz-column-count: 3;
    column-count: 3;
    /*定义列间距为3em,默认为1em*/
    -webkit-column-gap: 3em;
    -moz-column-gap: 3em;
    column-gap: 3em;
    line-height: 2.5em;
    /*定义列边框为2像素宽的灰色虚线*/
    -webkit-column-rule: dashed 2px gray;
    -moz-column-rule: dashed 2px gray;
    column-rule: dashed 2px gray;
}



</style>

在这里插入图片描述

5设置跨列显示(column-span)

column-span定义跨列显示

column-span:none|all;

取值说明:
none:只在本栏中显示
all:将横跨所有列

示例:

<style type="text/css" media="all">

body {
    /*定义页面内容显示为三列*/
    -webkit-column-count: 3;
    -moz-column-count: 3;
    column-count: 3;
    /*定义列间距为3em,默认为1em*/
    -webkit-column-gap: 3em;
    -moz-column-gap: 3em;
    column-gap: 3em;
    line-height: 2.5em;
    /*定义列边框为2像素宽的灰色虚线*/
    -webkit-column-rule: dashed 2px gray;
    -moz-column-rule: dashed 2px gray;
    column-rule: dashed 2px gray;}
/*设置一级标题跨越所有列显示*/
h1 {
    color: #333333;
    font-size: 20px;
    text-align: center;
    padding: 12px;
    -webkit-column-span: all;
    -moz-column-span: all;
    column-span: all;}
/*设置二级标题跨越所有列显示*/
h2 {
    font-size: 16px;
    text-align: center;
    -webkit-column-span: all;
    -moz-column-span: all;
    column-span: all;}
p {color: #333333; font-size: 14px; line-height: 180%; text-indent: 2em;}




</style>

在这里插入图片描述

6设置列高度(column-fill)

column-fill定义栏目高度是否统一

column-fill:auto|balance;

取值说明:
auto:各列的高度随其内容的变化而自动变化
balance:各列的高度将会根据内容最多的哪一列的高度进行统一

示例:

<style type="text/css" media="all">

body {
    /*定义页面内容显示为三列*/
    -webkit-column-count: 3;
    -moz-column-count: 3;
    column-count: 3;
    /*定义列间距为3em,默认为1em*/
    -webkit-column-gap: 3em;
    -moz-column-gap: 3em;
    column-gap: 3em;
    line-height: 2.5em;
    /*定义列边框为2像素宽的灰色虚线*/
    -webkit-column-rule: dashed 2px gray;
    -moz-column-rule: dashed 2px gray;
    column-rule: dashed 2px gray;
    /*设置各列高度自动调整*/
    -webkit-column-fill: auto;
    -moz-column-fill: auto;
    column-fill: auto;}
/*设置一级标题跨越所有列显示*/
h1 {
    color: #333333;
    font-size: 20px;
    text-align: center;
    padding: 12px;
    -webkit-column-span: all;
    -moz-column-span: all;
    column-span: all;}
/*设置二级标题跨越所有列显示*/
h2 {
    font-size: 16px;
    text-align: center;
    -webkit-column-span: all;
    -moz-column-span: all;
    column-span: all;}
p {color: #333333; font-size: 14px; line-height: 180%; text-indent: 2em;}




</style>

在这里插入图片描述

响应式设计

媒介查询

同一个CSS文件中,也可以根据不同的屏幕分辨率,选择应用不同的CSS规则。

@media screen and (max-device-width: 400px) {

.column {
      float: none;
      width:auto;
    }

#sidebar {
      display:none;
    }

}

上面的代码意思是,如果屏幕宽度小于400像素,则column块取消浮动(float:none)、宽度自动调节(width:auto),sidebar块不显示(display:none)。

  1. 将可能会出现在一行的表单项放在一个父级容器内
  2. 父级容器设置flex-flow: row wrap;表示横向排列,空间不足时换行
  3. 根据不同的屏幕宽度设置flex: 0 0 50%(两列)/33%(三列)/25%(四列)
@media screen and (max-width: 1280px) {
    flex: 0 0 50%;
}
@media screen and (min-width: 1281px) and (max-width: 1440px) {
    flex: 0 0 33.33%;
}
@media screen and (min-width: 1441px) {
    flex: 0 0 25%;
}

媒体查询(Media Queries)

Media Queries 能在不同的条件下使用不同的样式,使页面在不同在终端设备下达到不同的渲染效果

Media Query 原理:允许添加表达式用以媒体查询(包括 媒体类型媒体特性),以此来选择不同的样式表,从而自动适应不同的屏幕分辨率

使用方式
  • 通过 link 标签中判断设备的尺寸,从而引用不同的 css 样式文件
html
复制代码<!-- style.css 样式被用在宽度小于或等于 480px 的手持设备上,或者被用于屏幕宽度大于或等于 960px 的设备上 -->
<link rel="stylesheet" type="text/css" href="style.css" media="handheld and (max-width:480px), screen and (min-width:960px)" />
  • 通过 @media 判断设备的尺寸应用不同的 css 样式
css
复制代码// 屏幕大于 1024px 或小于 1440px 时应用该样式
@media screen and (min-width: 1024px) and (max-width: 1440px) {
  ...
}
响应式设计实践
  1. 设置 meta 标签
html
复制代码<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
  1. 使用 @media 设置样式
css
复制代码// 屏幕大于 1024px 或小于 1440px 时应用该样式
@media screen and (min-width: 1024px) and (max-width: 1440px) { 
  ...
}
  1. 依据要求并结合屏幕尺寸设置布局分界点
css
复制代码// 屏幕大于 1440px 时应用该样式
@media screen and (min-width: 1441px) { 
  ...
}

// 屏幕大于 1024px 或小于 1440px 时应用该样式
@media screen and (min-width: 1024px) and (max-width: 1440px) { 
  ...
}

**说明:**设置布局分界点时需要注意样式的先后顺序,后面的 @media 范围不应该包含前面的范围(满足条件时,后面的样式会覆盖前面的样式)

常见的屏幕尺寸
yaml
复制代码分辨率   比例 | 设备尺寸

1024 * 500		(8.9 寸)
1024 * 768		(4 : 3  | 10.4 寸、12.1 寸、14.1 寸、15 寸)
1280 * 800		(16 : 10  |15.4 寸)
1280 * 1024		(5:4  | 14.1寸、15.0寸)
1280 * 854		(15 : 10 | 15.2)
1366 * 768		(16:9 | 不常见)
1440 * 900		(16:10  17寸 仅苹果用)
1440 * 1050		(5:4  | 14.1寸、15.0寸)
1600 * 1024		(14:9 | 不常见)
1600 * 1200		(4:3 | 15、16.1)
1680 * 1050		(16:10 | 15.4寸、20.0寸)
1920 * 1200		(23寸)

Grid布局

  1. 设置父容器为grid布局
  2. 设置每一列的宽度为自动填充,最小宽度420,最大1fr
css
复制代码display: grid;
grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));

栅格布局

一、 什么是栅格
1. 栅格的由来

栅格就是网格。就是这种有规律的格子

img

哈哈,这样一说是不是就很接地气了。

英文翻译过来就是网格,至于现在为什么叫栅格就不得而知道,

img

栅格最早是应用于平面设计中。产生于二十世纪初的西欧,完善于五十年代的瑞士。通过有规律的网格来指导版面布局。

栅格设计的在屏幕端的应用也十分广泛,不光为设计服务,对响应式开发也起到了很大的作用。虽然开发小哥说的栅格和我们理解的不太一样,但也减少了沟通成本。

2. 网格Grid

网格是构成页面栅格系统的最小单位。

PC端我们一般用8作为网格的最小单位。

img

为什么用8?

尽量保持单位是偶数,这样在页面放大或者放大或者缩小时还能保持清晰。在保证偶数的前提下,使用“ 2、4、6、8、10、12… ”作为最小单位都是可以的。

通常情况下PC端横向是固定的,纵向是可以滚动的。根据2019年中国PC端分辨率端统计,“4、8”只有不能被1366整除,其他都可以。由于4过于小,普通用户从视觉上不容易分辨差别,所以我们选用8作为最小单位。之后所有的数值都使用8的倍数。

img

3. 栏Columns和槽Gutters

栏(Columns)是呈放内容区域。

PC端通常有12栅格或24栅格,意思就是纵向有12栏或24栏。

槽(Gutters)是两个栏中间的间距。槽的数量比栏的数量少一个。

假设是栅格宽度是W、栏的宽度是C、槽的宽度是G。有N个栏,就有N-1个槽。

则可以推断出算出W=N*C+(N-1)G。

忘掉 栏+槽=列的概念,(个人感觉没有作用,有不同见解的欢迎讨论。)

img

为什么用12或24栏

12栏和24栏都是PC端较常用的。移动端用4栏的居多。分的越细可变化的内容越丰富。但过于细也会使页面变得很碎,差异感和韵律感降低。12或24栏可以被2等分、3等分、4等分、6等分、12等分,还能按 1:2:1 、 1:3:2 、 1:2:2:1…等比例分割,提供了足够丰富的变化。

以下是京东首页的截图,应该是采用了12栅格,并且分别采用了2等分、四等分、六等分、2:6:2:2 、 2:10 。

img

4. 边距 Margin

栅格宽度外的边距,通常做自适应的距离。例如小屏和大屏之间做响应,就会改变边距,

img

5. 栅格宽度 Container

栅格宽度是需要栅格设计区域的宽度,不是显示器宽度

img

img

举例:假设我们以1920px的屏幕为画板作图、使用24列栅格。设定栏的宽度为32px4(个原子单位),槽的宽度为16px(2个原子单位)。

则栅格宽度W=24列 x 32栏宽 + 23 列x 16槽宽=1136px。其余宽度做自适应处理。

在1920屏宽下如下图所示:

img

应用原则

  1. 内容必须落在栏上,不能落在水槽中
  2. 父元素需对齐栅格,子元素可再做栅格
  3. 尽量按栅格做等分,平分成5等份也是可以的,前端工程师就需要改底层结构了。
二、为什么用栅格

不用栅格设计行不行? 行!

行,不用栅格没问题。很多优秀作品都没有刻意的遵守传统的栅格,反而显得更加灵动。但是打破规则前得知道规则才行。

使设计更有规律和逻辑

基于栅格设计,按一定的规律把文字和图片排列在页面之中,使版面不光具有视觉感官的美感,也具有严谨的逻辑和一定韵律。

利于团队协作

有了统一的栅格标准,就可以解释为什么“这个宽度要用120px,那个宽度不能用140px…”之类的问题。设计团队之间沟通成本就大大降低。同时也能提高团队作业的一致性。

响应式设计

现在人们使用的设备不在局限电脑或者手机,用户可能使用任何尺寸的设备来访问我们的设计。所以我们不能为单一的设备来设计,怎么动态的构建我们的设计、响应不同尺寸的设备,是设计师在起初就应该考虑的。

三、 栅格系统如何响应的
1. 什么是响应式设计

通俗的讲就是:为了让设计在各种尺寸的设备上都保合理、持美观,用户无论用手机、平板、电脑使用我们的产品时都有良好都体验。检测到不同的屏幕尺寸的时候改变栅格的一些数值,变成我们预先设计的样式,这就是响应式设计。

2. 栅格是怎么响应的
固定栅格

栏和槽的宽度是固定不变的,不随屏幕的大小而变化。到一定的临界值的时候栅格列数会发生变化。

假设在我们以1920的屏幕大小为画板,栅格宽度是1136,看到的如下图。

img

在2560的屏幕下看页面,两侧的留白就会变大,中间的内容保持不变

img

在1024的屏幕下看页面,就会出现横向滚动条,页面仿佛被截断一样。

img

在更小的屏幕下,栅格的列数会发生变化。但无论怎么变化,栏和槽的宽度是不变的。

img

在临界值之间设计的布局不会改变。具体到什么临界值栅格的列数会发生变化,需要跟开发说清楚。临界值设置多少、设置多少个临界值要根据实际情况来制定。

**优点:**设计的还原度是最高的,无论在什么什么屏幕下,核心样式是保持不变的。

**缺点:**在小屏下会有滚动条。在大屏上左右留白过多,有点浪费空间。

流动栅格

栏的宽度是变化的,随屏幕的大小而变化。槽的宽度固定不变。到一定的临界值的时候栅格列数会发生变化。

假设在我们以1920的屏幕大小为画板,栅格宽度是1136。看到的如下图。

img

在2560的屏幕下看页面,槽的宽度保持不变,栏的宽度发生改变。

img

在1024的屏幕下看页面,槽的宽度保持不变,栏的宽度发生改变。

img

问题来了,这样一算栏的像素就不但不是偶数,而且还不是整数了,怎么办,屏幕该怎么显示呢?没关系,有的卡片可能是351个像素,有的是356个像素,这样1像素的差距在屏幕上很难看出差别来,为了在不同大小的屏幕上适配,这1像素是可以忍受的。

需要把子元素内的布局样式,那些是可以变动的地方跟前端说明即可。(例如:当连变化时,卡片内的图标保持左对齐,左边距不变。文字左对齐,每行的文字数量自适应。)

**优点:**在不同屏幕下会自动放大或缩小,更充分的利用空间。

**缺点:**由于栏宽是不固定的,样式可能会发生变形。文字可能会变成多行或者超长的一行。

混合栅格

在同一页面中可以分成多个区域,每个区域做不同栅格类型。

img

四、 实例:从0建立后台栅格系统
1. 确定栅格的基准

根据自家的业务场景定下最小单位和栅格数量,我们以8为最小原子单位距离,之后所有的数值是8的倍数。栅格数量采用12举例。

2. 确定栅格区域

后台系统和网页不同,往往逻辑复杂、数据量大,同时需要获取、比对很多的信息。

信息以表格、表单居多。所以屏幕的宽度就显得很重要了,寸土寸金。所以通常选中全部填充的样式,舍弃两侧留白的样式。

我们选择设备比例最多1920x1080为画板。(这里主要将纵向栅格,暂不考虑浏览器自身的标签栏和菜单栏的高度)

制定如下的样式,数值仅供参考,照搬的请慎重。

img

3. 放置内容

在栏内放置内容,内容不能在开始和结尾不能在槽里。内容的高度也需要保持8的倍数。

img

4. 响应策略

大/小屏幕响应

当屏幕变大时,左侧蓝色菜单栏保持宽度不变(固定栅格)。右侧栅格区域的槽保持不变,栏等比例扩大。(流动栅格)

当屏幕变小时,左侧蓝色菜单栏保持宽度不变(固定栅格)。右侧栅格区域的槽保持不变,栏等比例缩小(流动栅格)

img

平板响应

当屏幕小到平板的尺寸时候,栅格区的内容就无法正常显示了,十分影响体验。于是就是改变栅格的数量,变成6列栅格,同时菜单栏收缩简要模式。这样就完成了平板端的适配

img

手机响应

当屏幕是iPhone8、8P…等手机尺寸时候,栅格区就改为更少的栅格,同时菜单栏变为汉堡按钮。还可以把一些内容做隐藏处理,例如常见的咨询客服、相关推荐等。

img

Flex布局

  1. 将可能会出现在一行的表单项放在一个父级容器内
  2. 父级容器设置flex-flow: row wrap;表示横向排列,空间不足时换行
  3. 设置容器内每一项元素的flex: 0 0 420px;(420px为每一项元素的基础宽度)
css
复制代码flex: 0 0 420px;
等同于
flex-grow: 0;
flex-shrink: 0;
flex-basis: 420px;

CSS 预处理器

CSS 预处理器是一个能让你通过预处理器自己独有的语法来生成CSS的程序。市面上有很多 CSS 预处理器可供选择,且绝大多数 CSS 预处理器会增加一些原生 CSS 不具备的特性,例如代码混合,嵌套选择器,继承选择器等。这些特性让 CSS 的结构更加具有可读性且易于维护。

CSS 预处理器:

Sass

基础用法

变量:使用$符号定义变量,可以减少代码的重复。

$primary-color: #333;
$secondary-color: #666;

body {
  background-color: $primary-color;
  color: $secondary-color;
}

嵌套:使用嵌套可以减少代码的层级,并提高可读性。

.wrapper {
  width: 100%;

  .box {
    width: 50%;
    float: left;
  }

  .content {
    width: 50%;
    float: right;
  }
}
  • 混合(Mixin):使用Mixin可以将一组属性打包成一个整体,便于重复使用。

@mixin flex {
  display: flex;
  justify-content: center;
  align-items: center;
}

这是一个简单的 mixin,用于定义一个 flex 布局,并使其子元素在主轴和交叉轴上都居中对齐。接下来,我会演示如何使用这个 mixin。

首先,在你的 SCSS 文件中,使用 @include 关键字来引入 mixin:

scssCopy code
.container {
  @include flex;
} 

JavaScript

ECMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会,European Computer Manufacturers Association)通过ECMA-262标准化的脚本程序设计语言。这种语言在万维网上应用广泛,它往往被称为JavaScriptJScript,所以它可以理解为是JavaScript的一个标准,但实际上后两者是ECMA-262标准的实现和扩展。

JavaScript是什么?

js是一个脚本语言(脚本语言可以在浏览器中执行,无需编译,执行顺序是从上到下解析,没用生命周期) js是基于对象和事件驱动的、解释型的松散型语言。

基于对象

(一切皆对象)

事件驱动:

对浏览器和用户的行为进行响应

解释型:

​ 浏览器自身可以解析执行无需编译解析

松散型(弱类型)

JS语言

如何执行

一、html中引入JS的方式

1.引入外部文件

  注意:标签内不能写入内容

2.嵌入式

3.在超链接以及重定向里面写入

  * 超链接的表现形式
    <!-- 普通链接 -->
      	<a href="http://"></a>
      	<!-- 在js里写入代码 -->
      	<a href="javascript:alert('1')"></a>
      	<a href="javascript:void(0)"></a>
      	<!-- 资源下载,默认只能是压缩过的文件 -->
      	<a href="1.zip"></a>
      	<!-- 空链接   点击后会跳转到页面顶部-->
      	<a href=""></a>
  * 重定向
    <form action="javascript:alert(1)" method="get">
      		<input type="submit">
      	</form>

4.在事件之后调用

注意:多个script块之间会相互影响。

二、如何输出

1、js输出工具

a 把想要展示的数据输出至页面

b 调试

1. alert();

在页面中弹出一个对话框。注意:alert()会阻止后面代码的执行

2. console.log();

将数据内容输出到控制台

3. document.write();

将数据内容输出到页面中

注意:识别标签和行内样式

4. confirm();

在页面中弹出一个带确定和取消按钮的弹出框

5. prompt(‘请输入你的姓名’);

页面中弹出一个带提示信息和输入框的弹出框

  • 注释标签

三、变量

3-1、命名规范:

  1. 变量必须以字母,下划线_或者 开头,后面部分可以跟任意的字母、数字、下划 线 、 或 开头,后面部分可以跟任意的字母、数字、下划线_、或 开头,后面部分可以跟任意的字母、数字、下划线;
  2. 不能使用关键字(JS自定义的var)或者是保留字(为以后扩展)命名;
  3. .JavaScript有自己的命名习惯
	* * 驼峰命名法:getElementById
	* * 首字母大写法:object

4.变量名区分大小写

5.命名一定要有意义,提高代码的可读性

3-2、什么是变量:

变量是保存数据的一个容器。 内存就是一个盒子,每次声明一个变量,它都会在内存中开辟一段空间进行保存。保存起来后,当我们需要用的时候会从内存中获取相应的数据。如果浏览器关闭,内存会释放空间,方便下次使用。

3-3、变量声明(通过关键字):

1. var
2. let(ES6)不适合IE10及以下

let的用法类似于var

let不存在变量提升现象

let不能重新声明赋值,报错为变量已声明

let存在块级作用域(es6)

3. const(ES6)

const声明的是一个常量

const只能声明的同时进行赋值

const不存在变量提升现象

const不能重新声明赋值,报错为变量已声明

3-4、变量的赋值情况

1、声明变量的同时进行赋值

2、声明之后赋值

3、声明多个变量并同时进行赋值时使用逗号”,“隔开

4、 声明多个变量之后赋值

注意:

1.变量声明之前进行调用,会返回undefined。【变量提升现象】

2.不通过关键字声明的变量,但是赋值之后,它会返回对应的值。(全局变量)

3.不通过关键字声明的变量,没有赋值,会报错。

4.对变量重新赋值会覆盖之前的值。

5.重新声明相同的变量并进行赋值,会发生覆盖。

四、数据类型

能够表达或者操作值的类型成为数据类型

4-1、为何要划分数据类型?

1. 需求
2. 在内存中存储的位置不一样

分类:

一. 初始类型

(存放于栈区,内存比较小,访问速度快)

1. undefined
可能的情况:声明变量并未赋值,返回undefined
	   声明变量之前访问,返回undefined

2. null(空,占位符)
可能的值:null
返回的值:null
返回值的类型:object

3. number(数值类型)
整型、浮点型、二进制、八进制、十进制、十六进制、科学计数法
返回的值:对应的数值
返回值的类型number

4. string(字符串类型)通过引号引起来的
返回的值:对应的字符串
返回值的类型:string

5. 布尔类型

(boolean) true、false

6. symbol(es6)
二. 引用类型(存放于堆区,内存大,访问速度慢)
object(数组、函数)

五、运算符

一、算数运算符:+ - * / % ++ –

加法 +
* 进行加法运算
** 如果两个操作数都是number,最终得到number的值
** 如果其中一个操作数是undefined,最终得到NaN(not a number),是number的一个状态。
** 如果其中一个操作数是null,最终得到number的值
** 如果一个操作数是布尔值,会转换成对应的值进行计算
* 字符串连接
** 如果操作数有一个string,最终类型为string

减法 -
* 进行减法运算
** 如果两个操作数都是number,最终得到number的值
** 如果其中一个操作数是undefined,最终得到NaN(not a number),是number的一个状态。
** 如果其中一个操作数是null,最终得到number的值
** 如果一个操作数是布尔值,会转换成对应的值进行计算
** 如果其中一个操作数是string
	*** 数值:隐式转换
	*** 字母:NaN
** 如果两个操作数都是string,得到NaN

乘法 *
*特殊用法:**  幂次运算

自增:

i先自增,再执行;i先执行,再自增;

自减:

–i先自减,再执行;i–先执行,再自减;

二、比较运算符(关系运算符)

  1. 如果操作数是字符串类型,会先进行隐式转换,转换成功进行正常运算,转换不成功永远返回false
  2. null==0返回false
  3. undefinednull返回true;undefined=null返回false
>
<
==
===
>=
<=
!=

三、赋值运算符(= 、+=、-=、* =、/=)

四、逻辑运算符(&& || !)

​ 1. 可以操作任何类型的数据 ​ 2. 数字0,false,undefined,null,NaN, 空字符串会转换为false ​ 3. &&同真为真(返回后面的值),其余都为假(返回假的值),如果第一个操作数为假,发生短路原则,对第二个数不进行操作,并返回假的值

4. || 同假为假,其余全为真,如果第一个操作数为真,发生短路原则,对第二个数不会进行操作

num1num2result返回值
truetruetruenum2
truefalsetruenum1
falsetruetruenum2
falsefalsefalsenum2

五、其他运算符

  1. 一元运算符(typeof、 ++、–、+、-、delete)
  2. 三元运算符 条件表达式?为真的值:为假的值

语法是 条件 ? 结果1 : 结果2;. 这里你把条件写在问号(?)的前面后面跟着用冒号(:)分隔的结果1和结果2。满足条件时结果1否则结果2。

六、特殊运算符()

作用:提高优先级

七、模版字符串(es6)

作用:方便引入变量这是-${变量} 需要使用反引号引起来,如果需要引入变量通过${变量名}

六、流程控制

一、流程

程序代码的执行顺序。 注意:JS的执行是根据浏览器的解析从上到下,一条语句一条语句的执行,有且只有这一种方式。

二、流程控制

通过规定的语句让程序代码有条件的按照一定的方式执行。

三、表达式

表达式一般由运算符合操作数构成,且有一定的值(已经有值或者即将赋值)

四、语句

以;为标识的为一条语句。

* 声明语句(声明一个变量、数组。。)
* 赋值语句(对变量进行赋值)
* if语句,switch语句,for语句
* 函数

五、三大流程控制

1. 顺序结构
是程序中最基本的流程控制。默认从上到下,一条语句一条语句执行。

2. 选择结构
a. 分支结构

if(条件){

执行的语句

}else{ ​ }

  • 注条件可以是表达式也可以是任何数据类型
b. 条件结构

switch(表达式){

case 条件1:条件1成立执行的语句;
break;
case 条件2:条件2成立执行的语句;
break;
...
default:条件都不满足之执行的语句

}

3. 循环结构

当条件满足的时候,需要重复的执行一段代码; for(初始化变量;条件表达式;步操作){

执行的语句

}

while(){}与do{}while()的区别
  • while(){}满足条件才执行循环体;
  • do{}while()先执行一次循环体,再进行判断
while(){}与for(){}的区别
  • 循环次数确定时用for;
  • 循环次数不确定时用while
终止语句
continue;跳出本层循环
  • 注意:最好用适当的语句替代continue语句;
break;跳出整个循环(只能跳出一层循环);

一次跳出多层循环,在要跳出的循环体前加一个标记,比如:‘out:’,那么终止语句就是‘break out;’.

七、数组

注意:
数组默认值为空数组。【变量的默认值是undefined】
数组元素的长度是可变的
数组可以保存任何类型的数据
数组下标是从0开始

一、数组

  • 数组就是存储一组或者一系列相关数据的集合。

二、优势

  • 方便对数据进行管理
  • 方便保存大批量的数据

三、创建方式

1.json格式 arr=[]; 2.通过实例化对象的方式 var arr=new Array();

四、赋值情况

1.声明的同时进行赋值 2.声明之后进行赋值,以下标的方式进行赋值,例如:

* var arr=[];
* arr[0]=1;
* arr[1]=2;
* arr[2]=3;
* arr[3]=4;
* ...

五、数组的访问

以下标的方式进行访问

  • length属性:统计数组的长度
  • 访问数组的第一个元素:arr[0]
  • 访问数组的最后一个元素:arr[arr.length-1]

六、数组的遍历( for / for in /forEach )

for in【数组和对象的遍历】最终遍历出来的是对象的属性

forEach(callback(current,index,arr))
该方法用来对数组进行遍历并对每个元素执行一次提供的函数;
当前元素,当前元素的下标,当前元素所属的数组对象。

八、函数

什么是函数

函数就是将能够实现某一特定功能的代码块封装起来,方便重复调用。

函数的特点

程序会更加简洁,便于维护。

函数的声明方式

1.通过关键字

function 函数名称([形参],[形参1],…reset){函数体}

2.通过字面量

var 变量名=function(){}

3.通过实例化对象方式

var a = new Function();

函数调用

1.函数名/变量名();
2.函数自调用

注意:

3.事件之后调用

只需要写函数名

注意:
* 函数自调用的时候,无论之前是什么,都必须加  分号‘ ; ’ 。
* 函数名重复会发生覆盖
* 通过关键字声明的函数,可以在声明之前进行访问【优先级提升现象】,通过字面量声明的函数只有在解析到它的时候才会进行赋值
* 代码从上到下一条语句一条语句解析执行。多个script块之间由于解析环境一样,它们之间相互影响,调用不同script块中的函数时,注意要先声明再调用。【针对于多个代码块之间】

函数参数

*默认参数
	1.直接在形参后设置,放在最后的位置 
	2.通过三元运算符
	形参=形参===undefined?默认值:实参;
	3.逻辑  ||
	形参=实参||默认值;
* 声明函数时(形参),调用函数时(实参)
动态改变函数体内相对应的值和类型,实现不同效果

有关函数参数的个数

实参和形参一一对应
实参个数小于形参时,多余的形参返回undefined
实参个数大于形参时,只返回形参对应的值

有关多余实参的接收问题

1.reset 参数:接收剩余参数时作为数组处理
function fn (a,b,...reset){
	alert(a,b,reset);
	/*...reset 是一个运算符*/
}
2. arguments 对象
当我们创建一个函数时,默认创建一个arguments对象。
在arguments保存了所有参数对象    
arguments.callee();指向函数自身        

函数的返回值 return

* 在函数调用的地方返回值
* return;返回undefined;
return只能返回一个值,如果是多个值,会发生覆盖,最终返回最后一个值。
* 终止函数执行 终止return之后的语句

作用域

有关变量和函数的访问范围

环境

1.宿主环境:浏览器
2.执行环境:决定了变量和函数的访问权限
全局环境;
函数环境;


作用域中分全局作用域和局部作用域

全局作用域:在任何地方都可以访问的变量

​ 在函数外部声明的变量

​ 没有通过关键字声明的变量,并且同时赋值

​ window 对象(Window拥有全局作用域)

局部作用域:在规定的代码块内能够访问的变量

​ 块级作用域{}:es6,if,switch,for ​ ​ 作用域链:作用域链的存在造成了闭包函数的产生

十二、闭包函数

​ 闭包函数:函数中存在作用域链,在函数中的变量全部保存在作用域链中,这样的特性,我们称为闭包。 ​ ​ 闭包函数的作用:保存局部变量; ​ 在函数外部访问局部变量

十三、回调函数

​ 把一个函数的指针(直接写函数名)作为参数传递给另一个函数,这个函数就叫回调函数。

​ 传参方式: ​ 1、通过函数指针 ​ 2、把整个函数传进去

十四、递归函数

​ 在函数内部直接调用自己或者间接调用自己

​ 阶乘 n! = n * (n-1)! 0! = 1

函数重载

argument实现

  • 同一个函数因为传入的参数的类型或个数不同,可以对应多个函数的实现,而且每种实现对应一个函数体
  • 重载函数常用来实现功能类似而所处理的数据类型不同的问题

预解析顺序

  • 1.按照块来解析,有多个代码块时,按照顺序,从第一个代码块开始解析
  • 2.按环境来解析
  • 3.遇到关键字var和function时,(即以关键字创建的函数),提前解析到内存中,(相对应的环境里)。即可在声明前调用。
  • 4.若还有代码块,再按照上面的顺序进行解析

内置顶层函数

  • escape();对字符串进行编码 对非字母、数字、特殊标点符号(@ + - ./ * 。)的字符串进行编码,最终得到十六进制的转义序列。也就是计算机可以识别的。
  • unescape(str);对编码的字符串解码

有关数据类型的转换

Number();

将 任何数据类型转换为数值类型 如果是布尔值,true为1,false为0 如果是数值,转换为本身,会将无意义的后导零与前导零去掉; 如果为null,转换为0; 如果是undefined,转换为NaN not a number; 如果是字符串 如果字符串中只有数字,则转换为数字(十进制)会忽略前导0和后导0; 如果是规范的浮点数,则转换为浮点数 会忽略前导0和后导0; 如果是空字符串,转换为0; 如果是其他值,转换为NaN

parseInt();

将任何数据类型转换为整数 如果一个字符串中只包含数字,转换为十进制数 如果有多个空格,会先找到第一个非空数值进行转换,直到非数值时结束 如果第一个不是以数字或者空格开头的,一定转换为NaN 有两个参数时,第一个表示要转换的值,第二个参数表示转换为几进制,返回值是一个十进制的数字:第一个参数从最高位开始计算,只要有一位数可以识别为第二个参数传入的进制,则可以实现转化,第二个参数可以传入的值为2-36.

parseFloat();

将任何数据类型转换为浮点数并返回 只有一个点起作用,其他无效; 如果字符串是一个有效的整数,他返回的是整数,不会返回浮点数。

String();

将任何数据类型转换为字符串 如果是null,undefined转换为字符串‘null’、’undefined‘; 如果是数值类型,转换为本身的字符串,123转换为‘123’; 如果是布尔类型,true为‘true’,false为‘false’

Boolean();

把任何数据类型转换为布尔型 转换为假: 空字符串,null,undefined,0,false,NaN; 其他都为真。

isNaN();

判断一个数据能否转换为数值; 如果能转换数值之返回假,不能返回真

eval();

将符合JS语法规范的字符串转换成javascript命令执行(必须在一行)

toString();

将对象以字符串的方式来表示,都是通过对象的方式来调用的 格式:对象.toString();

  • 1.数组 分割的字符串
  • 2.布尔
    • 3.字符串(还是本身)
    • 4.数值类型
    • 5.null与undefined没有toString()方法

对象

instanceof 判断一个实例化对象是或否是通过构造函数而来,真伪true,false

1、什么是对象

属性和行为的集合。

​ 属性:描述对象特征的数据

​ 行为:操作对象方法的数据

2、类和对象的关系

类是对象的抽象,对象是类的实例化

3、声明对象

1、实例化 new

2、字面量 {}

3、构造函数

4、添加属性和方法

  • 属性:对象.属性名 = 属性值;

    对象['属性名'] = 属性值;

  • 方法:对象.方法名 = function(){}

    对象['方法名'] = function(){}

5、访问属性和方法

  • 属性:对象.属性名 对象['属性名']

  • 方法:对象.方法名()

    6、删除属性和方法**

    delete

    7、清空对象

    null

    8、for in

    对象:i ->属性名/方法名

    对象名[i] -> 属性值/方法

、浅拷贝和深拷贝

浅拷贝:传地址,会修改原始值。指向的是赋值对象的引用

深拷贝:传值,不会改变。指向的是赋值对象所有引用对象的引用,即传值。 对象封装

将对象的所有组成部分全部组合起来,并对部分细节进行隐蔽,使其受到保护。只留下和外界链接的接口。

对象的继承:

1、prototype

2、call/apply 通过改变this指针

call(this,参数…);

四种方式

工厂模式:

方便维护,节省内存。代码不规范。


构造函数模式;

每次调用会重新开辟新地址,造成资源、内存浪费。


原型模式:

实现对象的属性和方法共享

原型就是一个对象。一个对象会继承另一个对象的属性和方法。

1、对象:[[prototype]]

[[prototype]]式对象内部的一个属性,但是不能直接访问。FOX和Chrome提供了‘proto’访问器,ECMANscript提供了Object.getPrototype(Object)访问器

2、函数:prototype

保存的是该函数的原型对象

3、原型对象:constructor

指向的是实例的构造函数

​ 函数对象和原型对象通过prototype和constructor实现相互关联

​ 通过prototype可以实现代码共享:实现继承

注意:

当一个函数作为构造函数来使用时,会把该函数的prototype属性作为原型值赋值給所有通过构造函数实例化的对象的原型。


构造函数+原型:

结合原型和构造函数的优点,将相同的部分共享,不同的部分独立。

类:是一个特殊的对象

ES6中通过类创建一个类

  • 构造函数:

    用来创建/实例化一个类的对象,一个类中只能有一个constructor

    class 类名{

    ​ constructor(name,age){

    ​ this.name=name;

    ​ }

    }

    继承:extends:实现继承
    super:调用父类的构造函数
    class 类名1 extends 类名{

    }

    json数据格式

    是一种比较轻量级的数据格式,采用独立于语言的文本格式,是理想的数据格式。

    两种结构:

    1、对象中

    var obj={“属性名”:属性值,}

    2、数组中

    var arr = [{“属性名”:属性值,},{“属性名”:属性值,},{“属性名”:属性值,}…]

  • 数据传输过程中处理的是JSON字符串;JS中操作的是JSON对象。

    json字符串转化为json对象:

    eval(“(”+json字符串+“)”);

    JSON.parse();

    JSON.stringify(json对象);

对象的分类:

1、内置对象

Math/Global

Array/String/Date/正则

Math对象身上的属性:

​ 1、Math.PI:圆周率

​ 2、Math.E:返回欧拉常数e的值

​ 3、Math.LN2:返回2的自然数对数

Math对象身上的方法
方法含义
abs()取绝对值
round()取近似值四舍五入
floor()取近似值 向下取整
ceil()取近似值 向上取整
max()取一组数中的最大值
min()取一组数中的最小值
random()取随机数
pow(x,y)取x的y次幂
sqrt()取平方根
trunc()去除一个数的小数部分
sin()取正弦值
cos()取余弦值
tan()取正切值
asin()取反正弦值
acos()取反余弦值
atan()取反正切值

角度与弧度之间的转换公式

弧度= 角度 * Math.PI / 180;

角度 = 弧度 * 180 / Math.PI;

Array数组的属性和方法
属性:

​ 1、length:返回/设置数组中元素的个数

​ 2、prototype:返回对象类型原型的引用

​ 3、constructor:代表当前对象的构造函数

方法:
(一)、添加、删除
1、push(元素1,元素2,…);

​ push方法用来向数组的末尾添加元素,返回值为新数组的长度。

​ 一次可以添加多个元素。

​ push方法会影响原数组。

2、pop(元素1,元素2);

​ pop方法用来删除数组中的元素,返回值为新数组的长度。

​ 一次可以删除多个元素

​ pop方法会影响原数组

3、unshift(元素1,元素2);

​ 用来向数组头部添加元素,返回值为新数组的长度

4、shift(元素1,元素2);

​ 用来删除数组头部的元素,返回值为删除的元素

5、splice(start,delete,插入的元素或数组);

​ 删除并在删除的位置插入新的元素并返回删除的元素

(二)、数组转换
1、join([分隔符]);

​ join方法用于将数组按照指定的分隔符转换为字符串,如果没有分隔符,默认为“,”来分隔。

2、toString();

​ 将数组元素转换为字符串

3、valueOf()

​ 返回Array对象的原始值。

(三)、数组的截取
1、slice(start,end);

​ slice方法从已有的数组中返回指定的元素,即从指定位置开始截取,到指定位置(不包括)结束

​ 如果没有指定结束位置,则从指定位置开始,到末尾结束。

​ 支持负数(从-1开始)

​ 返回值为新数组,不会破坏原数组

(四)、数组的连接
1、concat();

​ concat方法用于将数组或值连接成数组,并返回新数组。

​ 该方法不会影响原数组。

(五)、数组的排序
1、sort();

​ sort方法用于对数组中的元素进行排序。排序顺序可以是字母或数字,并按升序或降序排列。如果没有参数,按照字符的编码排序。

​ 如果有参数,这个参数必须是一个函数(回调函数)

//从小到大
arr2.sort(function(a,b){
  return a-b;
})
//从大到小
arr3.sort(function(a,b){
  return b-a;
})


(六)、数组的过滤
filter(function(element,index,arr));

filter返回数组中符合条件的所有元素。在回调函数中定义判断条件返回值为所有判断结果为真的值组成的新数组。

(七)、数组的映射
map(function(current,index,arr));

map方法会返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

(八)、数组的查找
1、indexOf(item,start)

​ indexOf用来返回数组中某个指定的字符串值第一次出现的位置,从指定位置起,从前向后搜索。若是没有找到,则返回-1.

​ 如果没有指定起始位置,将从数组的开始位置起查找。

2、lastIndexOf(item,start)

​ lastIndexOf方法返回数组中某个指定的字符串值最后一次出现的位置,和indexOf方法正好相反。

(九)、数组的判断
1、every(function(item,index,arr){})

​ every方法用来检测数组中的每一项元素是否符合条件。

​ 即在回调函数中进行判断,如果有一个元素不满足条件,则整个表达式返回false,且在其他元素将不再进行判断;日过所有元素都满足条件,则返回true。

​ 注意:every方法不会对空是数组进行检测。

2、some(function(val,index,arr){})

​ some方法用于检测数组中的每一个元素是否满足指定的条件。

​ 即在回调函数中对每个元素一次进行判断,如果有一个元素满足条件,则表达式将会返回true,且其他元素将不再进行判断;如果没有满足条件的元素,则返回false。

​ 注意:some方法不会对空数组进行检测。

(十)、数组反转
reverse()

​ 将数组的索引值颠倒。

(十一)、数组运算
1、reduce(function(total,val,index,arr){})

​ 对数组进行类似累加运算这种形式的运算。

2、reduceRight(function(total,val,index,arr){})

​ 功能同reduce,但是运算是从右往左的。

ECMAScript6
find(function(element,index,arr){})

从数组当中查找某个元素并返回

findIndex(function(element,index,arr){})

从数组中查找某个元素并返回它的索引值。

fill(val,start,end)

用于传入的参数替换数组中从起始位置到索引结束位置的所有元素。

includes(item,start)

判断数组中是否包含某个元素的方法

copyWithin(target,start,end)

从数组的指定位置元素拷贝到数组的另一个指定位置中

​ start忽略,从0开始复制

​ end忽略,复制到arr.length

(十二)、Array构造函数的方法
1、Array.from()

​ Array.from方法用于将两类对象转为真正的数组;类型数组的对象和可遍历的对象。

2、Array.of()

​ Array.of方法用于将一组值,转换为数组。Arraay.of总是返回参数值组成的数组。如果没有参数返回一个空数组。

3、Array.isArray()

​ Array.isArray()用于判断某个值是否为数组,返回布尔类型。

(十三)、遍历
forEach(function(current,index,arr){})

​ 该方法用来对数组进行遍历,并对每个元素执行一次提供的函数。

​ 字符串对象

字符串对象的属性
  • constreuctor 返回构造函数

  • length 返回字符串的长度

  • 字符串的长度是不可写的(只读)不区分大小写,识别空格

字符串对象的方法
(一)、获取
1、str.charAt()

用来返回指定位置的字符

2、str.charCodeAt()

用来返回指定位置字符串的Unicode编码

3、String.fromCharCode()

返回unicode编码所对应的字符串

(二)、位置
1、String.indexOf(item,start)

返回指定值在对象中第一次出现的位置

2、String.lastIndexOf(item,start)

返回指定值在对象中最后一次出现的位置

(三)、包含
1、String.includes(value);

判断字符串中是否包含指定值,包含返回真,不包含返回假

(四)、替换
1、String.replace(str1,str2);

用str2替换str1

(五)、查找
1、String.match(value)

匹配成功返回包含指定信息的数组,不存在null

2、String.search(regexp)

返回匹配字符串的索引值。没有返回-1

(六)、重复
1、String.repeat(num)num次数

返回该字符串被连接在一起指定数量的新字符串

(七)、转换
1、String.split(分隔符,num)
2、String.toUpperCase()
3、String.toLowerCase()
(八)、去空
1、String.trim()

删除字符串两端的空白

2、String.trimleft()

删除字符串左端的空白

3、String.trimRight()

删除字符串右端的空白

(九)、截取
1、String.slice(start,end)

从指定起始位置截取至结束位置,不包含结束位置。返回截取的新字符串。(支持负数)

2、String.substring(start,end)

同slice,但不支持负数

3、String.substr(start,length)

从指定位置起,截取指定长度的字符串

(十)、ES6
1、String.stratsWith(item,start)

判断字符串是否以指定字符开始

2、String.endsWith(item,end)

判断字符串是否已以指定字符结束

2、宿主对象

由JavaScript宿主环境提供的对象,它们的行为完全由宿主环境来决定。

JavaScript宿主对象千奇百怪,但是前端最熟悉得无疑是浏览器环境中的宿主了。

在浏览器环境中,我们都知道全局环境对象是window,window上又有很多属性,例如document。

实际上,这个全局对象window上的属性,一部分来自JavaScript语言,一部分来自浏览器环境。

JavaScript标准中规定了全局对象属性,w3c的各种标准中规定了window对象的其它属性。

宿主对象也分固有的和用户可创建的两种,比如document.createElement来创建img元素。

BOM(浏览器对象模型)

全称Browser Object Model 浏览器对象模型

作用:实现窗口之间的通讯

核心对象:window,拥有全局作用域。

ps: JS中定义的变量是作为window的属性,function作为window的方法。

BOM中的其他对象都是window的子对象 。

通过var声明的变量具有不可操作性。

var c=Object.create();添加对象

name:{
	value:'张三',
	writable:false/true,//是否可以重新赋值覆盖(可写属性)
	configurable:false/true,//是否可以删除属性()
	enumerable:false/true//是否可以枚举(遍历)
}

window对象的属性:

1、获取窗口尺寸

IE8以上及其他浏览器
	window.innerHeight / window.innerWidth
	window.outerHeight / window.outerWidth
IE6:
	document.documentElement.clientHight
	document.documentElement.clientHight


2、获取窗口位置

window.screenX;
window.screenY;


3、获取屏幕分辨率

window.screen.height;
window.screen.width;


顶层窗口:

​ window.top

窗口自身:

​ window.self

window对象的方法:

移动窗口

window.moveTo(x,y);

window.moveBy(x,y);基于当前去改变

重置窗口大小

window.resizeTo();

window.resizeBy();

滚动条位置

window.scrollTo();

window.scrollBy();

时间函数

setInterval(function(){},time);

clearInerval(定时器名称);

setTimeout(function(){},time);

clearTimeout(定时器名称);

一、BOM中涉及到的属性:

1、location:地址栏信息
对象属性:

​ protocol:设置或输出当前地址的协议 ps:http:

​ host:设置或输出带端口号的主机名 ps:www.baidu.com:80

​ port:端口号 ps::8080

​ hostname :设置或输出不带端口号的主机名 ps:www.baidu.com

​ pathname:文件路径 ps:HTML/index.html

​ hash:锚链接 ps:#page1

​ search:查询字符串 ps:?name=admin&&password=dhaslfl

​ href:整个URL地址

Ajax实现异步刷新,不能实现地址栏更新,结合history中的pushState()和replaceState()实现地址栏更新。

对象的方法
location.reload();

页面重新加载

location.assign();

重新打开一个页面,并且会形成历史记录

location.replace();

重新打开一个页面,并且不会形成历史记录

2、history:历史记录

保存了用户浏览过的页面的历史记录。同浏览器中的历史记录不一样,只存在于一个页面打开到关闭。关闭清除。

属性

方法:

​ history.back()

​ history.forward()

​ history.go()

​ 0 刷新 1前进 -1 后退

​ history.pushState()

3、navigator:浏览器信息
4、screen:屏幕信息
5、document:文档对象信息
6、frames:子窗口对象信息
​ ​ DOM

DOM

(document object model)文档对象模型 核心对象是document

document的属性

1、document.title

2、document.URL

3、document.bgColor 获取背景色或更改背景色

4、document.fgColor 前景色,内容设置颜色

5、document.body

6、document.documentElement

7、document.head

document的方法(获取元素的方法)

document.getElementsByTagName(‘div’) 通过指定的标签名获取元素,返回一个集合.[数组]

document.getElementsByClassName(‘box’)[0]; 通过指定的类名获取元素,返回一个集合

document.getElementById(‘box’) 通过指定的ID名获取元素,返回一个对象

document.querySelector(‘’); 通过指定的选择器获取元素或者是元素集合中的第一个元素document.querySelectorAll(‘’);

document.all== document.getElementsByTagName 获取页面中所有的元素 document.images==document.getElementsByTagName(‘’); 获取页面中所有的图片

document.links 获取页面中所有的链接元素

document.form 获取页面中所有的表单元素

document.anchors 获取页面中所有的锚链接元素

document.write()

往页面中写入内容,识别标签 注意:如果将该方法放在window.onload中执行会替换掉页面中所有的内容

操作元素内容

​ 表单元素内容 ​ 对象.value

​ 非表单元素内容 ​ 对象.innerHTML ​ 可以输出标签 ​ 对象.innerText(火狐不兼容) ​ 对象.textContent(火狐浏览器)

操作元素的属性

​ 对象.属性名 对象.getAttribute(‘属性值’);

​ getAttribute只有一个参数–你查询属性的名字

对象.setAttribute(‘属性值’);

​ setAttribute(‘id’,value)只能通过元素节点对象调用的函数 第一参数填带ID属性的值或标签,第二个是赋‘ID’的属性

 { 

console.log(document);

console.log(document.title); 

document.title = '这是我的'; 

console.log(document.title);

console.log(document.URL); 

document.bgColor = '#000'; 

console.log(document.bgColor); 背景色 

document.fgColor = 'blue'; 

 console.log(document.fgColor); 前景色,内容设置颜色  

console.log(document.body);  

console.log(document.head);  

console.log(document.documentElement); 获取根元素

  }

 var div = document.getElementsByTagName('div')[5]; 

 console.log(div);  

通过指定的标签名获取元素,返回一个集合.[数组]  

var box = document.getElementsByClassName('box'); 

 console.log(box);  通过指定的类名获取元素,返回一个集合  

var box1 = document.getElementById('box1');  

console.log(box1);  

通过指定的ID名获取元素,返回一个对象  

var a =document.querySelector('.box');  

console.log(a);  通过指定的选择器获取元素或者是元素集合中的第一个元素  

var son = box.getElementsByClassName('div')  通过指定的标签名获取元素,返回一个集合.[数组]  

var a =document.querySelectorAll('');  通过指定的选则器返回一个集合  

var all = document.getElementsByTagName('');

  var all1 =document.all;  获取页面中所有的元素 

 var img = document.getElementsByTagName('');  

var img = document.images;  获取页面中所有的图片 

 var aa = document.links  获取页面中所有的链接元素  

var aaa = document.anchors  获取页面中所有的锚链接元素

​图片按需加载流程:

var flot = document.getElementsByClassName('flot');  //	调用flot文档信息  

window.onscroll =function() {

 var top = document.documentElement.scrollTop ||  document.body.scrollTop || window.scrollY || window.pageYOffset 
 //	解决兼容性问题声明滚动条top  
 for (var i = 0; i < flot.length; i++) { // 楼层遍历  
 	var ftop = flot[i].offsetTop - 300; // 滚动条的位置  
 	var image = flot[i].getElementsByTagName('img'); // 调用楼层图片  
 	if (top > ftop) { // 判断楼层顶部与滚动条 
    	for (var j = 0; j < image.length; j++) { // 遍历图片  
    		var ster = image[j].getAttribute('ster');
    		image[j].setAttribute('src', ster); // 将ster赋上‘src’的属性  image.src = ster;
 }  }  }  }

BOM和DOM的关系

(1)DOM通过document对象来访问、控制、修改html和xhtml等文档中的内容

(2)BOM通过 window 对象来访问、控制、修改浏览器中的内容

联系:BOM包含DOM。
区别:DOM描述了处理网页内容的方法和接口,即操作页面内部

BOM描述了与浏览器进行交互的方法和接口,即操作页面之间

节点

**元素:**页面中所有的标签,元素—element, 标签----元素—对象

**节点:**页面中所有的内容(标签,属性,文本(文字,换行,空格,回车)),Node

在 HTML DOM (文档对象模型)中,每个部分都是节点:

文档本身是文档节点

所有 HTML 元素是元素节点

所有 HTML 属性是属性节点

HTML 元素内的文本是文本节点 (包括回车符也是属于文本节点)

注释是注释节点

Element 对象可以拥有类型为元素节点、文本节点、注释节点的子节点。

NodeList 对象表示节点列表,比如 HTML 元素的子节点集合。

元素也可以拥有属性。属性是属性节点。

元素和节点的区别:元素是一个小范围的定义,必须是含有完整信息的节点才是一个元素。

换句话说就是 元素一定是节点,但节点不一定是元素。

一个元素是由开始标签、结束标签以及标签之间的数据构成的

总结:元素是元素节点,是节点中的一种,但元素节点中可以包含很多的节点。

节点类型

  • 元素节点:标签

  • 属性节点:属性

  • 文本节点:

  • 注释节点:

  • 文档节点: 类型: nodeName nodeType nodeValus 元素节点 大写标签名 1 null 属性节点 Arrt 2 属性值 文本节点 #text 3 文本内容 注释节点 #comment 8 注释内容 文档节点 #document 9 null

元素的属性

  • obj.childNodes 所有的子节点 文本,空格(换行)

  • obj.children 所有的子元素

  • obj.childElementCount 子元素的个数

    • obj.children.length
  • obj.firstChild 第一个子节点

    • obj.lastChild 最后一个子节点
  • obj.firstElementChild 第一个子元素

    • obj.lastElementChild 最后一个子元素
  • obj.nextSibling 下一个兄弟节点

  • obj.nextSibling 下一个兄弟元素

  • obj.previousSibling 上一个兄弟节点 *obj.previousElementSibling 上一个兄弟元素

  • obj.parentNode=obj.parentElent 父亲节点

节点的属性

(可以使用标签–元素.出来,可以使用属性节点.出来,文本节点.点出来)   * nodeType:节点的类型:1表示标签,2表示属性,3表示文本   * nodeName:节点的名字:标签节点—大写的标签名字,属性节点—小写的属性名字,文本节点----#text   * nodeValue:节点的值:标签节点—null,属性节点—属性值,文本节点—文本内容

节点方法

​创建 createElement(tagName)

添加 appendChild(tagName)

​删除 removeChild(tagName)

let width = bottom.firstElementChild.offsetwidth 获取宽度

let rights = getComputedStyle(bottom.firstElementChild,null) 获取css中的样式

ajax

异步的 JavaScript 和 XML

什么是ajax

ajax的出现,刚好解决了传统方法的缺陷。AJAX 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

XMLHttpRequest 对象

XMLHttpRequest对象是ajax的基础,XMLHttpRequest 用于在后台与服务器交换数据。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。目前所有浏览器都支持XMLHttpRequest

方 法描 述
abort()停止当前请求
getAllResponseHeaders()把HTTP请求的所有响应首部作为键/值对返回
getResponseHeader(“header”)返回指定首部的串值
open(“method”,“URL”,[asyncFlag],[“userName”],[“password”])建立对服务器的调用。method参数可以是GET、POST或PUT。url参数可以是相对URL或绝对URL。这个方法还包括3个可选的参数,是否异步,用户名,密码
send(content)向服务器发送请求
setRequestHeader(“header”, “value”)把指定首部设置为所提供的值。在设置任何首部之前必须先调用open()。设置header并和请求一起发送 ('post’方法一定要 )

五步使用法:

1.创建XMLHTTPRequest对象

2.使用open方法设置和服务器的交互信息

3.设置发送的数据,开始和服务器端交互

4.注册事件

5.更新界面

下面给大家列出get请求和post请求的例子

get请求:

[复制代码](javascript:void(0)😉

//步骤一:创建异步对象
var ajax = new XMLHttpRequest();
//步骤二:设置请求的url参数,参数一是请求的类型,参数二是请求的url,可以带参数,动态的传递参数starName到服务端
ajax.open('get','getStar.php?starName='+name);
//步骤三:发送请求
ajax.send();
//步骤四:注册事件 onreadystatechange 状态改变就会调用
ajax.onreadystatechange = function () {
   if (ajax.readyState==4 &&ajax.status==200) {
    //步骤五 如果能够进到这个判断 说明 数据 完美的回来了,并且请求的页面是存在的
    console.log(ajax.responseText);//输入相应的内容
    }
}

[复制代码](javascript:void(0)😉

post请求:

[复制代码](javascript:void(0)😉

//创建异步对象  
var xhr = new XMLHttpRequest();
//设置请求的类型及url
//post请求一定要添加请求头才行不然会报错
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
 xhr.open('post', '02.post.php' );
//发送请求
xhr.send('name=fox&age=18');
xhr.onreadystatechange = function () {
    // 这步为判断服务器是否正确响应
  if (xhr.readyState == 4 && xhr.status == 200) {
    console.log(xhr.responseText);
  } 
};

[复制代码](javascript:void(0)😉

为了方便使用,我们可以把他封装进方法里面,要用的时候,直接调用就好了

[复制代码](javascript:void(0)😉

function ajax_method(url,data,method,success) {
    // 异步对象
    var ajax = new XMLHttpRequest();

    // get 跟post  需要分别写不同的代码
    if (method=='get') {
        // get请求
        if (data) {
            // 如果有值
            url+='?';
            url+=data;
        }else{

        }
        // 设置 方法 以及 url
        ajax.open(method,url);

        // send即可
        ajax.send();
    }else{
        // post请求
        // post请求 url 是不需要改变
        ajax.open(method,url);

        // 需要设置请求报文
        ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded");

        // 判断data send发送数据
        if (data) {
            // 如果有值 从send发送
            ajax.send(data);
        }else{
            // 木有值 直接发送即可
            ajax.send();
        }
    }

    // 注册事件
    ajax.onreadystatechange = function () {
        // 在事件中 获取数据 并修改界面显示
        if (ajax.readyState==4&&ajax.status==200) {
            // console.log(ajax.responseText);

            // 将 数据 让 外面可以使用
            // return ajax.responseText;

            // 当 onreadystatechange 调用时 说明 数据回来了
            // ajax.responseText;

            // 如果说 外面可以传入一个 function 作为参数 success
            success(ajax.responseText);
        }
    }

}

jQuery

jQuery是一个快速、小巧、功能丰富的JavaScript库。利用一些容易上手的API,它使一些任务,譬如HTML文档遍历和操纵、事件处理、动画,以及Ajax更简单,并能跨浏览器起作用

文档地址:

jQuery API 中文文档 | jQuery API 中文在线手册 | jquery api 下载 | jquery api chm (cuishifeng.cn)

Node.js

官网网址

Node.js 中文网 (nodejs.cn)

Node.js 是一个开源和跨平台的 JavaScript 运行时环境。 它是几乎任何类型项目的流行工具!

Node.js 在浏览器之外运行 V8 JavaScript 引擎(Google Chrome 的内核)。 这使得 Node.js 非常高效。

Node.js 应用在单个进程中运行,无需为每个请求创建新线程。 Node.js 在其标准库中提供了一组异步 I/O 原语,以防止 JavaScript 代码阻塞,并且通常,Node.js 中的库是使用非阻塞范例编写的,这使得阻塞行为成为异常而不是常态。

当 Node.js 执行 I/O 操作时,如从网络读取、访问数据库或文件系统,Node.js 不会阻塞线程和浪费 CPU 周期等待,而是会在响应返回时恢复操作。

这使得 Node.js 可以使用单个服务器处理数千个并发连接,而不会引入管理线程并发的负担(这可能是错误的重要来源)。

Node.js 具有独特的优势,因为数百万为浏览器编写 JavaScript 的前端开发者现在除了客户端代码之外,还能够编写服务器端代码,而无需学习完全不同的语言。

在 Node.js 中,可以毫无问题地使用新的 ECMAScript 标准,因为你不必等待所有用户更新他们的浏览器 - 你负责通过更改 Node.js 版本来决定使用哪个 ECMAScript 版本, 你还可以通过运行带有标志的 Node.js 来启用特定的实验性特性。

npm 简介

npm 是 Node.js 的标准包管理器。

npm 管理项目依赖的下载。

安装所有依赖

如果一个项目有一个 package.json 文件,通过运行

bashcopy
npm install

它将在 node_modules 文件夹中安装项目所需的所有内容,如果它不存在则创建它。

安装单个包

你还可以安装特定的包,通过运行

bashcopy
npm install <package-name>

此外,从 npm 5 开始,此命令将 <package-name> 添加到 package.json 文件依赖。 在版本 5 之前,你需要添加标志 --save

通常你会看到更多的标志被添加到这个命令中:

  • --save-dev 安装并添加条目到 package.json 文件开发依赖
  • --no-save 安装但不添加条目到 package.json 文件依赖
  • --save-optional 安装并添加条目到 package.json 文件可选依赖
  • --no-optional 将阻止安装可选依赖

也可以使用标志的简写形式:

  • -S:--save
  • -D:--save-dev
  • -O:--save-optional

devDependencies 和 dependencies 之间的区别在于前者包含开发工具,如测试库,而后者与生产中的应用打包在一起。

至于 optionalDependencies 的不同之处在于,依赖的构建失败不会导致安装失败。 但是你的程序有责任处理依赖的缺失。 阅读更多关于 可选依赖 的信息。

更新包

更新也很容易,通过运行

bashcopy
npm update

npm 将检查所有包是否有满足你的版本控制约束的更新版本。

你也可以指定要更新的单个包:

bashcopy
npm update <package-name>

版本控制

除了普通下载,npm 还管理 版本控制,因此你可以指定任何特定版本的软件包,或者要求比你需要的版本更高或更低的版本。

很多时候你会发现一个库只与另一个库的主要版本兼容。

或者最新版本的库中的一个错误,仍然没有修复,导致了一个问题。

指定一个库的明确版本也有助于让每个人都使用相同的包版本,这样整个团队就可以运行相同的版本,直到 package.json 文件被更新。

在所有这些情况下,版本控制都有很大帮助,npm 遵循语义版本控制 (semver) 标准。

你可以安装特定版本的软件包,通过运行

bashcopy
npm install <package-name>@<version>

运行任务

package.json 文件支持指定命令行任务的格式,可以使用

bashcopy
npm run <task-name>

例如:

jsoncopy
{
  "scripts": {
    "start-dev": "node lib/server-development",
    "start": "node lib/server-production"
  }
}

使用这个特性来运行 Webpack 是很常见的:

jsoncopy
{
  "scripts": {
    "watch": "webpack --watch --progress --colors --config webpack.conf.js",
    "dev": "webpack --progress --colors --config webpack.conf.js",
    "prod": "NODE_ENV=production webpack -p --config webpack.conf.js"
  }
}

因此,不用输入那些很容易忘记或输入错误的长命令,你可以运行

bashcopy
$ npm run watch
$ npm run dev
$ npm run prod

国内npm源镜像(npm加速下载)

指定npm镜像

npm 官方原始镜像网址是:https://registry.npmjs.org/
淘宝 NPM 镜像:https://registry.npm.taobao.org
阿里云 NPM 镜像:https://npm.aliyun.com
腾讯云 NPM 镜像:https://mirrors.cloud.tencent.com/npm/
华为云 NPM 镜像:https://mirrors.huaweicloud.com/repository/npm/
网易 NPM 镜像:https://mirrors.163.com/npm/
中科院大学开源镜像站:http://mirrors.ustc.edu.cn/
清华大学开源镜像站:https://mirrors.tuna.tsinghua.edu.cn/
腾讯,华为,阿里的镜像站基本上比较全

使用淘宝镜像源加速 NPM

最新的:

 npm config set registry https://registry.npmmirror.com

之前的:

 npm config set registry https://registry.npm.taobao.org

使用阿里云 镜像源加速 NPM

npm config set registry https://npm.aliyun.com

使用腾讯云镜像源加速 NPM

npm config set registry http://mirrors.cloud.tencent.com/npm/

使用华为云 镜像源加速 NPM

npm config set registry https://mirrors.huaweicloud.com/repository/npm/

返回npm 官方原始镜像

npm config set registry https://registry.npmjs.org/

使用那个镜像,只需要 npm config set registry + 对应的镜像网址就好了

npm config set registry 

查看当前的镜像源:npm config get registry

npm config get registry

推荐使用上面的方式指定npm镜像,当然方法不唯一,也可以用 nrm 去指定npm镜像

什么是nrm

nrm 是一个 npm 源管理器,允许你快速地在 npm 源间切换。

安装nrm

npm install -g nrm

使用

查看可选的源

nrm ls    

切换

如果要切换到taobao源,执行命令

nrm use taobao

测试速度

nrm test     

框架

Vue2.0

Vue.js (vuejs.org)

介绍 — Vue.js (vuejs.org)

安装命令

$ npm install -g vue-cli
$ vue init webpack my-project
$ cd my-project
$ npm install
$ npm run dev
npm run build

vue2.0目录结构

├── build                           存放项目打包后的文件
├── node_modules 					项目依赖
├── public 							存放index.html和静态文件
│   ├── idnex.html
│   ├── images							存放图片
│   ├── videos							存放视频
├── mock                            mock测试数据文件
│   ├── hello.js
├── src                             项目源码目录    
│   ├── api  						存放项目的接口目录
│ 		└── myAxios.js					对axios的封装
│ 		└── login.js					其他接口方法
│	├── assets						存放css相关和icon字体图标之类的
│   	└── resetCss  					全局样式和清除默认样式	
│   	└── iocnFonts 					矢量图标以及静态图片
│	│── components 					存放全局组件
│   	└── HelloWorld.vue 				每个组件
│		└── ...vue
│	├── config                       重要配置参数                  
│   	└── index.js                    存放一些配置参数(比如接口代理路径,百度云秘钥等等)
│	├── entry                       存放ts的类型约定(ts项目)                  
│   	└── index.js                    
│	│── plugins 					所需的第三方库(最好按需引入)
│   	└── elementUi.js  				element-ui库
│   	└── vantUi.js 					vant-ui库
│	│── router						存放路由 
│   	└── index.js					路由表及其配置
│	│── stores							vuex状态管理仓库 
│   	└── user.js							用户子模块							
│   	└── login.js						登陆子模块						
│   	└── index.js						根模块root
│	│── utils						工具类
│		└── tools.js					共用方法
│	│──views                         页面目录
│       └── hello.vue
│       └── login.vue
│       └── ....vue						其他页面
│	│──App.vue						设置路由出口 
│	│──main.js						入口文件  
├── .browserslistrc					针对浏览器的兼容性
├── .env.test						测试环境配置文件
├── .env.development				开发环境配置文件
├── .env.production					生产环境配置文件
├── .gitignore						忽略上传到git的文件,比如node_modules和build打包
├── .prettierrc.json				统一代码风格,比如缩进
├── .eslintrc.js					ESlint 语法检查,代码格式化,优化代码
├── babel.config.js					转ES5语法和配置一些插件
├── package.json                    npm包配置文件,里面定义了项目的npm脚本,依赖包等信息
├── package-lock.json               锁定包的版本,自动生成
├── vue.config.js					vue配置文件
├── README.md						项目说明文档,重要

Vue 3.0

简介 | Vue.js (vuejs.org)

前提条件

  • 熟悉命令行
  • 已安装 16.0 或更高版本的 Node.js

安装命令

npm install -g @vue/cli
vue create project

Manually select features–手动选择。

img

手动选择需要哪些插件,按空格加*号表示需要,学习使用就没加linter和一些单元测试。

img

选择vue.js的版本,选择3.x

img

是否使用es6类的语法来创建组件,输入n,因为使用这个需要写很多修饰符,一般是vue2中为了兼容Ts才使用

img

是否使用babel,是(直接回车默认就是yes);是否用history路由模式,是;选择写样式的方法,我选的less;一些配置是放在package.json还是单独的文件里面,选择单独的文件,就是dedicated config files;在之后的项目中是否保留这些设置,我选n,不保留。等待项目创建。

img

还有可能让你选择用npm还是yarn,我选的npm,可根据自己喜好自行选择。

\3. 项目创建成功后,进入该项目(我的项目名是vue3-project)

cd vue3-project/

\4. 启动该项目(我用的npm)

npm run serve

vue3.0目录结构

├── public							存放静态资源,如 HTML 文件、favicon 等
│   ├── index.html					入口的html文件
│   ├── favicon.ico					网站的显示图标
│   └── ...
├── src								是源代码目录,包含了 Vue 组件、路由、状态管理、工具类、插件等
│   ├── assets						存放项目中使用的图片、样式等资源文件
│   │   ├── images
│   │   ├── styles
│   │   └── ...
│   ├── components					存放通用的组件
│   │   ├── common
│   │   ├── layout
│   │   ├── ui
│   │   ├── form
│   │   └── ...
│   ├── views						存放页面级别的组件
│   │   ├── home
│   │   ├── about
│   │   ├── user
│   │   ├── product
│   │   └── ...
│   ├── router						存放 Vue Router 相关的文件
│   │   ├── index.js
│   │   └── ...
│   ├── store						存放 Vuex 相关的文件
│   │   ├── index.js
│   │   ├── modules
│   │   └── ...
│   ├── utils						存放一些工具类、公共函数等
│   │   ├── api.js
│   │   ├── auth.js
│   │   ├── request.js
│   │   └── ...
│   ├── plugins						存放 Vue 插件相关的文件
│   │   ├── element-plus.js
│   │   ├── i18n.js
│   │   └── ...
│   ├── App.vue						是 Vue 应用的根组件
│   └── main.js						是 Vue 应用的入口文件,包含 Vue 实例的创建、插件的注册等
├── tests							存放测试相关的代码
│   ├── unit
│   ├── e2e
│   └── ...
├── dist							存放打包后的代码
│   ├── css
│   ├── js
│   ├── index.html
│   └── ...
├── .eslintrc.js
├── babel.config.js
├── package.json					命令配置和包管理文件
├── README.md						项目的说明文件,使用markdown语法进行编写
├── vue.config.js					vue配置文件
├── .env.test						测试环境配置文件
├── .env.development				开发环境配置文件
├── .env.production					生产环境配置文件
└── ...

vue.config.js

这个文件导出了一个包含了选项的对象

基本配置
module.exports = {
    productionSourceMap: false,			生产环境是否要生成 sourceMap
    publicPath: './',					部署应用包时的基本 URL,用法和 webpack 本身的 output.publicPath 一致
可以通过三元运算去配置dev和prod环境, publicPath: process.env.NODE_ENV === 'production' ? '/prod/' : './'
    outputDir: 'dist',					build 时输出的文件目录
    assetsDir: 'assets',				放置静态文件夹目录
    devServer: {						dev环境下,相关配置
        port: 8090,						开发运行时的端口
        host: '0.0.0.0',				开发运行时域名,设置成'0.0.0.0',在同一个局域网下,如果你的项目在运行,同时可以通过你的http://ip:port/...访问你的项目
        https: false,					是否启用 https
        open: true						npm run serve 时是否直接打开浏览器
    },
    // 其他配置
    ...
}
module.exports = {
    baseUrl: '/',// 部署应用时的根路径(默认'/'),也可用相对路径(存在使用限制)
    outputDir: 'dist',// 运行时生成的生产环境构建文件的目录(默认''dist'',构建之前会被清除)
    assetsDir: '',//放置生成的静态资源(s、css、img、fonts)的(相对于 outputDir 的)目录(默认'')
    indexPath: 'index.html',//指定生成的 index.html 的输出路径(相对于 outputDir)也可以是一个绝对路径。
    pages: {//pages 里配置的路径和文件名在你的文档目录必须存在 否则启动服务会报错
        index: {//除了 entry 之外都是可选的
            entry: 'src/index/main.js',// page 的入口,每个“page”应该有一个对应的 JavaScript 入口文件
            template: 'public/index.html',// 模板来源
            filename: 'index.html',// 在 dist/index.html 的输出
            title: 'Index Page',// 当使用 title 选项时,在 template 中使用:<title><%= htmlWebpackPlugin.options.title %></title>
            chunks: ['chunk-vendors', 'chunk-common', 'index'] // 在这个页面中包含的块,默认情况下会包含,提取出来的通用 chunk 和 vendor chunk

        },
        subpage: 'src/subpage/main.js'//官方解释:当使用只有入口的字符串格式时,模板会被推导为'public/subpage.html',若找不到就回退到'public/index.html',输出文件名会被推导为'subpage.html'
    },
    lintOnSave: true,// 是否在保存的时候检查
    productionSourceMap: true,// 生产环境是否生成 sourceMap 文件
    css: {
        extract: true,// 是否使用css分离插件 ExtractTextPlugin
        sourceMap: false,// 开启 CSS source maps
        loaderOptions: {},// css预设器配置项
        modules: false// 启用 CSS modules for all css / pre-processor files.

    },
    devServer: {// 环境配置
        host: 'localhost',
        port: 8080,
        https: false,
        hotOnly: false,
        open: true, //配置自动启动浏览器
        proxy: {// 配置多个代理(配置一个 proxy: 'http://localhost:4000' )
            '/api': {
                target: '<url>',
                ws: true,
                changeOrigin: true

            },
            '/foo': {
                target: '<other_url>'

            }

        }

    },
    chainWebpack: config => {
        // 修复HMR
        config.resolve.symlinks(true);
    },
    css: {
        //extract: true,// 是否使用css分离插件 ExtractTextPlugin
        sourceMap: false,// 开启 CSS source maps
        loaderOptions: {},// css预设器配置项
        modules: false// 启用 CSS modules for all css / pre-processor files.
    },
    pluginOptions: {// 第三方插件配置

    }
}

就没加linter和一些单元测试。

[外链图片转存中…(img-Hwdbwj4R-1704449108438)]

选择vue.js的版本,选择3.x

[外链图片转存中…(img-oQyak6oB-1704449108439)]

是否使用es6类的语法来创建组件,输入n,因为使用这个需要写很多修饰符,一般是vue2中为了兼容Ts才使用

[外链图片转存中…(img-Z36Z7vGK-1704449108440)]

是否使用babel,是(直接回车默认就是yes);是否用history路由模式,是;选择写样式的方法,我选的less;一些配置是放在package.json还是单独的文件里面,选择单独的文件,就是dedicated config files;在之后的项目中是否保留这些设置,我选n,不保留。等待项目创建。

[外链图片转存中…(img-wAxnj4wj-1704449108440)]

还有可能让你选择用npm还是yarn,我选的npm,可根据自己喜好自行选择。

\3. 项目创建成功后,进入该项目(我的项目名是vue3-project)

cd vue3-project/

\4. 启动该项目(我用的npm)

npm run serve

vue3.0目录结构

├── public							存放静态资源,如 HTML 文件、favicon 等
│   ├── index.html					入口的html文件
│   ├── favicon.ico					网站的显示图标
│   └── ...
├── src								是源代码目录,包含了 Vue 组件、路由、状态管理、工具类、插件等
│   ├── assets						存放项目中使用的图片、样式等资源文件
│   │   ├── images
│   │   ├── styles
│   │   └── ...
│   ├── components					存放通用的组件
│   │   ├── common
│   │   ├── layout
│   │   ├── ui
│   │   ├── form
│   │   └── ...
│   ├── views						存放页面级别的组件
│   │   ├── home
│   │   ├── about
│   │   ├── user
│   │   ├── product
│   │   └── ...
│   ├── router						存放 Vue Router 相关的文件
│   │   ├── index.js
│   │   └── ...
│   ├── store						存放 Vuex 相关的文件
│   │   ├── index.js
│   │   ├── modules
│   │   └── ...
│   ├── utils						存放一些工具类、公共函数等
│   │   ├── api.js
│   │   ├── auth.js
│   │   ├── request.js
│   │   └── ...
│   ├── plugins						存放 Vue 插件相关的文件
│   │   ├── element-plus.js
│   │   ├── i18n.js
│   │   └── ...
│   ├── App.vue						是 Vue 应用的根组件
│   └── main.js						是 Vue 应用的入口文件,包含 Vue 实例的创建、插件的注册等
├── tests							存放测试相关的代码
│   ├── unit
│   ├── e2e
│   └── ...
├── dist							存放打包后的代码
│   ├── css
│   ├── js
│   ├── index.html
│   └── ...
├── .eslintrc.js
├── babel.config.js
├── package.json					命令配置和包管理文件
├── README.md						项目的说明文件,使用markdown语法进行编写
├── vue.config.js					vue配置文件
├── .env.test						测试环境配置文件
├── .env.development				开发环境配置文件
├── .env.production					生产环境配置文件
└── ...

vue.config.js

这个文件导出了一个包含了选项的对象

基本配置
module.exports = {
    productionSourceMap: false,			生产环境是否要生成 sourceMap
    publicPath: './',					部署应用包时的基本 URL,用法和 webpack 本身的 output.publicPath 一致
可以通过三元运算去配置dev和prod环境, publicPath: process.env.NODE_ENV === 'production' ? '/prod/' : './'
    outputDir: 'dist',					build 时输出的文件目录
    assetsDir: 'assets',				放置静态文件夹目录
    devServer: {						dev环境下,相关配置
        port: 8090,						开发运行时的端口
        host: '0.0.0.0',				开发运行时域名,设置成'0.0.0.0',在同一个局域网下,如果你的项目在运行,同时可以通过你的http://ip:port/...访问你的项目
        https: false,					是否启用 https
        open: true						npm run serve 时是否直接打开浏览器
    },
    // 其他配置
    ...
}
module.exports = {
    baseUrl: '/',// 部署应用时的根路径(默认'/'),也可用相对路径(存在使用限制)
    outputDir: 'dist',// 运行时生成的生产环境构建文件的目录(默认''dist'',构建之前会被清除)
    assetsDir: '',//放置生成的静态资源(s、css、img、fonts)的(相对于 outputDir 的)目录(默认'')
    indexPath: 'index.html',//指定生成的 index.html 的输出路径(相对于 outputDir)也可以是一个绝对路径。
    pages: {//pages 里配置的路径和文件名在你的文档目录必须存在 否则启动服务会报错
        index: {//除了 entry 之外都是可选的
            entry: 'src/index/main.js',// page 的入口,每个“page”应该有一个对应的 JavaScript 入口文件
            template: 'public/index.html',// 模板来源
            filename: 'index.html',// 在 dist/index.html 的输出
            title: 'Index Page',// 当使用 title 选项时,在 template 中使用:<title><%= htmlWebpackPlugin.options.title %></title>
            chunks: ['chunk-vendors', 'chunk-common', 'index'] // 在这个页面中包含的块,默认情况下会包含,提取出来的通用 chunk 和 vendor chunk

        },
        subpage: 'src/subpage/main.js'//官方解释:当使用只有入口的字符串格式时,模板会被推导为'public/subpage.html',若找不到就回退到'public/index.html',输出文件名会被推导为'subpage.html'
    },
    lintOnSave: true,// 是否在保存的时候检查
    productionSourceMap: true,// 生产环境是否生成 sourceMap 文件
    css: {
        extract: true,// 是否使用css分离插件 ExtractTextPlugin
        sourceMap: false,// 开启 CSS source maps
        loaderOptions: {},// css预设器配置项
        modules: false// 启用 CSS modules for all css / pre-processor files.

    },
    devServer: {// 环境配置
        host: 'localhost',
        port: 8080,
        https: false,
        hotOnly: false,
        open: true, //配置自动启动浏览器
        proxy: {// 配置多个代理(配置一个 proxy: 'http://localhost:4000' )
            '/api': {
                target: '<url>',
                ws: true,
                changeOrigin: true

            },
            '/foo': {
                target: '<other_url>'

            }

        }

    },
    chainWebpack: config => {
        // 修复HMR
        config.resolve.symlinks(true);
    },
    css: {
        //extract: true,// 是否使用css分离插件 ExtractTextPlugin
        sourceMap: false,// 开启 CSS source maps
        loaderOptions: {},// css预设器配置项
        modules: false// 启用 CSS modules for all css / pre-processor files.
    },
    pluginOptions: {// 第三方插件配置

    }
}
  • 17
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值