前端面试与学习

前端面试


前言

作为前端小小的一员,在学习的过程中记录下一些重要、关键的知识点,有自己总结一些难点,也有一些前端面试高频知识考点,有助于我复习的同时也希望能帮到大家,让我们一起学习一起成长,一起拿offer!


一、HTML和CSS


1、HTML5有那些新特性?

(1)HTML4 规定了三种声明方式,分别是:严格模式、过渡模式 和 框架集模式;而HTML5因为不是SGML的子集,只需要<!DOCTYPE>就可以了

(2)语义化更好的内容标签。headerfooterarticleasidenav

(3)音频、视频 API(audio,video)

(4)表单控件:HTML5 拥有多个新的表单输入类型。这些新特性提供了更好的输入控制和验证

  • color
  • date
  • datetime
  • datetime-local
  • email
  • month
  • number
  • range
  • search
  • tel
  • ime
  • url
  • week

(5)5个API-本地存储,长期存储数据的localStorage,比较常用,临时存储的 sessionStorage,浏览器关闭后自动删除,实际工作中使用的场景不多。

(6)其他还有Canvas画布、Geolocation地理:地理位置 API 允许用户向 Web 应用程序提供他们的位置。出于隐私考虑,报告地理位置前会先请求用户许可、拖拽释放、Web Wordker等·。


2、如何理解HTML结构的语义化?

去掉或样式丢失的时候能让页面呈现清晰的结构:

html 本身是没有表现的,我们看到例如<h1>是粗体,字体大小 2em,加粗;<strong>是加粗 的,不要认为这是 html 的表现,这些其实 html 默认的 css 样式在起作用,所以去掉或样式 丢失的时候能让页面呈现清晰的结构不是语义化的 HTML 结构的优点,但是浏览器都有有默 认样式,默认样式的目的也是为了更好的表达 html 的语义,可以说浏览器的默认样式和语 义化的 HTML 结构是不可分割的。

屏幕阅读器(如果访客有视障)会完全根据你的标记来“读”你的网页. 例如,如果你使用的含语义的标记,屏幕阅读器就会“逐个拼出”你的单词,而不是试着去对 它完整发音.

PDA、手机等设备可能无法像普通电脑的浏览器一样来渲染网页(通常是因为这些设备对 CSS 的支持较弱)

使用语义标记可以确保这些设备以一种有意义的方式来渲染网页.理想情况下,观看设备的 任务是符合设备本身的条件来渲染网页.

语义标记为设备提供了所需的相关信息,就省去了你自己去考虑所有可能的显示情况(包括 现有的或者将来新的设备).例如,一部手机可以选择使一段标记了标题的文字以粗体显示. 而掌上电脑可能会以比较大的字体来显示.无论哪种方式一旦你对文本标记为标题,您就可 以确信读取设备将根据其自身的条件来合适地显示页面.

搜索引擎的爬虫也依赖于标记来确定上下文和各个关键字的权重 过去你可能还没有考虑搜索引擎的爬虫也是网站的“访客”,但现在它们他们实际上是极其 宝贵的用户.没有他们的话,搜索引擎将无法索引你的网站,然后一般用户将很难过来访问.

你的页面是否对爬虫容易理解非常重要,因为爬虫很大程度上会忽略用于表现的标记,而只 注重语义标记.

因此,如果页面文件的标题被标记,而不是,那么这个页面在搜索结果的位置可能会比较靠后. 除了提升易用性外,语义标记有利于正确使用 CSS 和 JavaScript,因为其本身提供了许多“钩 钩”来应用页面的样式与行为.

SEO 主要还是靠你网站的内容和外部链接的。

便于团队开发和维护
W3C 给我们定了一个很好的标准,在团队中大家都遵循这个标准,可以减少很多差异化的东 西,方便开发和维护,提高开发效率,甚至实现模块化开发。


3、谈谈从前端的角度出发做好SEO需要考虑什么?

了解搜索引擎如何抓取网页和如何索引网页

你需要知道一些搜索引擎的基本工作原理,各个搜索引擎之间的区别,搜索机器人 (SE robot 或叫 web crawler)如何进行工作,搜索引擎如何对搜索结果进行排序等 等。

Meta 标签优化

主要包括主题(Title),网站描述(Description),和关键词(Keywords)。还有一些其它 的隐藏文字比如 Author(作者),Category(目录)Language(编码语种)等。

如何选取关键词并在网页中放置关键词

搜索就得用关键词。关键词分析和选择是 SEO 最重要的工作之一。首先要给网站确定主关键 词(一般在 5 个上下),然后针对这些关键词进行优化,包括关键词密度(Density),相 关度(Relavancy),突出性(Prominency)等等。

了解主要的搜索引擎

虽然搜索引擎有很多,但是对网站流量起决定作用的就那么几个。比如英文的主要有 Google,Yahoo,Bing 等;中文的有百度,搜狗,有道等。不同的搜索引擎对页面的抓取和 索引、排序的规则都不一样。还要了解各搜索门户和搜索引擎之间的关系,比如 AOL 网页搜 索用的是 Google 的搜索技术,MSN 用的是 Bing 的技术。

主要的互联网目录

Open Directory 自身不是搜索引擎,而是一个大型的网站目录,他和搜索引擎的主要区别 是网站内容的收集方式不同。目录是人工编辑的,主要收录网站主页;搜索引擎是自动收集 的,除了主页外还抓取大量的内容页面。

按点击付费的搜索引擎

搜索引擎也需要生存,随着互联网商务的越来越成熟,收费的搜索引擎也开始大行其道。最 典型的有 Overture 和百度,当然也包括 Google 的广告项目 Google Adwords。越来越多的 人通过搜索引擎的点击广告来定位商业网站,这里面也大有优化和排名的学问,你得学会用 最少的广告投入获得最多的点击。

搜索引擎登录

网站做完了以后,别躺在那里等着客人从天而降。要让别人找到你,最简单的办法就是将网 站提交(submit)到搜索引擎。如果你的是商业网站,主要的搜索引擎和目录都会要求你付 费来获得收录(比如 Yahoo 要 299 美元),但是好消息是(至少到目前为止)最大的搜索引 擎 Google 目前还是免费,而且它主宰着 60%以上的搜索市场。

