前端常识
浏览器内核
- IE:Trident --IE、360、百度浏览器
- FireFox:Gecko --火狐浏览器
- Safair:Webkit --苹果浏览器
- Chrome/Opera:Blink --Blink是webkit的分支
web标准的构成
| 构成 | 语言 | 说明 |
|---|---|---|
| 结构 | HTML | 页面元素和内容 |
| 表现 | CSS | 页面样式布局 |
| 行为 | JavaScript | 页面交互 |
前端第一阶段:静态页面
HTML/HTML5
超文本标记语言,就是超出普通文本能力范围的一门标记语言,它可以实现音频、视频、图片等等的功能。
<!DOCTYPE html> // html标准声明
<html lang="en"> // 页面语言声明
<head>
<meta charset="UTF-8"> // charset字符集声明,可以理解为"密码本"
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
元素显示模式
块级元素:div、ul、ol、dl、dt、dd、li、p、h1-h6、5个语义化标签
1.独占一行
2.可以设置宽高
3.宽度默认为父元素宽度,高度由内容撑开。
行内元素:span、a、em、strong、i、b、u、del
1.一行显示多个
2.不可以设置宽高
3.宽高默认由内容撑开
4.不可以设置垂直方向的margin
行内块元素:img(有其特点但是谷歌浏览器内显示inline)、input、textarea、select、button
1.一行显示多个
2.可以设置宽高
3.宽高默认由内容撑开。
伪元素:是css模拟出来的标签效果,::after,::before
必填:content属性
默认是inline元素
标签语义化
语义化标签可以理解为用于进行网页页面构建的标签,他们不会影响页面内容,只是对页面结构的规范化。易修改、维护;更易理解页面结构;有利于SEO搜索引擎检索。
1.头部标签<header>:<header>元素有两种用法,第一是标注内容的标题,第二是标注网页的页眉,如上图你看到的那样。除非必要(内容标题附带其它信息的情况下:发布时间、作者等),一般不在内容中使用<header>。因而,网页中可以包含多个<header>元素。按照 HTML5 的规定,<header>都应包含某个级别的标题,所以应隐式或显式地包含标题,通常将不希望显示的标题设置为display: none;,一方面遵守规范,另一方面则提供了无障碍阅读而不至于影响到页面设计。
2.导航栏标签<nav>:导航栏使用<nav>看起来是理所当然的,进一步,它也用于一组文章的链接。一个页面可以包含多个<nav>元素,但通常仅仅在页面的主要导航部分使用它。
3.附注标签<aside>:<aside>元素并不仅仅是侧栏,它表示与它周围文本没有密切关系的内容。文章中同样可以使用<aside>元素,来说明文章的附加内容、解释说明某个观点、相关内容链接等等。
4.页脚标签<footer>:<footer>标签仅仅可以包含版权、来源信息、法律限制等等之类的文本或链接信息。如果想要在页脚中包含其它内容,可以使用熟悉的<div>来帮忙。
5.主要内容标签<main>:在早先的 HTML5 版本中并没有规定页面主体的标签,相关的书中经常会说:除去头部、尾部、侧栏等其它部分,剩下的自然是主体部分。然而,HTML5.1 中规定了一个<main>标签来标识主体内容。<main>标签不能包含在页面其它区块元素中,通常是<body>的子标签,或者是全局<div>的子标签。<main>标签可以帮助屏幕阅读工具识别页面的主体部分,从而让访问者迅速得到有用的信息。
6.文章标签<article>:<article>表示一个完整的、自成一体的内容块。如文章或新闻报道。<article>应包含完整的标题、文章署名、发布时间、正文。当语义与表现发生冲突,例如有时需要将文章分多个页面显示,那么需要把每个页面的文章区域都用<article>标记。
CSS/CSS3
选择器
!important>行内样式>id选择器>伪类选择器>类选择器>标签选择器>通配符选择器>继承
结构伪类选择器
1.nth-child():先排序再选类型
2.nth-of-type():先选择类型再排序
盒模型
盒子模型:内容区域(content) + 内边距(padding) + 边框(border) + 外边距(margin)
实际盒子大小:内容区域(content) + 内边距(padding) + 边框(border)
宽度:设置的宽度为内容的宽度--->width=content
box-sizing:border-box
css3盒子模型盒子大小=设置的宽度=内容区域(content,自动内减) + 内边距(padding) + 边框(border)
margin合并/塌陷
1.margin合并:上下布局的两个块级盒子,上面盒子设置下外边距,下面的盒子设置上外边距,最终结果两盒子之间只保留两个盒子设置的最大值。
--解决方法:避免设置两个盒子,改为只设置一个盒子的外边距。
2.margin塌陷:父子级嵌套的两个块级盒子,子盒子设置上外边距会影响父盒子使父盒子与子盒子合并margin。
--解决方法:转化为BFC盒子,添加overflow:hidden、display:inline-block、float:left。
浮动
设置浮动的元素会脱离文档流,影响布局。
清楚浮动的方法:
1.父元素加高度
2.额外标签法
3.设置overflow:hidden
4.单伪元素法
.clearfix:after {
content: '.';
height: 0;
display: block;
clear: both;
}
5.双伪元素法(推荐)(还可解决margin塌陷)
.clearFix::after,.clearFix::before {
content:'.';
display:table ;
}
.clearFix::after{
clear:both;
}
BFC
BFC是web页面一个特殊的区域。
创建BFC盒子:
1.设置overflow:hdden
2.display:inline-block
3.设置浮动
特点:
1.BFC盒子会默认包裹住内部子元素(浮动,标准流)->清楚浮动
2.BFC盒子本身与子元素之间不存在margin的塌陷现象->解决margin塌陷
元素层级
定位元素>浮动元素>标准流元素
z-index:只能设置定位元素的层级
vertical-align
vertical-align起作用的前提是元素为inline元素或table-cell元素,包括span, img,input, button, td ,浮动和定位的元素已经块化所以也不会生效。
属性值:
(1)baseline: 默认的对齐方式,基线对齐,与父元素的基线对齐;
(2)top: 与行中的最高元素的顶端对齐,一般是父级元素的最顶端对齐;
(3)middle: 与父元素中线对齐(近似垂直居中);
(4)bottom: 与top相反,与父级元素的最低端对齐 ;
(5)text-top: 与父级元素content area的顶端对齐,不受行高以及周边其他元素的影响;
(6)text-bottom:与text-top相反,始终与父级元素content area的低端对齐。同理可以与bottom进行对比区分;
(7)数值与百分比: 当数值为正值时,对齐方式将以基线为基准,往上偏移响应的大小,当为负值时,往下偏移。而百分比则是根据行高的大小,计算出响应的数值,再以数值表现的方式进行偏移。(百分比根据行高计算偏移值这一点很重要,对后面讲解的一些奇怪的现象可以做出解释并找到解决的办法)。
(8)super与sub:这两个值均是找到合适的基线作为对齐的基线进行对齐,类似super标签和sub标签,但不缩放字体大小。
过渡transition
1.过度的属性:
all-所有能过渡的属性都过渡,具体属性名-transition:width 3s ,background-color 1s
2.过渡时常:1s
3.谁要过渡给谁加
定位
可以让元素自由摆放在页面任意位置
一般用于盒子之间层叠情况
转换(23D,不影响其他盒子)transform
translate(x,y,z) ----以%为单位以盒子自身为基准
rorate(deg)
scale(x,y,z)
3D呈现:transform-style
动画
animation : 动画名称,持续时间,运动曲线,何时开始,播放次数
媒体查询
字体图标
less/scss
文本水平居中
text-align:center(设置在父元素身上)
--行内元素:该属性可以让img、span、input、a标签水平居中
--块级元素:可以让元素内部文本水平居中(设置在元素本身也可生效)
元素水平居中
margin:0 auto(块级元素) --div、p等等
text-align:center(行内元素) --span等等
行高/文本垂直居中
行高(行间距):包含上间距,文本高度,下间距。
文本垂直居中:设置行高等于自身盒子高度
图片与其后文本水平垂直居中
- 图片与文本父盒子设置:text-align:center(文本与图片水平居中),行高等于高(文本垂直居中);图片设置:vertical-align:middle
<style>
div{width:500px;height:300px;line-height:300px;background:#999;text-align:center;}
img{vertical-align:middle;}
</style>
<div>
<a>哪怕我里面有一个字符都行</a>
<img src="/i/eg_tulip.jpg"/>
</div>
- flex
// 图片父盒子设置:
display: flex;
justify-content: center;
align-items: center;
页面布局
静态布局:给页面元素设置固定的宽度和高度,单位用px,当窗口缩小,会出现滚动条,拉动滚动条显示被遮挡内容。针对不一样分辨率的手机端,分别写不一样的样式文件。
自适应布局:建立多个静态布局,每一个静态布局对应一个屏幕分辨率范围,使用 @media媒体查询技术。
流式布局:元素的宽高用百分比作单位,元素宽高按屏幕分辨率调整,布局不发生变化。屏幕尺度跨度过大的状况下,页面不能正常显示。
响应式布局:采用自适应布局和流式布局的综合方式,为不一样屏幕分辨率范围建立流式布局。
弹性布局:要点在于使用em和rem单位来定义元素宽度,与流式布局有极大的类似性,但也有不一样之处,主要区别在于弹性布局的尺寸主要根据字体大小而变化。rem布局虽然与百分比布局很相似,但比百分比布局更好用。
静态布局
即传统Web设计,网页上的所有元素的尺寸一律使用px作为单位。
静态布局(static layout) (固定宽度)
1、布局特点
不管浏览器尺寸具体是多少,网页布局始终按照最初写代码时的布局来显示。常规的pc的网站都是静态(定宽度)布局的,也就是设置了min-width,这样的话,如果小于这个宽度就会出现滚动条,如果大于这个宽度则内容居中外加背景,这种设计常见于pc端。
2、设计方法
PC:居中布局,所有样式使用绝对宽度/高度(px),设计一个Layout,在屏幕宽高有调整时,使用横向和竖向的滚动条来查阅被遮掩部分;
移动设备:另外建立移动网站,单独设计一个布局,使用不同的域名如wap.或m.。
在移动端开发中采用静态布局的两种方式:(来自:流布局与响应式网页设计有什么区别?** )**
(1)在viewport meta标签上设置width=320,页面的各个元素也采用px作为单位。通过用JS动态修改标签的initial-scale使得页面等比缩放,从而刚好占满整个屏幕。
(2)设在viewport meta标签上设置content"width=640,user-scalable=no,页面的各个元素也采用px作为单位。由于640px超出了手机宽度,浏览器会自动缩小页面至刚好全屏。(具体见[content"width=640,user-scalable=no" 然后再进行固定尺寸的px设计? - 前端开发](www.zhihu.com/question/32… "content"width=640,user-scalable=no" 然后再进行固定尺寸的px设计? - 前端开发"))
优点:这种布局方式对设计师和CSS编写者来说都是最简单的,亦没有兼容性问题。
缺点:显而易见,即不能根据用户的屏幕尺寸做出不同的表现。当前,大部分门户网站、大部分企业的PC宣传站点都采用了这种布局方式。固定像素尺寸的网页是匹配固定像素尺寸显示器的最简单办法。但这种方法不是一种完全兼容未来网页的制作方法,我们需要一些适应未知设备的方法。
流式布局
流式布局(Liquid Layout) (百分比为单位)
流式布局(Liquid)的特点(也叫"Fluid") 是页面元素的宽度按照屏幕分辨率进行适配调整,但整体布局不变。代表作栅栏系统(网格系统)。
网页中主要的划分区域的尺寸使用百分数(搭配min-*、max-*属性使用),例如,设置网页主体的宽度为80%,min-width为960px。图片也作类似处理(width:100%, max-width一般设定为图片本身的尺寸,防止被拉伸而失真)。
关于CSS流式布局
💠 说明
1、流式布局使用非固定像素来定义网页内容,即百分比布局。
2、通过将盒子的宽度设置为百分比根据屏幕的宽度进行伸缩,不受固定像素的限制,内容向两侧填充。
💠 分类
👉 左侧固定,右侧自适应
👉 右侧固定,左侧自适应
👉 两侧固定,中间自适应(圣杯布局)
👉 等分布
💠 实例
.masonry { /* 火狐 */ -moz-column-count:3; /* Safari 和 谷歌 */ -webkit-column-count:3; column-count:3; -moz-column-gap: 1em; -webkit-column-gap: 1em; column-gap: 1em; width: 80%; margin:1em auto; } .item { padding: 1em; margin-bottom: 1em; -moz-page-break-inside: avoid; -webkit-column-break-inside: avoid; break-inside: avoid; background: #b5ffa1; } //适应屏幕 @media screen and (max-width: 800px) { .masonry { column-count: 2; // two columns on larger phones } } @media screen and (max-width: 500px) { .masonry { column-count: 1; // two columns on larger phones } }
- 布局特点
屏幕分辨率变化时,页面里元素的大小会变化而但布局不变。这就导致如果屏幕太大或者太小都会导致元素无法正常显示。
- 设计方法
使用%百分比定义宽度,高度大都是用px来固定住,可以根据可视区域 (viewport) 和父元素的实时尺寸进行调整,尽可能的适应各种分辨率。往往配合 max-width/min-width 等属性控制尺寸流动范围以免过大或者过小影响阅读。
这种布局方式在Web前端开发的早期历史上,用来应对不同尺寸的PC屏幕(那时屏幕尺寸的差异不会太大),在当今的移动端开发也是常用布局方式,但缺点明显:主要的问题是如果屏幕尺度跨度太大,那么在相对其原始设计而言过小或过大的屏幕上不能正常显示。因为宽度使用%百分比定义,但是高度和文字大小等大都是用px来固定,所以在大屏幕的手机下显示效果会变成有些页面元素宽度被拉的很长,但是高度、文字大小还是和原来一样(即,这些东西无法变得“流式”),显示非常不协调
自适应布局
自适应布局(Adaptive Layout) (利用@media媒体查询设置断点,设置多个宽高)
自适应布局的特点是分别为不同的屏幕分辨率定义布局,即创建多个静态布局,每个静态布局对应一个屏幕分辨率范围。改变屏幕分辨率可以切换不同的静态局部(页面元素位置发生改变),但在每个静态布局中,页面元素不随窗口大小的调整发生变化。可以把自适应布局看作是静态布局的一个系列。
1、布局特点 屏幕分辨率变化时,页面里面元素的位置会变化而大小不会变化。
2、设计方法 使用 @media 媒体查询给不同尺寸和介质的设备切换不同的样式。在优秀的响应范围设计下可以给适配范围内的设备最好的体验,在同一个设备下实际还是固定的布局。
响应式布局
随着CSS3出现了媒体查询技术,又出现了响应式设计的概念。响应式设计的目标是确保一个页面在所有终端上(各种尺寸的PC、手机、手表、冰箱的Web浏览器等等)都能显示出令人满意的效果,对CSS编写者而言,在实现上不拘泥于具体手法,但通常是糅合了流式布局+弹性布局,再搭配媒体查询技术使用。——分别为不同的屏幕分辨率定义布局,同时,在每个布局中,应用流式布局的理念,即页面元素宽度随着窗口调整而自动适配。即:创建多个流体式布局,分别对应一个屏幕分辨率范围。可以把响应式布局看作是流式布局和自适应布局设计理念的融合。 响应式几乎已经成为优秀页面布局的标准。
- 布局特点
每个屏幕分辨率下面会有一个布局样式,即元素位置和大小都会变。
- 设计方法
媒体查询+流式布局。通常使用 @media 媒体查询 和网格系统 (Grid System) 配合相对布局单位进行布局,实际上就是综合响应式、流动等上述技术通过 CSS 给单一网页不同设备返回不同样式的技术统称。
优点:适应pc和移动端,如果足够耐心,效果完美。
缺点:(1)媒体查询是有限的,也就是可以枚举出来的,只能适应主流的宽高。(2)要匹配足够多的屏幕大小,工作量不小,设计也需要多个版本。
<<!-- 响应式页面在头部会加上这一段代码: -->
<meta name="applicable-device" content="pc,mobile">
<meta http-equiv="Cache-Control" content="no-transform ">
总结:响应式与自适应的原理是类似的,都是检测设备,根据不一样的设备采用不一样的css,并且css都是采用的百分比的,而不是固定的宽度,不一样点是响应式的模板在不一样的设备上看上去是不同的,会随着设备的改变而改变展现样式,而自适应不会,全部的设备看起来都是一套的模板,不过是长度或者图片变小了,不会根据设备采用不一样的展现样式,流式就是采用了一些设置,当宽度大于多少时怎么展现,小于多少时怎么展现,并且展现的方式向水流同样,一部分一部分的加载,静态的就是采用固定宽度的了。
流式布局是用于解决相似的设备不一样分辨率之间的兼容(通常分辨率差别较少);响应式是用于解决不用设备之间不用分辨率之间的兼容问题(通常是指PC,平板,手机等设备之间较大的分辨率差别)。
弹性布局(rem/em布局)
可供参考:流布局与响应式网页设计有什么区别?
1. rem和em的区别
rem,em都是顺应不同网页字体大小展现而产生的。其中,em是相对其父元素,在实际应用中相对而言会带来很多不便;而rem是始终相对于html大小,即页面根元素。
🖖 在css中单位长度用的最多的是px、em、rem,它们的区别在哪里?
💠 px 与 em/rem的区别
px是固定的像素,一旦设置了就无法因为适应页面大小而改变。
em和rem相对于px更具有灵活性,他们是相对长度单位,意思是长度不是定死了的,更适用于响应式布局。
💠 em 与 rem的区别
对于em和rem的区别一句话概括:**em相对于父元素,rem相对于根元素。
em 👇**
- 子元素字体大小的em是相对于父元素字体大小
- 元素的width/height/padding/margin用em的话是相对于该元素的font-size
<div> 我是父元素div <p> 我是子元素p <span>我是孙元素span</span> </p> </div>div { font-size: 40px; width: 10em; /* 400px */ height: 10em; border: solid 1px black; } p { font-size: 0.5em; /* 20px */ width: 10em; /* 200px */ height: 10em; border: solid 1px red; } span { font-size: 0.5em; width: 10em; height: 10em; border: solid 1px blue; display: block; }效果如下:
rem 👇
rem是全部的长度都相对于根元素,根元素是谁?元素。通常做法是给html元素设置一个字体大小,然后其他元素的长度单位就为rem。
html { font-size: 10px; } div { font-size: 4rem; /* 40px */ width: 30rem; /* 300px */ height: 30rem; border: solid 1px black; } p { font-size: 2rem; /* 20px */ width: 15rem; height: 15rem; border: solid 1px red; } span { font-size: 1.5rem; width: 10rem; height: 10rem; border: solid 1px blue; display: block; }效果如下:
当用rem做响应式时,直接在媒体中改变html的font-size,那么用rem作为单位的元素的大小都会相应改变,很方便。
这就是rem的优势:父元素文字大小可能不一致, 但是整个页面只有一个html,可以很好来控制整个页面的元素大小。
看到这里我想我们都更深刻的体会了em和rem的区别(参照物不同)。
小结:
在做项目的时候用什么单位长度取决于你的需求,比如,我们通常可以这样:
👉🏻 像素(px):用于元素的边框或定位。
👉🏻 em/rem:用于做响应式页面,不过我更倾向于rem,因为em不同元素的参照物不一样(都是该元素父元素),所以,在计算的时候不方便,相比之下rem就只有一个参照物(html元素),这样计算起来更清晰。
- 使用 em 或 rem 单位进行相对布局,相对 % 百分比更加灵活,同时可以支持浏览器的字体大小调整和缩放等的正常显示,因为em是相对父级元素的原因没有得到推广。
中国站点制作网页的时候,习惯用CSS强制定义字体大小,保证每个人都看到一致的效果,包括网易、搜狐这些门户网站在内的大部分站点,用的都是绝对单位px(像素)。
但是,如果从网站易用性方面考虑,字体大小应该是可变的,一些视力不是那么好的人需要放大字体才能看得清页面内容。
然而,占据大部分浏览器市场的IE无法调整那些使用px作为单位的字体大小。国外人士非常重视网站的易用性,相当一部分外国站点已经使用em作为字体单位。
3、这类布局的特点是,包裹文字的各元素的尺寸采用em/rem做单位,而页面的主要划分区域的尺寸仍使用百分数或px做单位(同「流式布局」或「静态/固定布局」) 。早期浏览器不支持整个页面按比例缩放,仅支持网页内文字尺寸的放大,这种情况下。使用em/rem做单位,可以使包裹文字的元素随着文字的缩放而缩放。
4、浏览器的默认字体高度一般为16px,即1em:16px,但是 1:16 的比例不方便计算,为了使单位em/rem更直观,CSS编写者常常将页面根节点字体设为62.5%,比如,选择用rem控制字体时,先需要设置根节点html的字体大小,因为浏览器默认字体大小16px*62.5%=10px。这样1rem便是10px,方便了计算。
那么为什么一般多是 html{font-size:62.5%;} 而不是 html{font-size:10px;}呢?
因为有些浏览器默认的不是16px,或者用户修改了浏览器默认的字体大小(因浏览器分辨率大小,视力,习惯等因素)。如果我们将其设置为10px,一定会影响在这些浏览器上的效果,所以最好用绝大多数用户默认的16作为基数 * 62.5% 得到我们需要的10px。
<style>
html {
/* 10 ÷ 16 × 100% = 62.5% */
font-size: 62.5%;
}
body {
/*1.4 × 10px = 14px */
font-size: 1.4rem;
}
h1 {
/*2.4 × 10px = 24px*/
font-size: 2.4rem;
}
</style>
实际项目设置成 font-size: 62.5%可能会出现问题,因为chrome不支持小于12px的字体,计算小于12px的时候,会默认取12px去计算,导致chrome的em/rem计算不准确。
针对这个现象,可以尝试设置html字体为100px,body 修正为16px,这样 0.1rem 就是 10px,而body的字体仍然是默认大小,不影响未设置大小的元素的默认字体的大小。
5、用em/rem定义尺寸的另一个好处是更能适应缩进/以字体单位padding或margin/浏览器设置字体尺寸等情况(因为em/rem相对于字体大小,会同步改变)。例如:p{ text-indent: 2em; }
6、使用rem单位的弹性布局在移动端也很受欢迎。
rem **的定义:font size of the root element, **rem是相对于根元素来设置字体大小的,这就意味着,我们只需要根据自己的需求在根元素确定一个参考值。
rem 与em 、px 的区别:
px:像素,比较精确的单位,但不好做响应式布局
em:以父节点font-size大小为参考点,标准不统一,容易造成混乱
REM 支持的浏览器: Mozilla Firefox 3.6+、Apple Safari 5+、Google Chrome、IE9+和Opera11+。IE6-8无法支持。
对于不同尺寸的屏幕,可以统一假设屏幕宽度为640px后编写CSS(当然你也可以假定统一为320px)。此时,我们设定html元素的font-size为40px(同样,只是举例),然后各处(元素尺寸、文字大小)使用rem作为单位,随后搭配媒体查询或JS,根据屏幕的大小来动态控制html元素的font-size(特定屏幕尺寸下,html元素的font-size应当设置为何值,是使用这个方案时设计师和程序员需要反复考虑后确定的,以下试举一段相关的CSS媒体查询代码),即可自动改变所有用rem定义尺寸的元素的大小(且CSS编写者在脑中进行换算的计算过程比em简单得多)。
html {
font-size : 20px;
}
@media only screen and (min-width: 401px){
html {
font-size: 25px !important;
}
}
@media only screen and (min-width: 428px){
html {
font-size: 26.75px !important;
}
}
@media only screen and (min-width: 481px){
html {
font-size: 30px !important;
}
}
@media only screen and (min-width: 569px){
html {
font-size: 35px !important;
}
}
@media only screen and (min-width: 641px){
html {
font-size: 40px !important;
}
}
- 其实在移动端使用所谓的弹性布局,是比较勉强的。移动端弹性布局流行起来的原因归根结底是rem单位对于(根据屏幕尺寸)调整页面的各元素的尺寸、文字大小时比较好用。其实,使用vw、vh等后起之秀的单位,可以实现完美的流式布局(高度和文字大小都可以变得“流式”),弹性布局就不再必要了。详细可参考:视区相关单位vw, vh..简介以及可实际应用场景
rem布局和响应式布局 - 移动web开发之rem布局与移动web开发之响应式布局
优点:理想状态是所有屏幕的高宽比和最初的设计高宽比一样,或者相差不多,完美适应。
缺点:这种rem+js只不过是宽度自适应,高度没有做到自适应,一些对高度,或者元素间距要求比较高的设计,则这种布局没有太大的意义。如果只是宽度自适应,更推荐响应式设计。
响应式和弹性布局之间的对比:
响应式布局:改变浏览器宽度,“布局”会随之变化,不是一成不变的,例如导航栏在大屏幕下是横排,在小屏幕下是竖排,在超小屏幕下隐藏为菜单,也就是说如果有足够的耐心,在每一种屏幕下都应该有合理的布局,完美的效果。
rem布局:改变浏览器宽度,页面所有元素的高宽都等比例缩放,也就是大屏幕下导航是横的,小屏幕下还是横的只不过变小了。
结论
✔️ 如果只做pc端,那么静态布局(定宽度)是最好的选择;
✔️ 如果做移动端,且设计对高度和元素间距要求不高,那么弹性布局(rem+js)是最好的选择,一份css+一份js调节font-size搞定;
✔️ 如果pc,移动要兼容,而且要求很高那么响应式布局还是最好的选择,前提是设计根据不同的高宽做不同的设计,响应式根据媒体查询做不同的布局。
前端第二阶段:js脚本语言,页面交互
JS包含两部分:ECMAscript语法和操作DOM和BOM的api
ECMAScript
变量
var:变量,有预解析,声明时可以不赋值,没有局部作用域,可以定义多次。
let:变量, 声明时可以不赋值,有局部作用域,只能定义一次。
const:常量, 声明时必须 赋值,一旦定义不能被改变。
共同点:都没有预解析 都不能重复的变量名 都有块级作用域
数据类型
基本数据类型:数值number,字符串string,布尔Boolean,空null, 未定义undefind
引用数据类型:函数,对象
字符串方法
---indexOf() 方法返回字符串中指定文本首次出现的索引(位置)
例如:var pos = str.indexOf("China")->17
---lastIndexOf() 方法返回指定文本在字符串中最后一次出现的索引:
例如:var pos = str.indexOf("China")->51
indexOf,lastIndexOf-未找到均返回-1
---slice() 提取字符串的某个部分并在新字符串中返回被提取的部分。
该方法设置两个参数:起始索引(开始位置),终止索引(结束位置索引+1)。
一个参数从起始位置到最后。
例如:
var str = "Apple, Banana, Mango";<br>
var res = str.slice(7,13);->Banana
var str = "Apple, Banana, Mango";
var res = str.slice(-13,-7);->Banana
---substring()substring() 类似于 slice()。不同之处在于 substring() 无法接受负的索引。
---substr() 类似于 slice()。不同之处在于第二个参数规定被提取部分的长度。
---replace() 方法用另一个值替换在字符串中指定的值。对大小写敏感。不会改变调用它的字符串。它返回的是新字符串。默认地,replace() 只替换首个匹配:
例如:var txt=str.replace("Microsoft","W3School");
---toUpperCase() toLowerCase() 把字符串转换为大小写。
例如:
var text1 = "Hello World!";
var text2 = text1.toUpperCase();->HELLO WORLD!
---concat 拼接字符串
例如:text3 = text1.concat(text2)
---charAt() 方法返回字符串中指定位置的字符串
例如:
var text1 = "Hello World!";
var text2 = text1.toUpperCase();->HELLO WORLD!
---split() 将字符串转换为数组。
如果省略分隔符,被返回的数组将包含 index[0] 中的整个字符串。
如果分隔符是 "",被返回的数组将是间隔单个字符的数组:
例如:
var txt = "a,b,c,d,e"; // 字符串
txt.split(",");->[a,b,c,d,e]
---trim() 方法删除字符串两端的空白符
例如:
var str = " Hello World! "
alert(str.trim());
数字方法
---toString() 将数字转为字符串
例如:num.toString()
---String() 将数字转为字符串
例如:String(num)
---parseInt() 将字符串转为数字型(取整)
例如:parseInt('55.5')->55
---parseFloat()将字符串转为数字型(浮点数)
例如:parseInt(num)->55.5
---Number()将字符串转为数字型
例如:Number(num)->55.5
---toFixed() 返回字符串值,它包含了指定位数小数的数字
---toPrecision() 返回字符串值,它包含了指定长度的数字
数组-方法( 增加删除裁剪合并)
数组是一个特殊的变量,它能够一次存放多个值,并且可以通过索引拿到这些值
判断数组类型:Array.isArray(数组名)
---shift() 方法会删除首个数组元素,shift() 方法返回被移出的元素,并把所有其他元素“位移”到更低的索引:数组名.shift()
---unshift() 方法(在开头)向数组添加新元素,并“反向位移”旧元素
---pop() 方法从数组中删除最后一个元素,pop() 方法的返回值是已删除的项目:数组名.pop()
---push() 在最后添加一个数组元素:数组名.push("hgv")
---.toString()数组转为字符串:数组名.toString() (默认逗号分隔)
---join(" ") 方法也可将所有数组元素结合为一个字符串 小括号内可以指定分隔符
---splice() 三个及以上参数:拼接数组,第一个参数(2)定义了应添加新元素的位置(拼接)。 (位置)
第二个参数(0)定义应删除多少元素。 (从该位置开始删除元素个数)
其余参数(“Lemon”,“Kiwi”)定义要添加的新元素。
splice(2, 0, "Lemon", "Kiwi")
两个参数:裁剪/删除 :数组名.splice(0,1) , 数组名.splice(1,.3) 裁剪从0到1-1=0 ,裁剪从1到3-2。
返回包含已删除元素(如果有)的数组
一个参数:裁剪/删除:数组名.splice(3) ,从3到最后
返回包含已删除元素(如果有)的数组
---slice()裁剪数组, 可接受两个参数,比如 (1, 3)。该方法会从开始参数选取元素,直到结束参数(不包括)为止
---concat() 方法通过合并(连接)现有数组来创建一个新数组 var myChildren = myGirls.concat(myBoys); var myChildren = arr1.concat(arr2, arr3);
数组-排序
---sort() 方法以字母顺序对数组进行排序 ,以字符串方式排列 25>100。points.sort(function(a, b){return a - b})(升序) points.sort(function(a, b){return b - a}) (降序)
---reverse() 方法反转数组中的元素
---随机数:points.sort(function(a, b){return 0.5 - Math.random()})
---Math.max.apply (null,arr1)来查找数组中的最高值
---Math.min.apply (null,arr2)来查找数组中的最低值
数组-迭代
---forEach() 方法为每个数组元素调用一次函数(回调函数)
---map() 方法通过对每个数组元素执行函数来创建新数组
---filter() 方法创建一个包含通过测试的数组元素的新数组,过滤器
---every() 方法检查所有数组值是否通过测试
---some() 方法检查某些数组值是否通过了测试。
---indexOf() 方法在数组中搜索元素值并返回其位置 ,array.indexOf(item, start开始位置)
----find() 方法返回通过测试函数的第一个数组元素的值
---findIndex() 方法返回通过测试函数的第一个数组元素的索引
日期
---new Date() 用当前日期和时间创建新的日期对象
---toUTCString() 方法将日期转换为 UTC 字符串(一种日期显示标准) Wed, 14 Apr 2021 01:50:43 GMT
---toDateString() 方法将日期转换为更易读的格式(字符串) Wed Apr 14 2021
获取日期方法:
getDate() 以数值返回天(1-31)
getDay() 以数值获取周名(0-6)
getFullYear() 获取四位的年(yyyy)
getHours() 获取小时(0-23)
getMilliseconds()获取毫秒(0-999)
getMinutes() 获取分(0-59)
getMonth() 获取月(0-11)
getSeconds() 获取秒(0-59)
getTime() 获取时间(从 1970 年 1 月 1 日至今)
var time = new Date()
var year = time.getFullYear()
var month = time.getMonth + 1
var dates = time.getDate()
var arr =['星期日','星期一','星期二','星期三','星期四','星期五','星期六']
var day = time.getDay()
console.log(`今天是:` ${year} 年 ${month} 月 ${dates} 日 ${arr[day]})
var h = time.getHours()
h = h < 10 ? '0' + h : h
var m = time.getMinutes()
m = m < 10 ? '0' + m : m
var s = time.getSeconds()
s = s < 10 ? '0' + s : s
var newtime = h + ':' + m + ':' + s
console.log(newtime)
数学
Math.round(x) 的返回值是 x 四舍五入为最接近的整数
Math.random() 返回介于 0(包括) 与 1(不包括) 之间的随机数
Math.random() 与 Math.floor() 一起使用用于返回随机整数
Math.floor(Math.random() * 10) 0-9之间
function getRndInteger(min1, max10) {
return Math.floor(Math.random() * (max - min) ) + min;
}
语句 基于不同判断执行不同的动作
---if (条件 1) { 条件 1 为 true 时执行的代码块 }
else if (条件 2) { 条件 1 为 false 而条件 2 为 true 时执行的代码块 }
else { 条件 1 和条件 2 同时为 false 时执行的代码块 }
---switch(表达式) {
case n: 代码块 break;
case n1: 代码块 break;
default: 默认代码块
}
循环
break 语句“跳出”循环。continue 语句“跳过”循环中的一个迭代。)
for - 多次遍历代码块
for/in - 遍历对象属性
while - 当指定条件为 true 时循环一段代码块
do/while - 当指定条件为 true 时循环一段代码块 ,先执行一次循环体,之后条件为真继续执行
对象
在JavaScript中.对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。
var obj={
uname :xxx',
age:18 ,
sex:'男',
sayHi: function() {
console .log('hi~');
}
}
var obj=newObject();//创建了一个空的对象
obj.uname = 'xxx;
obj.age = 18;
obj.sex = 男';
obj.sayHi = function() {
console .1og( 'hi~" );
}
函数
函数就是封装了一段可以被重复执行调用的代码块目的:就是让大量代码重复使用
函数的封装是把一个或者多个功能通过函数的方式封装起来,对外只提供-个简单的函数接口
当我们不确定有多少个参数传递的时候,可以用arguments来获取。在JavaScript中, arguments实际上它是当前函数的一一个内置对象。所有函数都内置了-个arguments对象, arguments对象中存储了传递的所有实参。
//函数的2中声明方式
// 1.利用函数关键字自定义函数(命名函数)
function fn() {
}
fn();
// 2.函数表达式
var fun = function() {
console .1og('我是函数表达式);
}
fun();
构造函数
因为我们一次创建一个对象,里面很多的属性和方法是大量相同的我们只能复制
因此我们可以利用函数的方法重复这些相同的代码我们就把这个函数成为构造函数,有因为这个函数不一样,里面封装的不是普通代码,而是对象,构造函数就是把我们对象里面些相同的属性和方法抽象出来封装到函数里面
// new
构造函数名();
function Star(uname, age, sex) {
this.name = uname ;
this.age = age;
this.sex = sex;
}
var ldh = new Star ('xxx',18, '男'); //调用函数返回的是一个对象
// console. log(typeof ldh) ;
console . log(ldh. name);
console .1og(1dh[ ' sex' ]) ;
// new关键 字执行过程
// 1.new构造函数可以在内存中创建了一个空的对象
// 2. this 就会指向刚才创建的空对象
// 3.执行构造函数里面的代码给这个空对象添加属性和方法
// 4.返回这个对象
js同步与异步
计算机领域中的同步(Synchronous)和异步(Asynchronous)和我们生活中的同步和异步的概念是恰好相反的,计算机中的同步强调排队等待一步一步执行每个任务之间有依赖关系,上一个任务执行完后再执行下一个,异步强调的是同时执行任务。
- js需要异步,这样会提高用户体验,js单线程实现异步:通过事件循环(event loop) 实现'异步'
js的执行机制
- 首先判断js代码是同步还是异步,同步就进入主进程,异步就进入event table
- 异步任务在event table中注册函数,当满足触发条件后,被推入event queue
- 同步任务进入主线程后一直执行,直到主线程空闲时,才会去event queue中查看是否有可执行的异步任务,如果有就推入主进程中 以上三步循环执行,这就是event loop
js单线程
之所以采用单线程,而不是多线程,跟历史有关系。js 从诞生起就是单线程,原因是js设计初衷是让用户与浏览器交互,不想让浏览器变得太复杂,因为多线程需要共享资源、且有可能修改彼此的运行结果,对于一种网页脚本语言来说,这就太复杂了。
浏览器存储
// 存值函数
// 接收三个参数:键、值、有效天数
Storage.prototype.setCanExpireLocal = (key, value, expire) => {
// 判断传入的有效期是否为数值或有效
// isNaN是js的内置函数,用于判断一个值是否为NaN(非数值),
// 非数值返回true,数值返回false
// 还可以限制一下有效期为整数,这里就不做了
if (isNaN(expire) || expire < 1) {
throw new Error('有效期应为一个有效数值')
}
// 86_400_000一天时间的毫秒数,_是数值分隔符
let time = expire * 86_400_000
let obj = {
data: value, //存储值
time: Date.now(), //存值时间戳
expire: time, //过期时间
}
// 注意,localStorage不能直接存储对象类型,sessionStorage也一样
// 需要先用JSON.stringify()将其转换成字符串,取值时再通过JSON.parse()转换回来
localStorage.setItem(key, JSON.stringify(obj))
}
// 取值函数
// 接收一个参数,存值的键
Storage.prototype.getCanExpireLocal = key => {
let val = localStorage.getItem(key)
// 如果没有值就直接返回null
if (!val) return val
// 存的时候转换成了字符串,现在转回来
val = JSON.parse(val)
// 存值时间戳 + 有效时间 = 过期时间戳
// 如果当前时间戳大于过期时间戳说明过期了,删除值并返回提示
if (Date.now() > val.time + val.expire) {
localStorage.removeItem(key)
return '值已失效'
}
return val.data
}
// 存值
Storage.prototype.setCanExpireLocal('测试', '一天后过期', 1)
// 取值
Storage.prototype.getCanExpireLocal('测试')
console.log(Storage.prototype.getCanExpireLocal('测试'));
DOM
HTML DOM 是关于如何获取、更改、添加或删除 HTML 元素的标准
BOM
浏览器对象模型(Browser Object Model (BOM))允许 JavaScript 与浏览器对话