浏览器是如何对 HTML5 的离线储存资源进行管理和加载?
- 在线的情况下,浏览器发现 html 头部有 manifest 属性,它会请求 manifest 文件,如果是第一次访问页面 ,那么浏览器就会根据 manifest 文件的内容下载相应的资源并且进行离线存储。如果已经访问过页面并且资源已经进行离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的 manifest 文件与旧的 manifest 文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,就会重新下载文件中的资源并进行离线存储。
- 离线的情况下,浏览器会直接使用离线存储的资源。
label 的作用是什么?如何使用?
label标签来定义表单控件的关系:当用户选择label标签时,浏览器会自动将焦点转到和label标签相关的表单控件上。
- 使用方法1:
<label for="mobile">Number:</label>
<input type="text" id="mobile"/>
- 使用方法2:
<label>Date:<input type="text"/></label>
CSS3的新特性
transition
:过渡transform
: 旋转、缩放、移动或倾斜animation
: 动画gradient
: 渐变box-shadow
: 阴影border-radius
: 圆角word-break
:normal|break-all|keep-all
; 文字换行(默认规则|单词也可以换行|只在半角空格或连字符换行)text-overflow
: 文字超出部分处理text-shadow
: 水平阴影,垂直阴影,模糊的距离,以及阴影的颜色。box-sizing
:content-box|border-box
盒模型- 媒体查询
@media screen and (max-width: 960px) {}
还有打印print
CSS中可继承与不可继承属性有哪些
一、无继承性的属性
- display:规定元素应该生成的框的类型
- 文本属性:
- vertical-align:垂直文本对齐
- text-decoration:规定添加到文本的装饰
- text-shadow:文本阴影效果
- white-space:空白符的处理
- unicode-bidi:设置文本的方向
- 盒子模型的属性:width、height、margin、border、padding
- 背景属性:background、background-color、background-image、background-repeat、background-position、background-attachment
- 定位属性:float、clear、position、top、right、bottom、left、min-width、min-height、max-width、max-height、overflow、clip、z-index
- 生成内容属性:content、counter-reset、counter-increment
- 轮廓样式属性:outline-style、outline-width、outline-color、outline
- 页面样式属性:size、page-break-before、page-break-after
- 声音样式属性:pause-before、pause-after、pause、cue-before、cue-after、cue、play-during
二、有继承性的属性
- 字体系列属性
- font-family:字体系列
- font-weight:字体的粗细
- font-size:字体的大小
- font-style:字体的风格
- 文本系列属性
- text-indent:文本缩进
- text-align:文本水平对齐
- line-height:行高
- word-spacing:单词之间的间距
- letter-spacing:中文或者字母之间的间距
- text-transform:控制文本大小写(就是uppercase、lowercase、capitalize这三个)
- color:文本颜色
- 元素可见性
- visibility:控制元素显示隐藏
- 列表布局属性
- list-style:列表风格,包括list-style-type、list-style-image等
- 光标属性
- cursor:光标显示为何种形态
单行、多行文本溢出隐藏
- 单行文本溢出
overflow: hidden; // 溢出隐藏
text-overflow: ellipsis; // 溢出用省略号显示
white-space: nowrap; // 规定段落中的文本不进行换行
- 多行文本溢出
overflow: hidden; // 溢出隐藏
text-overflow: ellipsis; // 溢出用省略号显示
display:-webkit-box; // 作为弹性伸缩盒子模型显示。
-webkit-box-orient:vertical; // 设置伸缩盒子的子元素排列方式:从上到下垂直排列
-webkit-line-clamp:3; // 显示的行数
注意:由于上面的三个属性都是 CSS3 的属性,没有浏览器可以兼容,所以要在前面加一个-webkit-
来兼容一部分浏览器。
transition和animation的区别
- transition是过度属性,强调过度,它的实现需要触发一个事件(比如鼠标移动上去,焦点,点击等)才执行动画。它类似于flash的补间动画,设置一个开始关键帧,一个结束关键帧。
- animation是动画属性,它的实现不需要触发事件,设定好时间之后可以自己执行,且可以循环一个动画。它也类似于flash的补间动画,但是它可以设置多个关键帧(用@keyframe定义)完成动画。
参考 前端进阶面试题详细解答
head 标签有什么作用,其中什么标签必不可少?
标签用于定义文档的头部,它是所有头部元素的容器。 中的元素可以引用脚本、指示浏览器在哪里找到样式表、提供元信息等。
文档的头部描述了文档的各种属性和信息,包括文档的标题、在 Web 中的位置以及和其他文档的关系等。绝大多数文档头部包含的数据都不会真正作为内容显示给读者。
下面这些标签可用在 head 部分:<base>, <link>, <meta>, <script>, <style>, <title>
。
其中 <title>
定义文档的标题,它是 head 部分中唯一必需的元素。
为什么有时候⽤translate来改变位置⽽不是定位?
translate 是 transform 属性的⼀个值。改变transform或opacity不会触发浏览器重新布局(reflow)或重绘(repaint),只会触发复合(compositions)。⽽改变绝对定位会触发重新布局,进⽽触发重绘和复合。transform使浏览器为元素创建⼀个 GPU 图层,但改变绝对定位会使⽤到 CPU。 因此translate()更⾼效,可以缩短平滑动画的绘制时间。 ⽽translate改变位置时,元素依然会占据其原始空间,绝对定位就不会发⽣这种情况。
水平垂直居中的实现
- 利用绝对定位,先将元素的左上角通过top:50%和left:50%定位到页面的中心,然后再通过translate来调整元素的中心点到页面的中心。该方法需要考虑浏览器兼容问题。
.parent { position: relative;} .child { position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);}
- 利用绝对定位,设置四个方向的值都为0,并将margin设置为auto,由于宽高固定,因此对应方向实现平分,可以实现水平和垂直方向上的居中。该方法适用于盒子有宽高的情况:
.parent {
position: relative;
}
.child {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
- 利用绝对定位,先将元素的左上角通过top:50%和left:50%定位到页面的中心,然后再通过margin负值来调整元素的中心点到页面的中心。该方法适用于盒子宽高已知的情况
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px; /* 自身 height 的一半 */
margin-left: -50px; /* 自身 width 的一半 */
}
- 使用flex布局,通过align-items:center和justify-content:center设置容器的垂直和水平方向上为居中对齐,然后它的子元素也可以实现垂直和水平的居中。该方法要考虑兼容的问题,该方法在移动端用的较多:
.parent {
display: flex;
justify-content:center;
align-items:center;
}
|| 和 && 操作符的返回值?
|| 和 && 首先会对第一个操作数执行条件判断,如果其不是布尔值就先强制转换为布尔类型,然后再执行条件判断。
- 对于 || 来说,如果条件判断结果为 true 就返回第一个操作数的值,如果为 false 就返回第二个操作数的值。
- && 则相反,如果条件判断结果为 true 就返回第二个操作数的值,如果为 false 就返回第一个操作数的值。
|| 和 && 返回它们其中一个操作数的值,而非条件判断的结果
判断数组的方式有哪些
- 通过Object.prototype.toString.call()做判断
Object.prototype.toString.call(obj).slice(8,-1) === 'Array';
- 通过原型链做判断
obj.__proto__ === Array.prototype;
- 通过ES6的Array.isArray()做判断
Array.isArrray(obj);
- 通过instanceof做判断
obj instanceof Array
- 通过Array.prototype.isPrototypeOf
Array.prototype.isPrototypeOf(obj)
use strict是什么意思 ? 使用它区别是什么?
use strict 是一种 ECMAscript5 添加的(严格模式)运行模式,这种模式使得 Javascript 在更严格的条件下运行。设立严格模式的目的如下:
- 消除 Javascript 语法的不合理、不严谨之处,减少怪异行为;
- 消除代码运行的不安全之处,保证代码运行的安全;
- 提高编译器效率,增加运行速度;
- 为未来新版本的 Javascript 做好铺垫。
区别:
- 禁止使用 with 语句。
- 禁止 this 关键字指向全局对象。
- 对象不能有重名的属性。
async/await对比Promise的优势
- 代码读起来更加同步,Promise虽然摆脱了回调地狱,但是then的链式调⽤也会带来额外的阅读负担
- Promise传递中间值⾮常麻烦,⽽async/await⼏乎是同步的写法,⾮常优雅
- 错误处理友好,async/await可以⽤成熟的try/catch,Promise的错误捕获⾮常冗余
- 调试友好,Promise的调试很差,由于没有代码块,你不能在⼀个返回表达式的箭头函数中设置断点,如果你在⼀个.then代码块中使⽤调试器的步进(step-over)功能,调试器并不会进⼊后续的.then代码块,因为调试器只能跟踪同步代码的每⼀步。
对盒模型的理解
CSS3中的盒模型有以下两种:标准盒子模型、IE盒子模型 盒模型都是由四个部分组成的,分别是margin、border、padding和content。
标准盒模型和IE盒模型的区别在于设置width和height时,所对应的范围不同:
- 标准盒模型的width和height属性的范围只包含了content,
- IE盒模型的width和height属性的范围包含了border、padding和content。
可以通过修改元素的box-sizing属性来改变元素的盒模型:
box-sizeing: content-box
表示标准盒模型(默认值)box-sizeing: border-box
表示IE盒模型(怪异盒模型)
常见的图片格式及使用场景
(1)BMP,是无损的、既支持索引色也支持直接色的点阵图。这种图片格式几乎没有对数据进行压缩,所以BMP格式的图片通常是较大的文件。
(2)GIF是无损的、采用索引色的点阵图。采用LZW压缩算法进行编码。文件小,是GIF格式的优点,同时,GIF格式还具有支持动画以及透明的优点。但是GIF格式仅支持8bit的索引色,所以GIF格式适用于对色彩要求不高同时需要文件体积较小的场景。
(3)JPEG是有损的、采用直接色的点阵图。JPEG的图片的优点是采用了直接色,得益于更丰富的色彩,JPEG非常适合用来存储照片,与GIF相比,JPEG不适合用来存储企业Logo、线框类的图。因为有损压缩会导致图片模糊,而直接色的选用,又会导致图片文件较GIF更大。
(4)PNG-8是无损的、使用索引色的点阵图。PNG是一种比较新的图片格式,PNG-8是非常好的GIF格式替代者,在可能的情况下,应该尽可能的使用PNG-8而不是GIF,因为在相同的图片效果下,PNG-8具有更小的文件体积。除此之外,PNG-8还支持透明度的调节,而GIF并不支持。除非需要动画的支持,否则没有理由使用GIF而不是PNG-8。
(5)PNG-24是无损的、使用直接色的点阵图。PNG-24的优点在于它压缩了图片的数据,使得同样效果的图片,PNG-24格式的文件大小要比BMP小得多。当然,PNG24的图片还是要比JPEG、GIF、PNG-8大得多。
(6)SVG是无损的矢量图。SVG是矢量图意味着SVG图片由直线和曲线以及绘制它们的方法组成。当放大SVG图片时,看到的还是线和曲线,而不会出现像素点。SVG图片在放大时,不会失真,所以它适合用来绘制Logo、Icon等。
(7)WebP是谷歌开发的一种新图片格式,WebP是同时支持有损和无损压缩的、使用直接色的点阵图。从名字就可以看出来它是为Web而生的,什么叫为Web而生呢?就是说相同质量的图片,WebP具有更小的文件体积。现在网站上充满了大量的图片,如果能够降低每一个图片的文件大小,那么将大大减少浏览器和服务器之间的数据传输量,进而降低访问延迟,提升访问体验。目前只有Chrome浏览器和Opera浏览器支持WebP格式,兼容性不太好。
- 在无损压缩的情况下,相同质量的WebP图片,文件大小要比PNG小26%;
- 在有损压缩的情况下,具有相同图片精度的WebP图片,文件大小要比JPEG小25%~34%;
- WebP图片格式支持图片透明度,一个无损压缩的WebP图片,如果要支持透明度只需要22%的格外文件大小。
object.assign和扩展运算法是深拷贝还是浅拷贝,两者区别
扩展运算符:
let outObj = {
inObj: {a: 1, b: 2}
}
let newObj = {...outObj}
newObj.inObj.a = 2
console.log(outObj) // {inObj: {a: 2, b: 2}}
Object.assign():
let outObj = {
inObj: {a: 1, b: 2}
}
let newObj = Object.assign({}, outObj)
newObj.inObj.a = 2
console.log(outObj) // {inObj: {a: 2, b: 2}}
可以看到,两者都是浅拷贝。
- Object.assign()方法接收的第一个参数作为目标对象,后面的所有参数作为源对象。然后把所有的源对象合并到目标对象中。它会修改了一个对象,因此会触发 ES6 setter。
- 扩展操作符(…)使用它时,数组或对象中的每一个值都会被拷贝到一个新的数组或对象中。它不复制继承的属性或类的属性,但是它会复制ES6的 symbols 属性。
JavaScript 中如何进行隐式类型转换?
首先要介绍ToPrimitive
方法,这是 JavaScript 中每个值隐含的自带的方法,用来将值 (无论是基本类型值还是对象)转换为基本类型值。如果值为基本类型,则直接返回值本身;如果值为对象,其看起来大概是这样:
/*** @obj 需要转换的对象* @type 期望的结果类型*/
ToPrimitive(obj,type)
type
的值为number
或者string
。
(1)当type
为number
时规则如下:
- 调用
obj
的valueOf
方法,如果为原始值,则返回,否则下一步; - 调用
obj
的toString
方法,后续同上; - 抛出
TypeError
异常。
(2)当type
为string
时规则如下:
- 调用
obj
的toString
方法,如果为原始值,则返回,否则下一步; - 调用
obj
的valueOf
方法,后续同上; - 抛出
TypeError
异常。
可以看出两者的主要区别在于调用toString
和valueOf
的先后顺序。默认情况下:
- 如果对象为 Date 对象,则
type
默认为string
; - 其他情况下,
type
默认为number
。
总结上面的规则,对于 Date 以外的对象,转换为基本类型的大概规则可以概括为一个函数:
var objToNumber = value => Number(value.valueOf().toString())
objToNumber([]) === 0
objToNumber({}) === NaN
而 JavaScript 中的隐式类型转换主要发生在+、-、*、/
以及==、>、<
这些运算符之间。而这些运算符只能操作基本类型值,所以在进行这些运算前的第一步就是将两边的值用ToPrimitive
转换成基本类型,再进行操作。
以下是基本类型的值在不同操作符的情况下隐式转换的规则 (对于对象,其会被ToPrimitive
转换成基本类型,所以最终还是要应用基本类型转换规则):
+
操作符+
操作符的两边有至少一个string
类型变量时,两边的变量都会被隐式转换为字符串;其他情况下两边的变量都会被转换为数字。
1 + '23' // '123'
1 + false // 1
1 + Symbol() // Uncaught TypeError: Cannot convert a Symbol value to a number
'1' + false // '1false'
false + true // 1
-
、*
、\
操作符
NaN
也是一个数字
1 * '23' // 23
1 * false // 0
1 / 'aa' // NaN
- 对于
==
操作符
操作符两边的值都尽量转成number
:
3 == true // false, 3 转为number为3,true转为number为1
'0' == false //true, '0'转为number为0,false转为number为0
'0' == 0 // '0'转为number为0
- 对于
<
和>
比较符
如果两边都是字符串,则比较字母表顺序:
'ca' < 'bd' // false
'a' < 'b' // true
其他情况下,转换为数字再比较:
'12' < 13 // true
false > -1 // true
以上说的是基本类型的隐式转换,而对象会被ToPrimitive
转换为基本类型再进行转换:
var a = {}
a > 2 // false
其对比过程如下:
a.valueOf() // {}, 上面提到过,ToPrimitive默认type为number,所以先valueOf,结果还是个对象,下一步
a.toString() // "[object Object]",现在是一个字符串了
Number(a.toString()) // NaN,根据上面 < 和 > 操作符的规则,要转换成数字
NaN > 2 //false,得出比较结果
又比如:
var a = {name:'Jack'}
var b = {age: 18}
a + b // "[object Object][object Object]"
运算过程如下:
a.valueOf() // {},上面提到过,ToPrimitive默认type为number,所以先valueOf,结果还是个对象,下一步
a.toString() // "[object Object]"
b.valueOf() // 同理
b.toString() // "[object Object]"
a + b // "[object Object][object Object]"
const对象的属性可以修改吗
const保证的并不是变量的值不能改动,而是变量指向的那个内存地址不能改动。对于基本类型的数据(数值、字符串、布尔值),其值就保存在变量指向的那个内存地址,因此等同于常量。
但对于引用类型的数据(主要是对象和数组)来说,变量指向数据的内存地址,保存的只是一个指针,const只能保证这个指针是固定不变的,至于它指向的数据结构是不是可变的,就完全不能控制了。
li 与 li 之间有看不见的空白间隔是什么原因引起的?如何解决?
浏览器会把inline内联元素间的空白字符(空格、换行、Tab等)渲染成一个空格。为了美观,通常是一个<li>
放在一行,这导致<li>
换行后产生换行字符,它变成一个空格,占用了一个字符的宽度。
解决办法:
(1)为<li>
设置float:left。不足:有些容器是不能设置浮动,如左右切换的焦点图等。
(2)将所有<li>
写在同一行。不足:代码不美观。
(3)将<ul>
内的字符尺寸直接设为0,即font-size:0。不足:<ul>
中的其他字符尺寸也被设为0,需要额外重新设定其他字符尺寸,且在Safari浏览器依然会出现空白间隔。
(4)消除<ul>
的字符间隔letter-spacing:-8px,不足:这也设置了<li>
内的字符间隔,因此需要将<li>
内的字符间隔设为默认letter-spacing:normal。
let、const、var的区别
(1)块级作用域: 块作用域由 { }
包括,let和const具有块级作用域,var不存在块级作用域。块级作用域解决了ES5中的两个问题:
- 内层变量可能覆盖外层变量
- 用来计数的循环变量泄露为全局变量
(2)变量提升: var存在变量提升,let和const不存在变量提升,即在变量只能在声明之后使用,否在会报错。
(3)给全局添加属性: 浏览器的全局对象是window,Node的全局对象是global。var声明的变量为全局变量,并且会将该变量添加为全局对象的属性,但是let和const不会。
(4)重复声明: var声明变量时,可以重复声明变量,后声明的同名变量会覆盖之前声明的遍历。const和let不允许重复声明变量。
(5)暂时性死区: 在使用let、const命令声明变量之前,该变量都是不可用的。这在语法上,称为暂时性死区。使用var声明的变量不存在暂时性死区。
(6)初始值设置: 在变量声明时,var 和 let 可以不用设置初始值。而const声明变量必须设置初始值。
(7)指针指向: let和const都是ES6新增的用于创建变量的语法。 let创建的变量是可以更改指针指向(可以重新赋值)。但const声明的变量是不允许改变指针的指向。
区别 | var | let | const |
---|---|---|---|
是否有块级作用域 | × | ✔️ | ✔️ |
是否存在变量提升 | ✔️ | × | × |
是否添加全局属性 | ✔️ | × | × |
能否重复声明变量 | ✔️ | × | × |
是否存在暂时性死区 | × | ✔️ | ✔️ |
是否必须设置初始值 | × | × | ✔️ |
能否改变指针指向 | ✔️ | ✔️ | × |
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。