链接交换和链接广泛度(Link Popularity)

网页内容都是以超文本(Hypertext)的方式来互相链接的,网站之间也是如此。除了搜索 引擎以外,人们也每天通过不同网站之间的链接来 Surfing(“冲浪”)。其它网站到你的 网站的链接越多,你也就会获得更多的访问量。更重要的是,你的网站的外部链接数越多, 会被搜索引擎认为它的重要性越大,从而给你更高的排名。


4、CSS中link和@import的区别是?

Link属于 html 标签,而@import是 CSS 中提供的

在页面加载的时候,link 会同时被加载,而@import 引用的 CSS 会在页面加载完成后才会加 载引用的 CSS
@import 只有在 ie5 以上才可以被识别,而 link 是 html 标签,不存在浏览器兼容性问题
Link 引入样式的权重大于@import 的引用(@import 是将引用的样式导入到当前的页面中)
故一般来说使用link更快更安全


5、为什么要初始化样式?

由于浏览器的兼容问题,不同浏览器对标签的默认样式值不同,若不初始化会照成不同浏览器之间的显示差异
但是初始化css会对搜索引擎优化造成小影响


6、实现元素垂直居中

两种实现方法,第一种简单快捷通过设置外层盒子flex布局,然后设置justify-content:center; 实现横向居中(默认水平居中),align-iten: center;实现纵向居中(默认即垂直居中)。

第二种即通过定位来实现,注意外层position设置为relative内层的absolute才管用,设置完相应的偏移值后别忘了平移一下,将内盒子自身的宽高算进去。

		.outer { 
			width: 300px;
			height: 300px;
			border: 1px solid red;
			background-color: red;
/* 			display: flex;
			justify-content: center;
			align-items: center; */
			position: relative;
		}
				
		.inner { 
			width: 150px;
			height: 150px;
			background: blue; 
			position: absolute;
			top: 50%;
			left: 50%;
			transform: translate(-50%, -50%);
		}

7、通过css实现一个三角形,并且鼠标移入时能旋转

注意实现旋转的时候通过transform-origin设置旋转中心。

		.box {
			margin: 0 auto;
			width: 0;
			height: 0;
			border-top: 100px solid transparent;
			border-bottom: 100px solid transparent;
			border-left: 100px solid greenyellow;
			transform-origin: 0% 50%; /* 这个不能放在下面不然会乱 ->*/
			transition: transform 0.5s;
		}
		.box:hover {
			transform: rotate(90deg);	
		}

8、如何实现浏览器内多个标签之间的通信?


调用 localstorgecookies 等本地存储方式:

  • 在 B 页面中可以使用 window.opener 获得 A 页面的 window 句柄,使用该句柄即可调用 A 页面中的对象,函数等。
    例如 A 页面定义 js 函数 onClosePageB,在 B 页面可以用 window.opener.onClosePageB 来进行回调。
  • 使用 window.showModalDialog(sURL [, vArguments] [,sFeatures])打开新窗口。 其中vArguments 参数可以用来向对话框传递参数。传递的参数类型不限,包括数组、函数等。对话框通过window.dialogArguments来取得传递进来的参数。
  • 如果是支持 HTML5 的话,建议用本地存储 (local storage),它支持一个事件方法window.onstorage,只要其中一个窗口修改了本地存储,其他同源窗口会触发这个事件。

9、简述一下src与href的区别?

  • src ⽤于替换当前元素,href⽤于在当前⽂档和引⽤资源之间确⽴联系。
  • src 是 source 的缩写,指向外部资源的位置,指向的内容将会嵌⼊到⽂档中当前标签所在位置;在请求 src 资源时会将其指向的资源下载并应⽤到⽂档内,例如 js 脚本,img 图⽚和 frame 等元素
  • 当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执⾏完毕,图⽚和框架等元素也如此,类似于将所指向资源嵌⼊当前标签内。这也是为什么将js脚本放在底部⽽不是头部
  • href 是 Hypertext Reference 的缩写,指向⽹络资源所在位置,建⽴和当前元素(锚点)或当前⽂档(链接)之间的链接,如果我们在⽂档中添加<link href="common.css" rel="stylesheet"/> 那么浏览器会识别该⽂档为 css ⽂件,就会并⾏下载资源并且不会停⽌对当前⽂档的处理。这也是为什么建议使⽤ link ⽅式来加载 css ,⽽不是使⽤ @import ⽅式

10、浏览器是怎么渲染页面的?


11、Canvas和SVG图形的区别是什么?

  • Canvas 和 SVG 都可以在浏览器上绘制图形。

  • SVG Canvas 绘制后记忆,换句话说任何使用 SVG 绘制的形状都能被记忆和操作,浏览器可以再次显示 Canvas 则是绘制后忘记,一旦绘制完成你就不能访问像素和操作它 SVG 对于创建图形例如 CAD 软件是良好的,一旦东西绘制,用户就想去操作它 Canvas 则用于绘制和遗忘类似动漫和游戏的场画。

  • 为了之后的操作,SVG 需要记录坐标,所以比较缓慢。

  • 因为没有记住以后事情的任务,所以 Canvas 更快。

  • SVG 并不属于 html5 专有内容,在 html5 之前就有 SVG。
    SVG 文件的扩展名是”.svg”。
    SVG 绘制的图像在图片质量不下降的情况下被放大。
    SVG 图像经常在网页中制作小图标和一些动态效果图


12、CSS的权重和优先级

权重

  • 从0开始,一个行内样式+1000,一个id选择器+100,一个属性选择器、class或者伪类+10,一个元素选择器,或者伪元素+1,通配符+0

CSS的伪类选择器有 :hover、:active、:focus等,伪元素选择器有::first-letter、::before、::after等,具体可以看这篇文章

优先级

  • 权重相同,写在后面的覆盖前面的
  • 使用 !important 达到最大优先级,都使用 !important 时,权重大的优先级高

13、圣杯布局和双飞翼布局

