一、BFC、IFC、GFC、FFC
1、BFC(块级格式化上下文)
- 概念:就是页面上的一个隔离的渲染区域,容器里面的子元素不会在布局上影响到外面的元素。
- 触发方式:body根元素;float除none以外的值;position(absolute,fixed);display为inline-block,table-cell,flex;overflow除visible以外的值。
- 作用和特性:清除元素浮动;同一个BFC下外边距会发生折叠,解决方案:把里面的元素放在不同的BFC之中
2、IFC(内联格式上下文)
- 概念:高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)
- 作用和特性:水平居中:当一个块要在环境中水平居中时,设置其为inline-block则会在外层产生IFC,通过text-align则可以使其水平居中。垂直居中:创建一个IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align:middle,其他行内元素则可以在此父元素下垂直居中。
3、GFC(网格布局格式化上下文)
- 概念:当为一个元素设置display值为grid的时候,此元素将会获得一个独立的渲染区域,我们可以通过在网格容器(grid container)上定义网格定义行(grid definition rows)和网格定义列(grid definition columns)属性各在网格项目(grid item)上定义网格行(grid row)和网格列(grid columns)为每一个网格项目(grid item)定义位置和空间。
- 作用和特性:更加丰富的属性来控制行列,控制对齐以及更为精细的渲染语义和控制
4、FFC(自适应格式上下文)
- 概念:display值为flex或者inline-flex的元素将会生成自适应容器
- 作用或者特性:伸缩容器外和伸缩项目内的一切元素都不受影响。简单地说,Flexbox 定义了伸缩容器内伸缩项目该如何布局
二、DIV水平垂直居中方法
1、绝对定位加相对定位1
父元素设置position: relative;
子元素设置
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
background-color: skyblue;
transform: translate(-50%,-50%);
2、绝对定位加相对定位2
父元素设置position: relative;
子元素设置
position: absolute;
top: 50%;
left: 50%;
width: 100px;
height: 100px;
background-color: skyblue;
margin-top: -50px;/*元素本身高度的负一半*/
margin-left: -50px;/*元素本身宽度的负一半*/
3、绝对定位加相对定位3
父元素设置position: relative;
子元素设置
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
width: 100px;
height: 100px;
background-color: skyblue;
margin: auto;
4、弹性盒子
display: flex;
justify-content: center;
align-items: center;
5、table-cell实现水平垂直居中
父元素设置
display: table-cell;
vertical-align: middle;
text-align: center;
子元素设置display: inline-block;
6、calc()
函数动态计算实现水平垂直居中
display: none;visibility:hidden;opacity: 0;
三者的区别
三、1、渲染元素不同
display: none;
不会渲染元素,后两者会。
2、事件监听
display: none;visibility:hidden;
不会触发事件监听,opacity: 0;
会
3、性能
display: none;
性能差,当动态改变元素时会重新渲染,后两者不会,性能高。
4、继承
display: none;
不会被继承,后两者会,并且设置visibility:hidden
的元素,其子元素可以通过visibility:visible;
解除继承。
5、transition区别
display: none;
不能设置transition,后两者能设置。并且visibility是会立即显示,隐藏时会延时。而opacity可以延时显示隐藏。
四、不改变代码的情况下怎么修改样式
源代码:
<div style="width:600px !important;height: 600px;background-color: red;"></div>
css修改:样式覆盖
1、<div style="width:600px !important;height: 600px;background-color: red; max-width:300px;"></div>
2、<div style="width:600px !important;height: 600px;background-color: red;transform:scale(0.6,1)"></div>
3<div style="width:600px !important;height: 600px;background-color: red;width: 300px !important;"></div>
js修改
document.querySelector('div').setAttribute("style", "width:300px !important;height:200px;background-color:skyblue")
五、移动端1PX问题
在移动端web开发中,UI设计稿中设置边框为1像素,前端在开发过程中如果出现border:1px
,测试会发现在某些机型上,1px会比较粗,即是较经典的 移动端1px像素问题。
理解:
物理像素和逻辑像素,物理像素即指实际的像素大小,逻辑像素即指css中显示的像素大小,比例多少与设备相关。可以用 javascript 中的 window.devicePixelRatio
来获取,也可以用媒体查询的 -webkit-min-device-pixel-ratio
来获取。
解决方案:
1、媒体查询
利用设备像素比缩放,设置小数像素;优点:简单,好理解。
缺点:兼容性差,目前之余IOS8+才支持,在IOS7及其以下、安卓系统都是显示0px。
css
.border {
border: 1px solid #999 }
@media screen and (-webkit-min-device-pixel-ratio: 2) {
.border {
border: 0.5px solid #999 }
}
@media screen and (-webkit-min-device-pixel-ratio: 3) {
.border {
border: 0.333333px solid #999 }
}
js
<body><div id="main" style="border: 1px solid #000000;"></div></body>
<script type="text/javascript"> if (window.devicePixelRatio && devicePixelRatio >= 2) {
var main = document.getElementById('main'); main.style.border = '.5px solid #000000'; } </script>
2、设置 border-image 方案
缺点:需要制作图片,圆角可能出现模糊
border-image-1px {
border-width: 1px 0px;
-webkit-border-image: url("border.png") 2 0 stretch;
border-image: url("border.png") 2 0 stretch;
}
border-width
:指定边框的宽度,可以设定四个值,分别为上右下左border-width: top right bottom left。
border-image
:该例意为:距离图片上方2px(属性值上没有单位)裁剪边框图片作为上边框,下方2px裁剪作为下边框。距离左右0像素裁剪图片即没有边框,以拉伸方式展示。
3、background-image 渐变
.border {
background-image:linear-gradient(180deg, red, red 50%, transparent 50%),
linear-gradient(270deg, red, red 50%, transparent 50%),
linear-gradient(0deg, red, red 50%, transparent 50%),
linear-gradient(90deg, red, red 50%, transparent 50%);
background-size: 100% 1px,1px 100% ,100% 1px, 1px 100%;
background-repeat: no-repeat;
background-position: top, right top, bottom, left top;
padding: 10px;
}
将原本1个物理像素的边框大小利用线性渐变分割成几个部分(百分比控制),实现小于1像素效果。
4.阴影
利用阴影也可以实现,优点是没有圆角问题,缺点是颜色不好控制
div {
-webkit-box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.5);
}
5、viewport + rem
整体思路就是利用viewport + rem + js 动态的修改页面的缩放比例,实现小于1像素的显示。
缺点:以为缩放涉及全局的rem单位,比较适合新项目,对于老项目可能要涉及到比较多的改动。
在页面初始化时,在头部引入原始默认状态如下:
<meta name="viewport" id="WebViewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
接下来的任务就是js的动态修改缩放比 以及 实现rem根元素字体大小的设置。
var viewport = document.querySelector("meta[name=viewport]")
if (window.devicePixelRatio == 1) {
viewport.setAttribute('content', 'width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no')
}
if (window.devicePixelRatio == 2) {
viewport.setAttribute('content', 'width=device-width, initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no')
}
if (window.devicePixelRatio == 3) {
viewport.setAttribute('content', 'width=device-width, initial-scale=0.333333333, maximum-scale=0.333333333, minimum-scale=0.333333333, user-scalable=no')
}
var docEl = document.documentElement;
var fontsize = 10 * (docEl.clientWidth / 320) + 'px';
docEl.style.fontSize = fontsize;
6、transform: scale(0.5) 方案
设置height: 1px,根据媒体查询结合transform缩放为相应尺寸。
div {
height:1px;
background:#000;
-webkit-transform: scaleY(0.5);
-webkit-transform-origin:0 0;
overflow: hidden;
}
用::after和::befor,设置border-bottom:1px solid #000,然后在缩放-webkit-transform: scaleY(0.5);可以实现两根边线的需求
div::after{
content:'';width:100%;
border-bottom:1px solid #000;
transform: scaleY(0.5);
}
用::after设置border:1px solid #000; width:200%; height:200%,然后再缩放scaleY(0.5); 优点可以实现圆角,京东就是这么实现的,缺点是按钮添加active比较麻烦。
.div::after {
content: '';
width: 200%;
height: 200%;
position: absolute;
top: 0;
left: 0;
border: 1px solid #bfbfbf;
border-radius: 4px;
-webkit-transform: scale(0.5,0.5);
transform: scale(0.5,0.5);
-webkit-transform-origin: top left;
}
7、媒体查询 + transfrom 对方案1的优化
/* 2倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 2.0) {
.border-bottom::after {
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
}
/* 3倍屏 */
@media only screen and (-webkit-min-device-pixel-ratio: 3.0) {
.border-bottom::after {
-webkit-transform: scaleY(0.33);
transform: scaleY(0.33);
}
}
六、parseInt和map遍历组合题
[“1”, “2”, “3”].map(parseInt)
你的第一反应结果是不是[1,2,3],但是真正的结果是[1, NaN, NaN]
为什么呢?
因为parseInt(string, radix)接收两个参数,第一个表示被处理的值(字符串),第二个表示为解析时的基数。radix是一个介于2-36之间的整数,返回解析后的整数值。 如果被解析参数的第一个字符无法被转化成数值类型,则返回 NaN。
1. parseInt(‘1’, 0); // radix为0时,使用默认的10进制。
2. parseInt(‘2’, 1); // radix值在2-36,无法解析,返回NaN
3. parseInt(‘3’, 2); // 基数为2,2进制数表示的数中,最大值小于3,无法解析,返回NaN
七、函数节流与函数防抖
1、什么是函数节流
为了尽可能的减少资源的消耗,最大的发挥性能。举个例子,我们通常观看的视频,一般32帧就能满足绝大多数人的要求,所以节目制作组也没有必要把视频做到32帧以上,更好的节约了资源。
函数节流:指定时间间隔内只执行一次函数。
函数防抖:任务频繁触发的情况下,只有任务触发的间隔超过指定间隔的时候,任务才会执行。举例,假如电梯指定时间内才能上,只有当电梯到达指定时间了才会上去,而不是来一个人上一个。
2、应用场景
函数节流应用场景:当我们滚动条下拉的时候,我们需要判断页面是否到了底部,但是我们如果不加任何其他措施的时候,他会一直触发监听页面是否到了底部,这样就很浪费性能。所以我们可以用setTimeout设订时间,每隔多长时间判断一次。
函数防抖应用场景:以用户注册时用户名是否被占用为例,现在,很多应用为了提高用户体验,都是在用户输入的时候就判断该名称是否被占用,但是这样是很浪费性能的。理想的做法是当用户输入第一个字符以后如果用户还要输入我们就暂时不去判断用户名是否被占用。