这两个三列布局的方式是大厂的高频考点,不只是要能实现,还要知道这两者实现的差异。这篇博客清楚的介绍了这两者的概念、实现过程和他们的区别。


14、BFC

BFC(Block Formatting Context)块级格式化上下文,是 Web 页面中盒模型布局的 CSS 渲染模式,指一个独立的渲染区域或者说是一个隔离的独立容器。

形成 BFC 的条件:

  1. 浮动元素,floatnone 以外的值
  2. 定位元素,positionabsolute,fixed
  3. display 为以下其中之一的值 inline-block,table-cell,table-caption
  4. overflow 除了 visible 以外的值(hidden,auto,scroll
  5. HTML 就是一个 BFC

BFC 的特性:

  1. 内部的 Box 会在垂直方向上一个接一个的放置。

  2. 垂直方向上的距离由 margin 决定

  3. BFC 的区域不会与 float 的元素区域重叠,利用此特性可以实现两列布局,左边固定宽度,右边自适应

  4. 计算BFC 的高度时,浮动元素也参与计算

  5. BFC 就是页面上的一个独立容器,容器里面的子元素不会影响外面元素。

    大家请记住下面这个表现原则:如果一个元素具有BFC,内部子元素再怎么翻江倒海、翻云覆雨,都不会影响外部的元素。所以,BFC元素是不可能发生ma rgin重叠的,因为margin重叠是会影响外面的元素的; BFC 元素也可以用来清除浮动的影响,因为如果不清除,子元素浮动则父元素高度塌陷,必然会影响后面元素布局和定位,这显然有违BFC元素的子元素不会影响外部元素的设定。


15、清除浮动的方法

为什么需要清除浮动?
不清楚浮动会发送高度塌陷,当父元素没有设置高度而子元素设置了浮动时,子元素脱离正常的文档流,父元素高度自适应而塌陷。

解决方法:

  1. 添加空div法:在浮动的元素后面添加一个空的idv并设置css样式为
.clear{
        clear: both;
        overflow: hidden;
    }

该方法通俗易懂、操作方便,但是添加了无意义的标签,不利于结构化。

  1. 给浮动父元素设置高度
  2. 父级元素添加overflow: hidden;,可以通过触发BFC的方式,实现清楚浮动效果。必须定义width或zoom:1,同时不能定义height,使用overflow:hidden时,浏览器会自动检查浮动区域的高度

该方法 简单、代码少、但是内容增多时候容易造成不会自动换行导致内容被隐藏掉,无法显示需要溢出的元素。

  1. after伪元素 清除浮动法(现在主流方法,推荐使用)
 .clearfix:after{/*伪元素是行内元素 正常浏览器清除浮动方法*/
        content: "";
        display: block;
        height: 0;
        clear:both;
        visibility: hidden;
    }

为什么使用伪元素清除浮动需要display:block?因为伪元素默认是内联的,而clear只对块级元素起作用,故需要块级化


16、CSS min-width/height和max-width/height

虽然在MDNW3C的文档上显示的min-width/min-height初始值为0,但是在所有浏览器中的min-width/min-height初始值都是auto

document.body.style.minWidth;
// auto

注意: 这四个属性权重是超越!important,超越最大

超越!important指的是max-width会覆盖width的设置,不管width是行内样式还是!important

<img src="1.ipg" style="width:480px !important;">

img {
	max-width: 256px;
}
/* 最终图片的大小是256px */

超越最大指的是min-width覆盖max-width,当像下面这样设计时:

.container {
	min-width: 1400px;
	max-width: 1200px;
}

最终的宽度最少是1400px,即min-width覆盖了max-heigth


17、幽灵空白节点

幽灵空白节点CSS世界的作者对内联元素的所有解析和渲染表现就如同每个行框盒子的前面都有一个空白节点一样现象的称呼。

div {
	background-color: aqua;
}
span {
	display: inline-block;
}
<div><span></span></div>

上面的CSSHTML代码的结果如下:
在这里插入图片描述
为什么内部span元素的宽高明明是0,标签之间也没有换行符,此div标签的高度并不为0?原因就是存在幽灵空白节点 ——即在span元素的前面还有一个宽度为0的空白字符。

规范中有提到这个现象,幽灵空白节点实际上也是一个盒子,不过是假象盒,名叫strut,中文翻译为支柱,是一个存在于行框盒子前面,同时具有该元素的字体和行高属性的0宽度的内联盒。

规范中原文如下:

     Each line box starts with a zero-width inline box 
 with the element's font and line height properties. We
 call that imaginary box a "strut".

18、CSS实现动态"…"加载效果

content属性的一种妙用

html代码:

<div>
	正在加载<dot>...</dot>
</div>

CSS代码:

dot {
	display: inline-block;
	height: 1em;
	line-height: 1;
	text-align: left;
	vertical-align: bottom;  /* 让'...'在一行的底部显示 */
	overflow: hidden;
}
			
dot::before {
	display: block;
	content: "...\A..\A.";
	white-space: pre-wrap;
	animation: dot 3s infinite step-start both;  /* step-start动画开始的时候省去第一帧,从第二帧开始,且省去过度效果与之相对应的step-end正常执行,只是省去过度效果*/
}

@keyframes dot {
	33% { transform: translateY(-2em); }
	66% { transform: translateY(-1em); }
}

一些细节实现的解答:

(1)为什么使用<dot>这个元素?

<dot>是自定义的一个标签元素,除了简约、语义化明显外,更重要的是方便向下兼容,IE8等低版本浏览器不认识自定义的 HTML标签,因此,会乖乖地显示里面默认的3个点,对我们的CSS代码完全忽略。

(2)为什么使用::before ,可不可以使用: :after ?

伪元素使用: : before 同时display设置为block ,是为了在高版本浏览器下原来的3个点推到最下面,不会影响content 的3行内容显示,如果使用: : after 怕是效果就很难实现了。

(3)从含量属性值来看,是3个点在第1行,而1个点反而在最后一行,为什么这么处理?

3个点在第一行的目的在于兼容IE9浏览器,因为IE9浏览器认识以及:: before ,但是不支持CSS新世界的animation属性,所以,为了IE9也能正常显示静态的3个点,故而把3个点放在第一行。

还有最后几个小技巧,首先,’\A’是不区分大小写的;其次,’\D’也能实现换行效果,但是,要想上下行对齐,需要用在 : : before 伪元素上,因为CR是将光标移动到当前行的开头,而LF是将光标「垂直」移动到下一行。


19、不简单的vertical-align

ertical-align: 该属性定义行内元素基线相对于该元素所在行的基线的垂直对齐,只对行内元素和行内块元素有效

这里的垂直对齐方式有那些呢?
首先我们需要了解中文文本的组成,文本有基线、底线、中线、顶线组成。
在这里插入图片描述
类比而言行内元素的垂直对齐方式就有基于底部、基线、中间和顶部。默认是基线。所以当图片和文字在一起的时候就会出现两者“不对齐”,这时可以把图片的vertical-align设置成bottom


20、实现打字机效果

效果如下:
在这里插入图片描述
html代码:

<div>我不知道你在说什么</div>

CSS:

  div {
    font-size: 46px;
    font-family: monospace;
    /* 1ch 代表0的宽度  */
    width: 0ch;
    white-space: nowrap;
    /* animation: move 4s linear  forwards; */
    /* steps 就是分几步来完成动画,有了 steps 不要写ease linear了 */
    animation: move 4s steps(9) forwards;
    overflow: hidden;
  }

  @keyframes move {
    0% {}
    100% {
      width: 18ch;
    }
  }

注意:

  • 1ch = 1个英文 = 1个数字
  • 2ch = 1个中文

21、深入理解content计数器

计数器效果可以说是content部分的重中之重,因为此功能非常强大、实用,且具有不可替代性,甚至可以实现连JavaScript都不好实现的效果。

CSS计数器的两个属性:

  1. 属性counter-reset。顾名思义就是计数器重置的意思,主要用于给计数器起个名字,方便调用。列如声明两个计数器counter1和counter2且counter1从0开始计数(默认的)counter2从2开始计数。

    div { counter-reset: counter1 counter2 2;}
    
  2. counter-increment。顾名思义就是计数器递增的意思。该属性的值为一个或多个counter-reset声明的值,后面可以跟数字,表示每次计数的变化值,默认是1。该属性没出现一次对应的计数器就计数一次。

  3. 方法counter() / counters() 。作用是显示计数,有四种用法
    - counter(name)
    - counter(name, style)
    - counters(name, string)
    - counters(name, string, style)
    name就是计数器的名称,style类似有序列表的list-style-type即显示的序列号类型,比如circlelower-roman等。counters用于实现嵌套计数,如1.1、1.2等,string参数为字符串,表示层级序号之间的连接字符,如1-1的string就是’ - ‘。

是不是很懵…,我也很懵。。。还是来看例子吧
html代码

<div class="reset">
	<div class="counter">爷爷
		<div class="reset">
			<div class="counter">大儿子</div>
			<div class="counter">二儿子
				<div class="reset">
					<div class="counter">二儿子的大儿子</div>
					<div class="counter">二儿子的二儿子</div>
					<div class="counter">二儿子的三儿子</div>
				</div>
			</div>
			<div class="counter">三儿子</div>
		</div>
	</div>
	<div class="counter">二爷爷</div>
	<div class="counter">三爷爷
		<div class="reset">
			<div class="counter">三爷爷的大儿子</div>
		</div>
	</div>
</div>

CSS代码

 .reset { 
	padding-left: 20px; 
	counter-reset: counter1;
 }
.counter:before { 
	content: counters(counter1, '-') '. '; 
	counter-increment: counter1;
}

结果如下:
在这里插入图片描述
需要注意的是:想要实现嵌套,每一个列表容器(指上面有.reset的div)都要拥有同一个计数器


22、内联元素的padding不影响垂直方向吗?

这里常有一个错误的认识:内联元素的padding只会影响水平方向,不会影响垂直方向。

这种认知是不准确的,内联元素的padding在垂直方向同样会影响布局,影响视觉表现。只是因为内联元素没有可视宽度和可视高度的说法(clientHeight和clientwidth永远是o),垂直方向的行为表现完全受line-heightvertical-align的影响,视觉上并没有改变和上一行下一行内容的间距,因此,给我们的感觉就会是垂直padding没有起作用。

例如:
html:

<div class="d">这是第一行</div>
	<div>
		<a>我是链接</a>
	</div>
<div class="d">这是第二行</div>

CSS:

a {
	padding: 20px 0;
	background-color: red;
}
.d {
	background-color: bisque;
}

结果:
在这里插入图片描述
可以看到,尺寸虽有效,但是对上下元素的原本布局却没有任何影响,仅仅是垂直方向发生了层叠,
其实,relative元素的定位、明影box-shadow以及outline等也有类似的层叠效果。但是他们是有区别的。可以分为两类: 一类是纯视觉层叠,不影响外部尺寸;另一则会影响外部尺寸。box-shadow以及outline属于前者,而这里的inline元素的padding层叠属于后者。区分的方式很简单,如果父容器overflow:auto,层叠区域超出父容器的时候,没有滚动条出现,则是纯视觉的;如果出现滚动条,则会影响尺寸、影响布局。

当为上面a元素外层div设置overflow:auto后,结果如下:
在这里插入图片描述
由此可见,内联元素padding对视觉和布局有双重影响,所以类似于【垂直方向padding对内联元素没有作用】的说法显然不正确。

那知道这个有什么作用呢?很明显可以给链接加一个垂直方向上的padding,这样不影响布局和视觉,但是可以更方便的点击链接,特别是在移动端特别的有用。

23、使用padding的一些注意事项

  • padding百分比值无论水平方向还是垂直方向都是对于宽度计算的;

24、用padding实现三道杠和双层圆点

效果如下:
在这里插入图片描述
代码:
html

<div class="icon-menu"></div>
<div class="icon-dot"></div>

CSS

.icon-menu {
	display: inline-block;
	width: 140px;
	height: 10px;
	padding: 50px 0;
	border-bottom: 10px solid;
	border-top: 10px solid;
	background-color: black;
	background-clip: content-box;
}			

.icon-dot {
	display: inline-block;
	width: 90px;
	height: 90px;
	padding: 10px;
	border: 10px solid;
	border-radius: 50%;
	background-color: black;
	background-clip: content-box;
}

25、margin属性

  • 内联元素垂直方向的margin是没有任何影响的;

26、深入理解CSS中的margin:auto

margin:auto的填充规则如下:

  1. 如果一侧定值,一侧auto,则auto为剩余空间(相对父级盒子而言);
  2. 如果两侧都是auto,则平分剩余空间;

想要实现元素左或右对齐的话,可以使用margin-right:automargin-left:auto

为什么容器固定宽高,margin:auto却无法垂直居中?
      ~~~~~      因为触发margin:auto计算有一个前提条件,就是width或height为auto时,元素具有对应方向自动填充特性,很明显垂直方向不会自动填,所以也就实现不了。

那怎么实现垂直居中呢?通过绝对定位加margin:auto。
html

<div id="father">
	<div class="son"></div>
</div>

CSS

#father {
	width: 500px;
	height: 500px;
	border: 3px solid blue;
	position: relative;
}
.son {
	width: 200px;
	height: 200px;
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	top: 0;
	margin: auto;
	background-color: red;
}

在这里插入图片描述


27、boder-style:double

双线边框,顾名思义,即两根实线,其表现规则如下:
在这里插入图片描述
于是三道杠的另一种实现方法如下:
CSS

.icon-menu {
	width: 120px;
	height: 20px;
	border-top: 60px double;
	border-bottom: 20px solid;
}

结果:
在这里插入图片描述


28、添加图片的盒子实现

有时候外面需要实现下面这种效果:
在这里插入图片描述
对于右面的效果可以这样实现:
html:

<a class="add"></a>

CSS:

.add {
	display: inline-block;
	width: 200px;
	height: 200px;
	color: #ccc;
	border: 6px dashed;
	position: relative;
	transition: color .25s;
}
.add::before,
.add::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 50%;
}
.add::before {
	width: 40px;
	border-top: 10px solid;
	margin: -5px 0 0 -20px;
}
.add::after {
	height: 40px;
	border-left: 10px solid;
	margin: -20px 0 0 -5px;
}
.add:hover {
	color: #34538b;
}

结果:
在这里插入图片描述
这里有几个需要注意的点:

  • before或after伪元素默认为内联元素,故直接设置宽高无效;
  • 绝对定位会将内联元素块级化;
  • 绝对定位是相对于父级盒子的内边框而言的,即padding+content区域;
  • 绝对定位的元素包括margin区域;

29、line-height的使用

首先介绍一个东西——x-height,其表示小写字母x的高度,css中有些属性值的定义就和x-height有关,最典型的就是vertical-align:middle,这里的middle不是中间的意思,其指的是基线往上1/2x-height高度。

一些结论:

  • div的高度由行高决定的,而不是文字;
  • 对于非替换元素的纯内联元素,其可视高度完全line-height决定;

30、vertical-align

vertical-aigin的值可以分为四类:

  • 线类,如baseline (默认值)、top、middle、bottom;
    vertical-align属性的默认值baseline在文本之类的内联元素那里就是字符×下边缘,对于替换元素则是替换元素的下边缘。但是,如果是inline-block元素,则规则要复杂了:一个inline-block元素,如果里面没有内联元素,或者overflow不是visible,则该元素的基线就是其margin底边缘;否则其基线就是元素里面最后一行内联元素的基线。

  • 文本类,如text-top、text-bottom; (作用不大)

  • 上标下标类,如sub、super;

  • 数值百分比类,如20px、2em、20%;相对于基线往上或者往下相应的数值,对于百分比的值是相对于line-height的。

注意 vertical-align起作用的前提是内联元素或是display为table-cell的元素


31、absolute和text-align

按道理absolute会使元素块状化,应该不会受控制内联元素对齐的text-align影响,但是结果却不这样。

CSS、html代码:

<p><img src="1.jpg"/><p>
p {
	text-align: center;
}
img {
	position: absolute;
}

结果:
在这里插入图片描述
解释如下:

虽然本示例中图片位置确实受text-align属性影响,但是并不是text-align和absolute元素直接发生关系,absolute元素的display计算值是块状的,text-align是不会有作用的。 这里之所以产生了位置变化,本质上是「幽灵空白节点」和「无依赖绝对定位」共同作用的结果。

具体的渲染原理如下。
(1)由于<img>是内联水平,<p>标签中存在一 个宽度为0、看不见摸不着的「幽灵空白节点」,也是内联水平,于是受text-align : center影响而水平居中显示。

(2) <img>设置了position: absolute,表现为「无依赖绝对定位」,因此在「幽灵空白节点」后面定位显示;同时由于图片不占据空间,这里的「幽灵空白节点」当仁不让,正好在<p>元素水平中心位置显示,于是我们就看到了图片从<p>元素水平中间位置显示的效果。

这是非常简约的定位表现。此时,我们只要margin-left-半图片宽度负值大小,就可以实现图片的水平居中效果了,与父元素position:relative然后定位元素设置left : 50%的方法相比,其优势在于不需要改变父元素的定位属性,避免可能不希望出现的层级问题等。


32、relative的最小化影响原则

使用relative定位时,需要注意一下两点:

  1. 尽量不要使用relative,如果想定位某元素,看看能否使用【无依赖的绝对定位】
  2. 如果场景受限,一定要使用relative,则该relative务必最小化。

这里的最小化怎么理解呢?
最小化指的是,给需要父级盒子relative定位的元素单独包裹一层relative定位的盒子,使得relative影响最小化,避免因relative的层叠改变导致的各种【bug】

【relative的最小化影响原则】不仅规避了复杂场景可能出现样式问题的隐患,从日后的维护角度讲也更方便,比方说过了一端时间,我们不需要定位的元素了,直接移除这个relative最小化的单元即可!但是,如果relative是在整个容器上的,这段样式代码你敢删吗?万一其他元素定位也需要呢?万一relative还有提高层叠顺序的作用呢?留着没问题,删掉可能出bug,我想大多数的开发者一定会留着的, 这也是为什么随着项目进程的推进代码会越来越冗余的原因。


33、理解CSS世界的层叠上下文和层叠水平

层叠上下文相当于一个结界,层叠水平指在一个层叠上下文中各个元素在z轴上的层叠关系,注意,层叠水平的比较要限定在一个重叠上下文里,不同的层叠上下文又具有不同的层叠水平(相对于根元素的重叠上下文而已)

水平探讨只局限在当前层叠上下文元素中。为什么呢?因为不如此就没有意义。层叠上下文本身就是一个强力的「层叠结界」,而普通元素的层叠水平是无法突破这个结界和结界外的元素去较量层叠水平的。

需要注意的是,诸位千万不要把层叠水平和CSS的z-index 属性混为一谈。尽管某些情况下 z-index 确实可以影响层叠水平,但是只限于定位元素以及 flex 盒子的孩子元素;而层叠水平所有的元素都存在。

层叠关系图:
在这里插入图片描述(1)位于最下面的 background/ border 特指层叠上下文元素的边框和背景色。每一个层叠顺序规则仅适用于当前层叠上下文元素的小世界。

(2)inline 水平盒子指的是包括 inline/inline-block/inline-table 元素的「层叠顺序」,它们都是同等级别的。

(3) 单纯从层叠水平上看,实际上 z-index:0 和 z-index:auto 是可以看成是一样的。注意这里的措辞—— [单纯从层叠水平上看」,实际上,两者在层叠上下文领域有着根本性的差异。

对于position值不是static的定位元素,当其z-index值不是auto的时候,会创建重叠上下文


34、


二、JavaScript基础


1、 this、call、apply

JavaScript的this总是指向一个对象,根据函数运行时的执行环境动态绑定的。

this指向大致可以分为四种:

  1. 作为对象的方法调用
    this指向调用对象
  2. 作为普通函数的调用
    非严格模式下,指向全局对象windows,严格模式下是undefind。
  3. 构造器调用
    通常情况下,构造器里的this就指向返回的对象
  4. call或apply调用
    用于动态的改变传入函数的this’

1、


1、


1、


1、


1、


1、


三、web开发


1、谈谈降低页面加载时间的方法

1、压缩 css、js 文件
2、合并 js、css 文件,减少 http 请求
3、外部 js、css 文件放在最底下
4、减少 dom 操作,尽可能用变量替代不必要的 dom 操作


2、前端静态资源的组织总结

  • 为了最大程度利用缓存,将页面入口(HTML)设置为协商缓存,将JavaScript、CSS 等静态资源设置为永久强缓存
  • 为了解决强缓存更新问题,将文件摘要(hash)作为资源路径(URL)构成的一部分。·为了解决覆盖式发布引发的问题,采用name-hash 而非query-hash的组织方式,具体需要配置Wbpack的output.filename为 contenthash。
  • 为了解决 Nginx目录存储过大+结合 CDN提升访问速度,采用了Nginx反向代理+将静态资源上传到CDN。
  • 为了上传CDN,我们需要按环境动态构造publicPath+按环境构造CDN上传目录并上传。
  • 为了动态构造publicPath并且随构建过程插入到HTML 中,采用 Webpack-HTML- Plugin 等插件,将编译好的带hash+publicPath的静态资源插入到HTML中。
  • 为了保证上传CDN 的安全,我们需要一种机制管控上传CDN秘钥,而非简单的将秘钥写到代码/Dockerfile等明文文件中。

简直是层层套娃!
此时,我们已经基本获得了一套相对完备的前端静态资源组织方案。


3、从输入url到页面加载的全过程

  • 首先在浏览器中输入URL

  • 查找缓存:浏览器先查看浏览器缓存-系统缓存-路由缓存中是否有该地址页面,如果有则显示页面内容。如果没有则进行下一步。

    • 浏览器缓存:浏览器会记录DNS一段时间,因此,只是第一个地方解析DNS请求;
    • 操作系统缓存:如果在浏览器缓存中不包含这个记录,则会使系统调用操作系统, 获取操作系统的记录(保存最近的DNS查询缓存);
    • 路由器缓存:如果上述两个步骤均不能成功获取DNS记录,继续搜索路由器缓存;
    • ISP缓存:若上述均失败,继续向ISP搜索。
  • DNS域名解析:浏览器向DNS服务器发起请求,解析该URL中的域名对应的IP地址。DNS服务器是基于UDP的,因此会用到UDP协议。。

  • 建立TCP连接:解析出IP地址后,根据IP地址和默认80端口,和服务器建立TCP连接

  • 发起HTTP请求:浏览器发起读取文件的HTTP请求,,该请求报文作为TCP三次握手的第三次数据发送给服务器

  • 服务器响应请求并返回结果:服务器对浏览器请求做出响应,并把对应的html文件发送给浏览器

  • 关闭TCP连接:通过四次挥手释放TCP连接

  • 浏览器渲染:客户端(浏览器)解析HTML内容并渲染出来,浏览器接收到数据包后的解析流程为:

    • 构建DOM树:词法分析然后解析成DOM树(dom tree),是由dom元素及属性节点组成,树的根是document对象
    • 构建CSS规则树:生成CSS规则树(CSS Rule Tree)
    • 构建render树:Web浏览器将DOM和CSSOM结合,并构建出渲染树(render tree)
    • 布局(Layout):计算出每个节点在屏幕中的位置
    • 绘制(Painting):即遍历render树,并使用UI后端层绘制每个节点。

JS引擎解析过程:调用JS引擎执行JS代码(JS的解释阶段,预处理阶段,执行阶段生成执行上下文,VO,作用域链、回收机制等等)

  • 创建window对象:window对象也叫全局执行环境,当页面产生时就被创建,所有的全局变量和函数都属于window的属性和方法,而DOM Tree也会映射在window的doucment对象上。当关闭网页或者关闭浏览器时,全局执行环境会被销毁。

  • 加载文件:完成js引擎分析它的语法与词法是否合法,如果合法进入预编译

  • 预编译:在预编译的过程中,浏览器会寻找全局变量声明,把它作为window的属性加入到window对象中,并给变量赋值为’undefined’;寻找全局函数声明,把它作为window的方法加入到window对象中,并将函数体赋值给他(匿名函数是不参与预编译的,因为它是变量)。而变量提升作为不合理的地方在ES6中已经解决了,函数提升还存在。

  • 解释执行:执行到变量就赋值,如果变量没有被定义,也就没有被预编译直接赋值,在ES5非严格模式下这个变量会成为window的一个属性,也就是成为全局变量。string、int这样的值就是直接把值放在变量的存储空间里,object对象就是把指针指向变量的存储空间。函数执行,就将函数的环境推入一个环境的栈中,执行完成后再弹出,控制权交还给之前的环境。JS作用域其实就是这样的执行流机制实现的。


4、浏览器重绘与回流

1、重绘与回流的区别
  • 重排/回流(Reflow):当DOM的变化影响了元素的几何信息,浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排。表现为重新生成布局,重新排列元素。
  • 重绘(Repaint): 当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程,叫做重绘。表现为某些元素的外观被改变
    单单改变元素的外观,肯定不会引起网页重新生成布局,但当浏览器完成重排之后,将会重新绘制受到此次重排影响的部分

重排和重绘代价是高昂的,它们会破坏用户体验,并且让UI展示非常迟缓,而相比之下重排的性能影响更大,在两者无法避免的情况下,一般我们宁可选择代价更小的重绘。

『重绘』不一定会出现『重排』,『重排』必然会出现『重绘』。

2、如何触发回流和重绘

任何改变用来构建渲染树的信息都会导致一次回流或重绘:

  • 添加、删除、更新DOM节点
  • 通过display: none隐藏一个DOM节点-触发回流和重绘
  • 通过visibility: hidden隐藏一个DOM节点-只触发重绘,因为没有几何变化
  • 移动或者给页面中的DOM节点添加动画
  • 添加一个样式表,调整样式属性
  • 用户行为,例如调整窗口大小,改变字号,或者滚动。
3、如何避免回流和重绘
  • 集中改变样式,不要一条一条地修改 DOM 的样式。

  • 不要把 DOM 结点的属性值放在循环里当成循环里的变量。

  • 为动画的 HTML 元件使用 fixedabsoluteposition,那么修改他们的 CSS 是不会reflow的。

  • 不使用 table布局。因为可能很小的一个小改动会造成整个 table 的重新布局。

  • 尽量只修改position:absolutefixed元素,对其他元素影响不大

  • 动画开始GPU加速,translate使用3D变化

  • 提升为合成层
    将元素提升为合成层有以下优点:

    • 合成层的位图,会交由 GPU 合成,比 CPU 处理要快
    • 当需要 repaint 时,只需要 repaint 本身,不会影响到其他的层
    • 对于 transform 和 opacity 效果,不会触发 layout 和 paint

    提升合成层的最好方式是使用 CSS 的 will-change 属性:

    #target {
    	will-change: transform;
    }
    

5、闭包的两大作用:保存/保护

  • 闭包的概念

    函数执行时形成的私有上下文EC(FN),正常情况下,代码执行完会出栈后释放;但是特殊情况下,如果当前私有上下文中的某个东西被上下文以外的事物占用了,则上下文不会出栈释放,从而形成不销毁的上下文。 函数执行函数执行过程中,会形成一个全新的私有上下文,可能会被释放,可能不会被释放,不论释放与否,他的作用是:

(1)保护:划分一个独立的代码执行区域,在这个区域中有自己私有变量存储的空间,保护自己的私有变量不受外界干扰(操作自己的私有变量和外界没有关系);

(2)保存:如果当前上下文不被释放【只要上下文中的某个东西被外部占用即可】,则存储的这些私有变量也不会被释放,可以供其下级上下文中调取使用,相当于把一些值保存起来了;

我们把函数执行形成私有上下文,来保护和保存私有变量机制称为闭包

闭包是指有权访问另一个函数作用域中的变量的函数–《JavaScript高级程序设计》

稍全面的回答: 在js中变量的作用域属于函数作用域, 在函数执行完后,作用域就会被清理,内存也会随之被回收,但是由于闭包函数是建立在函数内部的子函数, 由于其可访问上级作用域,即使上级函数执行完, 作用域也不会随之销毁, 这时的子函数(也就是闭包),便拥有了访问上级作用域中变量的权限,即使上级函数执行完后作用域内的值也不会被销毁。

  • 闭包的特性:

    • 1、内部函数可以访问定义他们外部函数的参数和变量。(作用域链的向上查找,把外围的作用域中的变量值存储在内存中而不是在函数调用完毕后销毁)设计私有的方法和变量,避免全局变量的污染。

      1.1.闭包是密闭的容器,,类似于set、map容器,存储数据的

      1.2.闭包是一个对象,存放数据的格式为 key-value 形式

    • 2、函数嵌套函数

    • 3、本质是将函数内部和外部连接起来。优点是可以读取函数内部的变量,让这些变量的值始终保存在内存中,不会在函数被调用之后自动清除

  • 闭包形成的条件

    • 函数的嵌套
    • 内部函数引用外部函数的局部变量,延长外部函数的变量生命周期
  • 闭包的用途:

    • 模仿块级作用域
    • 保护外部函数的变量 能够访问函数定义时所在的词法作用域(阻止其被回收)
    • 封装私有化变量
    • 创建模块
  • 闭包应用场景
    闭包的两个场景,闭包的两大作用:保存/保护。 在开发中, 其实我们随处可见闭包的身影, 大部分前端JavaScript 代码都是“事件驱动”的,即一个事件绑定的回调方法; 发送ajax请求成功|失败的回调;setTimeout的延时回调;或者一个函数内部返回另一个匿名函数,这些都是闭包的应用。

  • 闭包的优点:延长局部变量的生命周期

  • 闭包缺点:会导致函数的变量一直保存在内存中,过多的闭包可能会导致内存泄漏


6、new运算符的实现机制

  1. 首先创建了一个新的空对象
  2. 设置原型,将对象的原型设置为函数的prototype对象。
  3. 让函数的this指向这个对象,执行构造函数的代码(为这个新对象添加属性)
  4. 判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。

7、EventLoop 事件循环

JS是单线程的,为了防止一个函数执行时间过长阻塞后面的代码,所以会先将同步代码压入执行栈中,依次执行,将异步代码推入异步队列,异步队列又分为宏任务队列微任务队列,因为宏任务队列的执行时间较长,所以微任务队列要优先于宏任务队列。微任务队列的代表就是,Promise.thenMutationObserver,宏任务的话就是setImmediate setTimeout setInterval

JS运行的环境。一般为浏览器或者Node。 在浏览器环境中,有JS 引擎线程和渲染线程,且两个线程互斥。 Node环境中,只有JS 线程。 不同环境执行机制有差异,不同任务进入不同Event Queue队列。 当主程结束,先执行准备好微任务,然后再执行准备好的宏任务,一个轮询结束。

浏览器中的事件环(Event Loop)

事件环的运行机制是,先会执行栈中的内容,栈中的内容执行后执行微任务,微任务清空后再执行宏任务,先取出一个宏任务,再去执行微任务,然后在取宏任务清微任务这样不停的循环。

  • eventLoop 是由JS的宿主环境(浏览器)来实现的;

  • 事件循环可以简单的描述为以下四个步骤:

    • 函数入栈,当Stack中执行到异步任务的时候,就将他丢给WebAPIs,接着执行同步任务,直到Stack为空;
    • 此期间WebAPIs完成这个事件,把回调函数放入队列中等待执行(微任务放到微任务队列,宏任务放到宏任务队列)
    • 执行栈为空时,Event Loop把微任务队列执行清空;
    • 微任务队列清空后,进入宏任务队列,取队列的第一项任务放入Stack(栈)中执行,执行完成后,查看微任务队列是否有任务,有的话,清空微任务队列。重复4,继续从宏任务中取任务执行,执行完成之后,继续清空微任务,如此反复循环,直至清空所有的任务。

浏览器中的任务源(task):

  • 宏任务(macrotask):
    宿主环境提供的,比如浏览器ajax、setTimeout、setInterval、setTmmediate(只兼容ie)、script、requestAnimationFrame、messageChannel、UI渲染、一些浏览器api
    微任务(microtask):

  • 语言本身提供的,比如promise.then、queueMicrotask(基于then)、mutationObserver(浏览器提供)、messageChannel 、mutationObersve


8、节流和防抖


9、


9、


9、


9、


四、React

1、虚拟DOM的diff算法

  1. react/vue中的key有什么作用?(key的内部原理是什么?)
    虚拟DOM中key的作用:

    • 简单的说:key是虚拟DOM的标识,在更新显示时起着极其重要的作用。

    • 详细的说:当状态中的数据发生变化时,react会根据新数据生成新的虚拟DOM,随后React进行新虚拟DOM与旧虚拟DOM的diff比较,比较规则如下:
         ~~    a. 旧虚拟DOM中找到与新虚拟DOM’相同的key:

      • 若虚拟DOM中内容没有变,直接使用之前的真实DOM
      • 若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM

         ~~   b. 旧虚拟DOM中未找到与新虚拟DOM相同的key

      • 根据数据创建新的真实DOM,随后渲染到页面
  2. 为什么遍历列表时,key最好不要用index?
    用index作为key可能引发的问题:

    • 若对数据进行逆序添加逆序删除等破坏顺序的操作,会产生没有必要的真实DOM更新==>界面效果没问题,但效率低。
    • 如果结构中还包含了输入类的DOM,那么会产生错误的DOM更新
    • 注意!如果不存在对数据的逆序添加、逆序删除等破坏性的操作,仅用于渲染列表时,使用index作为key是没有问题的。

2、


五、CSS选择器世界


1、CSS优先级规则

  • 0级:通配选择器 ‘*‘
  • 1级:标签选择器,如div、span
  • 2级:类选择器、属性选择器和伪类
    类选择器:.foo、.bar
    属性选择器:[class]、[src]、[type]
    伪类::hover、:focus
  • 3级:id选择器
  • 4级:style内联样式
  • 5级!important

注意:不同级别优先级无法跨越,即11个类选择器还是小于一个id选择器


2、CSS选择器的命名

  • 命名时尽量简短,比如【一段简绍】,类名可以这样:.some-intro,而没必要这样:.some-introduction。
  • 命名时除了特有名称,不要使用拼音
  • 借鉴html标签。比如:
    .cs-module-body {}
    .cs-module-nav{}
    .cs-module-img{}
    .cs-module-a {}          ~~~~~~~~         当想要表示链接时可以考虑使用a代替link
    .cs-module-ul {}
    .cs-module-li {}
    .cs-module-g {}          ~~~~~~~~         g表示group
    .cs-module-desc {}          ~~~~~~~~         desc表示description
    .cs-module-x {}          ~~~~~~~~         x表示box
    cs表示css-style

3、CSS选择器设计的最佳实践

  • 不要使用id选择器
    原因:

    • ID选择器优先级太高,不利于后期重置样式
    • 和JavaScript耦合。一般元素id用于让js获取DOM元素,若何样式关联,那么可维护性就会大打折扣。一旦id变化就要同时修改CSS和JavaScript。
  • . 不要嵌套选择器
    原因:

    • 渲染性能糟糕
    • 优先级混乱
    • 样式布局脆弱。不利于后期维护

    正确的选择器用法,全部使用无嵌套的纯类名选择器
    例如:
    在这里插入图片描述

  • 正确使用面向属性的命名
    建立自己的css样式库,比如:
    .dn { display: none; }
    .dib { display: inline-block }

  • 正确使用状态类名


4、属性选择器

ID选择器和类选择器都属于属性选择器。


1、CSS优先级规则


1、CSS优先级规则


1、CSS优先级规则


1、CSS优先级规则


1、CSS优先级规则


1、CSS优先级规则


更多精彩使用内容后续持续更新

我的世界
我的世界
我的世界
我的世界

   ~~   空格

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值