2024前端应试宝典,高频涵盖面试细节

时间:2024-03-06 16:10:10

前言

前端面试一直是前端人最麻烦的经历,因为面试需要(简历、学历、技术点、框架掌握、面试八股、未来规划、应试技巧、简历细节等),对于小厂相对简单一些,但是对于大厂来说,一次面试往往需要精心准备很长时间。

然后面经与前端面试八股,网上出现了各种最新的面试题,涵盖入门进阶啊什么的,但是往往有用的很少,真正的面试题需要一个人经验技术阅历都相对牛逼的人来整理。所以大家有需要可以【点击此处

正文详细

1.介绍上家公司项目

vue 项目总结,项目期间遇到的问题、难点等。【不定期更新】

近期一直在做一个 xxx 中心的项目,先来吐槽下内心的想法, 要开发的项目需求很不明确,需求两周两周的更改,感觉每天并没有特别多实际 的产出,总是感觉有点儿浪费时间。

虽然这样,但是作为开发,我们只能服从上级命令,好了,进入正题。

但是对我来说,感觉还好,需求的更改,对我来说又是新的开发,新的接触,同 时也是在锻炼我的耐心和耐性。

第一次使用 vue 开发实际的项目,虽然之前也有写过,但是都是自己练手的,并 没有实际的后端接口,这次对我自己来说也算是个小小的锻炼。项目开发过程中 遇到的坑,以及 bug,以及自己不会的地方挺多的,下面我就一一列举下。

(下面所有的问题,在我博客里面都会有)

(1)axios-请求中 post 请求的坑。刚开始的坑是,使用 axios 的 post 方法请求数 据,数据被拦截,数据一直传不到后端那边。后来查文档才得知 axios 对于 post 请求是有拦截功能的,需要自己判断,或者使用提请的 qs 方法,将传给后端的 数据进行下处理。

(2)路由传参的功能的坑。之前一直使用路由传参,但是当本页面刷新的时候, 页面上是没有参数的,因为参数是从上个页面传入进来的。

解决办法:使用 了缓存,和 vuex 状态管理。但是由于项目并不是很大型的项目,所以使用最多 的是缓存。

(3)页面缓存的坑。有个填写信息的页面,需要填写一部分信息,进入查新协 议页面,返回的时候,页面上填写的信息还需要留存。 解决办法:使用 vue 提 供的 keep-alive,来完成页面的缓存的。

(4)vue 组件动态加载的坑。由于首页的排版不确定,然后想着,让组件动态 显示,根据后端传入的数据,传入那个组件的数据,就显示那个组件。解决办法: 和后端商量好,做个标识。前端根据标识判断,动态显示组件。 使用到了 vue 中的<component :is=""></component> , 刚开始想着是不是和原生 js 一样使用append 直接可以插入进入呢,但是后来发现根本不可以,思路是可以的,但是 实现起来是行不通的。因为 append 后面插入的必须是个节点,而不是组件。后 来就去查阅 vue 文档。

但是现在还有个问题,首页是通过动态组件添加的,数据得从后端接口返回,但 是接口请求也是需要时间,所以,刚开始进入页面的是,页面先会是空白,但是 这样的体验并不友好,会让用户感觉到页面就是一片空白,但是好的解决办法现 在暂时没有想出来。好的解决办法还在寻找 ing。【师傅有建议添加个加载的 gif 图,但是,感觉。。。,我在找下看还有别的办法没,实在没有的话,就只能添加 个 gif 图了。】

(5)解析后端返回的 map 格式数据的坑。 之前解析数据的时候,直接就可以 拿去,然后直接渲染页面使用即可。但是这次遇到后端返回的是 map 格式的数 据,这就得解析下了。

例如:body['1'] 。根据返回的格式,自己解析成自己 需要的数据格式。

(6)更新文件缓存的坑。每次打包好文件给后端更新的时候,用户手机上总会 留下,上次版本的信息,而且每次都得清下缓存,才会显示最新版本的数据。后 来,我师傅提了个建议,让后端返回一个更新版本的接口,前端每次更新版本的 时候,都会给后端传入时间戳,然后后端接收后判断和库里的时间戳是否相同, 相同的返回不需要更新,不相同的话,返回要更新,然后前端这边的处理方法是: 需要更新的话,清除掉缓存,刷新页面即可。

虽然说给.js .css 文件后缀加上时间戳也是可以的,但是页面的入口 index.html 每次都是一样的,所以。。。就不会更新,,百度一些说在 nginx 服务器上,写上 强制更新,但是由于公司服务器上的文件很多,万一操作失误那就麻烦了。

(7)h5 页面打开调试日志。h5 页面不像小程序那样,直接可以打开控制台,在 手机上查看日志,得需要自己安装 vConsole 的插件来实现。 详见博客:

https://blog.****.net/Miss_liangrm/article/details/100867112

(8)获取首页链接里面的参数问题。获取是可以获取到,只要不跳转出这个项 目的页面,都是可以的,但是该项目链接了许多外链,所以,有时候返回的时候, 页面就会显示空白,因为获取的参数出了问题。解决办法:将参数设置成了缓存, 但是返回的速度快了,首页同样还是会出现拿不到参数,的问题。

解决办法还在寻找 ing。

(9)h5 里面的搜索。h5 里面 input 实现在手机上按下“搜索”,“go”,“前往” 等按钮的时候,同时会触发像 PC 端的 Enter。 input 标签需要设置属性:

type="search"

详见博客

https://blog.****.net/Miss_liangrm/article/details/102520925(10)登录接口 bug。需要判断 errCode 10001 状态的情况。如果出现 errCode 出现 10001,则清空原来的 session,重新请求该网络请求。

(11)封装的请求方法不需要在传入相同的参数。 封装的方法,每个方法里面 都得传入 sessoin,但是里面需要有个版本的方法不需要传入 session,那么就得 在封装的方法里面进行判断。详见博客:

https://blog.****.net/Miss_liangrm/article/details/102593402

(config.method == 'get') {

console.log('config.params.version',config.params.version)

if(config.params.version == 'v'){

// 在更新版本的接口里面会用到

config.url = config.url

}else{

config.url = config.url + '?session='+localStorage.getItem('session');

}

}

(12)省份地区判断的话,尽量不使用 name 判断,会有 bug 的。通过市区匹配 省份的话,使用 areaCode,有些文件是不一样的。

(13)进来不在 index.html 文件里面引入公共的文件,因为每次更新版本的时候, index.html 都是相同的,如果修改了公共文件,是会有缓存,不会更新。因为该 公共文件后面没有添加时间戳。

待优化的:

首页空白。【已解决】【添加了 loading】

页面更新版本缓存. 【已解决】(将获取连接的 templateId 写在 Home 页面)

2.用 node.js 做过项目么

3.对关系型数据库了解多少

4.移动端的布局方式

常见的 8 种移动端界面布局方式包括 8 种:. 1、列表式布局. 2、宫格式布局. 3、仪表布局. 4、卡片布局. 5、瀑布流布局. 6、Gallery 布局. 7、手风琴布 局. 8、多面板布局.4.PC 端的布局方式

总共有 6 大 布局方式 双飞翼、多栏、弹性、流式、瀑布流、响应式 布局

react 生命周期

1、mounting: 插入真实 DOM </br>

2、updating: 正在被重新渲染 props 或 state 改变 </br>

3、unmounting: 卸载 移除真实 DOM

第一阶段:装载阶段 3

constructor()

componentWillMount()

render()

componentDidMount()

第二阶段:更新阶段 2

componentWillReceiveProps()

shouldComponentUpdate()

componentWillUpdate()

render()

componentDidUpdate()

第三阶段:卸载阶段 1

componentWillUnmount()

constructor 生命周期:

(1)当 react 组件实例化时,是第一个运行的生命周期;

(2)在这个生命周期中,不能使用 this.setState();

(3)在这个生命周期中,不能使用副作用(调接口、dom 操作、定时器、长连接等);

(4)不能把 props 和 state 交叉赋值;

componentDidMount 生命周期:

(1)相当于是 vue 中的 mounted;

(2)它表示 DOM 结构在浏览器中渲染已完成;

(3)在这里可以使用任何的副作用;

shouldComponentUpdate(nextProps,nextState)生命周期:

(1)相当于一个开关,如果返回 true 则更新机制正常执行,如果为 false 则更新机制停止;

(2)在 vue 中是没有的;

(3)存在的意义:可以用于性能优化,但是不常用,最新的解决方案是使用 PureComponent;

(4)理论上,这个生命周期的作用,用于精细地控制声明式变量的更新问题,如果变化的声 明式变量参与了视图渲染则返回 true,如果被变化的声明式变量没有直接或间接参与视图渲染,则返回 false;

componentDidUpdate 生命周期:

(1)相当于 vue 中的 updated();

(2)它表示 DOM 结构渲染更新已完成,只发生在更新阶段;

(3)在这里,可以执行大多数的副作用,但是不建议;

(4)在这里,可以使用 this.setState(),但是要有终止条件判断。

componentWillUnmount 生命周期:

(1)一般在这里清除定时器、长连接等其他占用内存的构造器;

render 生命周期:

(1)render 是类组件中唯一必须有的生命周期,同时必须有 return(return 返回的 jsx 默认 只能是单一根节点,但是在 fragment 的语法支持下,可以返回多个兄弟节点);

(2)Fragment 碎片写法: <React.Fragment></React.Fragment> 简写成<></>;

(3)return 之前,可以做任意的业务逻辑,但是不能使用 this.setState(),会造成死循环;

(4)render()在装载阶段和更新阶段都会运行;

(5)当 render 方法返回 null 的时候,不会影响生命周期函数的正常执行。

Vue 和 React 的区别

1,react 整体是函数式的思想,把组件设计成纯组件,状态和逻辑通过参数 传入,所以在 react 中,是单向数据流;

2,

vue 的思想是响应式的,是基于是数据可变的,通过对每一个属性 Watcher 来监听,当属性变化的时候,响应式的更新对应的虚拟 dom。

3,

vue 表单可以使用 v-model 支持双向绑定,相比于 react 来说开发更简单。

4,改变数据的方式不同。react 需要通过 setState

5,react 使用 jsx,有一定的上手成本,并且需要一整套工具链支持。vue 使用模版语法,完全脱离工具链。

21、react 的优势

1. React 速度很快:它并不直接对 DOM 进行操作,引入了一个叫做虚拟 DOM 的概念,安插在 javascript 逻辑和实际的 DOM 之间,性能好。

2. 跨浏览器兼容:虚拟 DOM 帮助我们解决了跨浏览器问题,它为我们提供了 标准化的 API,甚至在 IE8 中都是没问题的。

3. 一切都是 component:代码更加模块化,重用代码更容易,可维护性高。

4. 单向数据流:Flux 是一个用于在 JavaScript 应用中创建单向数据层的架 构,它随着 React 视图库的开发而被 Facebook 概念化。

5. 同构、纯粹的 javascript:因为搜索引擎的爬虫程序依赖的是服务端响应 而不是 JavaScript 的执行,预渲染你的应用有助于搜索引擎优化。

6. 兼容性好:比如使用 RequireJS 来加载和打包,而 Browserify 和 Webpack 适用于构建大型应用。它们使得那些艰难的任务不再让人望而生畏。

6.你理解的闭包

闭包是什么?

闭包(closure)就是能够读取其他函数内部变量的函数。

在 javascript 中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解 成 “定义在一个函数内部的函数”。

在本质上,闭包是将函数内部和函数外部连接起来的桥梁。(闭包的最典型的应 用是实现回调函数(callback) )。

闭包的作用:

1. 在外部访问函数内部的变量

2. 让函数内的局部变量可以一直保存下去

3. 模块化私有属性和公共属性

参数和变量不会被垃圾回收机制回收

闭包的使用场景

1.setTimeout

原生的 setTimeout 传递的第一个函数不能带参数,通过闭包可以实现传参 效果。

2.回调定义行为,然后把它关联到某个用户事件上(点击或者按键)。代码通常会 作为一个回调(事件触发时调用的函数)绑定到事件。

3.函数防抖

在事件被触发 n 秒后再执行回调,如果在这 n 秒内又被触发,则重新计时。 实现的关键就在于 setTimeOut 这个函数,由于还需要一个变量来保存计时, 考虑维护全局纯净,可以借助闭包来实现。

4.封装私有变量

闭包的原理:

全局变量生存周期是永久,局部变量生存周期随着函数的调用结束而销毁。

闭包就是 在函数中定义且成为该函数内部返回的函数的*变量 的变量,该 变量不会随着外部函数调用结束而销毁。

(注:不光是变量,函数内声明的函数也可以形成闭包)

当函数可以记住并访问所在的词法作用域,即使函数是在当前词法作用域之外 执行,这时就产生了闭包。

闭包的 this 指向问题:

1.this 指向 window 对象(因为匿名函数的执行具有全局性,所以其 this 对 象指向 window);

2.不能实现 value 加 1(每个函数在被调用时都会自动取得两个特殊变量,this 和 arguments,内部函数在搜索这两个对象时,只会搜索到其活动对象为止, 所以不能实现访问外部函数的 this 对象);

3.修改代码实现正确功能

第一种解决方法:

/定义变量 that 用于保存上层函数的 this 对象

第二种解决方法:

//使用 apply 改变 helper 的 this 对象指向,使其指向 myNumber 对象

第三种解决方法

//使用 bind 绑定,和 apply 相似,只是它返回的是对函数的引用,不会立即

执行

闭包的应用场景:

// 1. 返回值 最常见的一种形式

// 2. 函数赋值 一种变形的形式是将内部函数赋值给一个外部变量

// 3. 函数参数 通过函数参数引用内部函数产生闭包

// 4. IIFE(自执行函数)

// 5. 循环赋值

// 6. getter 和 setter// getter 和 setter 函数来将要操作的变量保存在函数内部,防止暴露在

外部

// 7.迭代器(计数器)

// 8.触发事件

简述闭包的问题以及优化

闭包的缺点:占用内层空间 大量使用闭包会造成 栈溢出

由于闭包会一直占用内存空间,直到页面销毁,我们可以主动将已使用的闭包

销毁:

将闭包函数赋值为 null 可以销毁闭包

JS 中闭包的优缺点及特性

→ 优点:

1.保护函数内的变量安全

2.在内存中维持一个变量(用的太多就变成了缺点,占内存) ;

3. 逻辑连续,当闭包作为另一个函数调用的参数时,避免你脱离当前逻辑 而单独编写额外逻辑。

4. 方便调用上下文的局部变量。

5. 加强封装性,可以达到对变量的保护作用。

→ 缺点:

1.常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。

2.还有有一个非常严重的问题,那就是内存浪费问题,这个内存浪费不仅仅 因为它常驻内存,更重要的是,对闭包的使用不当会造成无效内存的产生。

→ 特性:

1. 函数嵌套函数

2. 内部函数可以访问外部函数的变量

3. 参数和变量不会被回收。

在哪里用到了闭包

1.匿名自执行函数

我们创建了一个匿名的函数,并立即执行它,由于外部无法引用它内部的变量, 因此在函数执行完后会立刻释放资源,关键是不污染全局对象。

2.结果缓存

我们开发中会碰到很多情况,设想我们有一个处理过程很耗时的函数对象,每 次调用都会花费很长时间,

那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓 存中查找,如果找不到,则进行计算, 然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可 以做到这一点,因为它不会释放外部的引用, 从而函数内部的值可以得以保留。

3.封装

4.实现类和继承

8.你理解的 JS 的继承

什么是继承?

简单说就是:在 js 中获取存在对象已有属性和方法的一种方式.下面我总结了几 个继承:

一丶原型链继承

基本原理是:将父类的实例赋值给子类的原型。

这种继承方式的缺点:子类的实例可以访问父类的私有属性,子类的实例还可以 更改该属性,这样不安全。

二丶构造函数继承

原理:在子类构造函数中,使用 call 来将子类的 this 绑定到父类中去

优点:

借用构造函数法可以解决原型中引用类型值被修改的问题;

缺点:

只能继承父对象的实例属性和方法,不能继承父对象原型属性和方法

三丶组合继承

将原型继承和借用构造函数两种方式组合起来

优点:

可以保证每个函数有自己的属性,可以解决原型中引用类型值被修改的问题;

子类的实例可以继承父类原型上面的属性和方法

缺点:

在实例化子类的过程中,父类构造函数调用了两次

四丶寄生组合式继承(推荐)

所谓寄生继承:通过 Object.create() 将子类的原型继承到父类的原型上。

特点:

这种方式的高效率体现在纸雕用了一次父类构造函数,并且因此避免了在父类的 prototype 上面创建不必要的、多余的属性。

同时,原型链还能保持不变,可以正常使用 instanceof 和 isPrototypeOf 。

开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。

五丶 class extend 继承

ES6 中有了类的概念,可以通过 class 声明一个类,通过 extends 关键字来实 现继承关系。

class 与 ES5 构造函数的主要区别:

class 只能通过 new 来调用,而构造函数则可以直接调用;

class 内部所有定义的方法,都是不可枚举的(non-enumerable)

值得注意的是:

super 关键字表示父类的构造函数,相当于 ES5 的 Parent.call(this)。

子类必须在 constructor 方法中调用 super 方法,否则新建实例时会报错。这是 因为子类没有自己的 this 对象,而是继承父类的 this 对象,然后对其进行加工, 如果不调用 super 方法,子类就得不到 this 对象。 正是因为这个原因,在子类的构造函数中,只有调用 super 之后,才可以使用 this 关键字,否则会报错。子类的 proto 属性指向父类因此,子类可以继承父类的静态方法。子类的原型 的 proto,总是指向父类的 prototype 属性

9.JS 的原型与原型链

你知道什么是原型吗?我们为什么要用原型呢?或者说原型为我们提供了什 么?

什么是原型:

Javascript 规定,每一个函数都有一个 prototype 对象属性,指向另一个对 象(原型链上面的)。

prototype(对象属性)的所有属性和方法,都会被构造函数的实例继承。这意味 着,我们可以把那些不变(公用)的属性和方法,直接定义在 prototype 对象属 性上。

prototype 就是调用构造函数所创建的那个实例对象的原型(proto)。

prototype 可以让所有对象实例共享它所包含的属性和方法。也就是说,不必 在构造函数中定义对象信息,而是可以直接将这些信息添加到原型中。

为什么要用原型:使用原型对象解决浪费内存

你了解原型链吗 你能说说 prototype 与 proto 的区别吗?

1.对象有属性__proto__,指向该对象的构造函数的原型对象。

2.方法除了有属性__proto__,还有属性 prototype,prototype 指向该方法的 原型对象

22、react 中不同组件之间如何做到数据交互?

1. 父组件向子组件通信:使用 props

2. 子组件向父组件通信:使用 props 回调

3. 跨级组件间通信:中间组件层次传递 props,使用 context 对象

4. 非嵌套组件间通信:使用事件订阅

13、说一下 Redux

Redux 三大原则

1.单一数据源:

整个应用的 state 被储存在一棵对象结构中,并且这个对象结构只存在于唯一 一个 store 中

2.State 是只读的:

redux 中的 state 只读的不可以直接修改

3.使用纯函数(reducer)来执行修改 state

为了修改了 state 数据,

redux 定义了一个 reducer 函数来完成 state 数据的修改,

reducer 会接收先前的 state 和 action,并返回新的 state

操作原理图

①、store 通过 reducer 创建了初始状态

②、component 通过 store.getState()获取到了 store 中保存的 state 挂载在了自己 的状态上

③、用户产生了操作,调用了 actions 的方法

④、actions 的方法被调用,创建了带有标示性信息的 action(描述对象)

⑤、actions 将 action 通过调用 store.dispatch 方法发送到了 reducer 中

⑥、reducer 接收到 action 并根据标识信息判断之后返回了新的 state

⑦、store 的 state 被 reducer 更改为新 state 的时候,store.subscribe 方法里的回 调函数会执行,此时就可以通知 component 去重新获取 state

两边固定,中间自适应

绝对定位法

绝对定位法原理是将左右两边使用 absolute 定位,因为绝对定位使其脱离文 档流,后面的 center 会自然流动到他们上面,然后使用 margin 属性,留出左右 元素的宽度,既可以使中间元素自适应屏幕宽度。

使用自身浮动法

自身浮动法的原理就是使用对左右使用分别使用 float:left 和 float:right,

float

使左右两个元素脱离文档流,中间元素正常在正常文档流中,使用 margin 指定 左右外边距对其进行一个定位。

圣杯布局

先定义好 header 和 footer 的样式,使之横向撑满。

在 container 中的三列设为浮动和相对定位(后面会用到),center 要放在最 前面,footer 清除浮动。

三列的左右两列分别定宽 200px 和 150px,中间部分 center 设置 100%撑 满

这样因为浮动的关系,center 会占据整个 container,左右两块区域被挤下 去了

接下来设置 left 的 margin-left: -100%;,让 left 回到上一行最左侧

但这会把 center 给遮住了,所以这时给外层的 container 设置 padding-left:

200px;padding-right: 150px;,给 left 和 right 空出位置 这时 left 并没有在最左侧,因为之前已经设置过相对定位,所以通过 left: -200px; 把 left 拉回最左侧

同样的,对于 right 区域,设置 margin-left: -150px; 把 right 拉回第一行 这时右侧空出了 150px 的空间,所以最后设置 right: -150px;把 right 区域拉 到最右侧就行了。

防抖和节流

防抖是控制次数,节流是控制频率。

在前端开发的过程中,我们经常需要绑定一些持续触发的事件,而当一个函数(事 件)被频繁的调用的时候,会造成浏览器卡顿的现象,这时就要用到防抖和节流。

防抖:

点击事件时,点多少次就会执行多少次,防抖就是让代码在最后一次点击的时候 去执行一次。(点击结束之后去执行)

例:搜索框,鼠标滚动会用到防抖

节流:

在快速点击的过程中降低日至打印的频率。(设置多长时间执行一次)

节流解决:每次触发事件前都判断当前是否有等待执行的延时函数

11、深拷贝是什么?项目哪里是用到了深拷贝?

浅拷贝:

当对某个数据(数组或对象)进行拷贝后,修改新数据(拷贝后的数据)里 面第 1 层的数据是不会影响老数据(被拷贝的数据)的,但是如果还要第 2 层 或 更深层次的数据(复杂数据类型),它仍然是有关联的,如果修改了新数据,那 么老数据也会被修改。

深拷贝:

* 就是在拷贝数据(数组或对象)时,不管数据里面有多少层,是简单 还是 复杂数据类型,只要进行深拷贝后,和老数据(之前被拷贝的数据)就毫 无关联,相互独立,互不影响!在修改新数据,对老数据毫无影响。

* 作用:打断两个对象或数组之间的引用关系!

1,在拷贝构造函数中假如只完成了数据成员本身的赋值则称为“浅拷贝”;编译 器提供的默认拷贝构造函数就已经可以完成这个任务。

而假如要复制的数据除了属性值本身以外,还要复制附加在数据属性值上的额 外内容,那就要自己来写拷贝构造函数了,来完成所谓的“深拷贝”。

把一个对象里面的每一个成员都复制一份到新的对象里面

=> 当对象中的某一个成员是复杂数据类型的时候

=> 继续循环遍历这个复杂数据类型

=> 在新的对象里面也创建一个复杂数据类型继续复制进去

实现深拷贝:通过递归函数来实现深拷贝

除了递归,我们还可以借用 JSON 对象的 parse 和 stringify

deepCopy() 自定义方法

=> 在函数内部判断, 如果你是一个对象或者数组

=> 那么就再次调用函数

举个例子:

若在构造函数中 new 了一个新的空间存放数据,并且用指针记录了首地址;若 是浅拷贝,则在拷贝构造函数中指针值将复制给另一个数据成员,这样就会有 两个指针指向同一个空间;这样的话在析构函数里将会对指针所指向的空间进 行释放,由于两个指针指向的是同一个空间,在释放第一个指针指向的空间时 不会出现什么问题,而释放第二个指针指向的空间时就会因为空间已经被解析 过而导致解析的空间不存在的情况,就会造成程序无法终止。

而解决上面这种情况的办法就是使用“深拷贝”,深拷贝是在拷贝构造函数里再 new 一个新的空间。将数据复制在新空间里,并将拷贝的指针记录这个新空间的 首地址,这样在析构函数里就不会有问题了。

2,在某些引用类型值不更新的情况下用深拷贝

17. ★★★ async 和 await 、promise 的区别 和 这两个的本质

/*---------Promise 概念:---------*/

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件—— 更合理和更强大,简单地说,Promise 好比容器,里面存放着一些未来才会执 行完毕(异步)的事件的结果,而这些结果一旦生成是无法改变的

/*---------async await 概念:---------*/

async await 也是异步编程的一种解决方案,他遵循的是 Generator 函数的语 法糖,他拥有内置执行器,不需要额外的调用直接会自动执行并输出结果,它 返回的是一个 Promise 对象。

两者的区别:

Promise 的出现解决了传统 callback 函数导致的“地域回调”问题,但它的语 法导致了它向纵向发展行成了一个回调链,遇到复杂的业务场景,这样的语法 显然也是不美观的。而 async await 代码看起来会简洁些,使得异步代码看起 来像同步代码,await 的本质是可以提供等同于”同步效果“的等待异步返回能 力的语法糖,只有这一句代码执行完,才会执行下一句。

async await 与 Promise 一样,是非阻塞的。

async await 是基于 Promise 实现的,可以说是改良版的 Promise,它不能用于普通的回调函数。

什么是 Vue.nextTick()??

定义:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使 用这个方法,获取更新后的 DOM。

所以就衍生出了这个获取更新后的 DOM 的 Vue 方法。所以放在 Vue.nextTick() 回调函数中的执行的应该是会对 DOM 进行操作的 js 代码;

理解:nextTick(),是将回调函数延迟在下一次 dom 更新数据后调用,简单的理 解是:当数据更新了,在 dom 中渲染后,自动执行该函数,

13.浏览器渲染原理,什么情况下会触发重绘重排

浏览器会把 HTML 解析成 DOM,把 CSS 解析成 CSSOM,DOM 和 CSSOM 合 并就产生了 RenderTree(渲染树)。有了 Render Tree,我们就知道了所有节点的 样式,然后计算他们在页面上的大小和位置,最后把节点绘制到页面上。

DomTree 用来存放元素,渲染树(Render Tree)用来展示元素相应的样式.

重排(回流)和重绘是什么?

1、回流:当 Render Tree 中部分或全部元素的尺寸、结构、或某些属性发生改 变时,浏览器重新渲染部分或全部文档的过程称为回流。每个页面至少需要一 次回流,就是在页面第一次加载的时候。

2、重绘:当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、 background-color、visibility 等),这些属性只是影响元素的外观,风格,而不 会影响布局的,浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重 绘。

回流必将引起重绘,而重绘不一定会引起回流。

因为:如果一个元素引发了回流,它就影响了父级以及兄弟节点的位置,它们 都要重新渲染了,所以回流必定引发重绘。

触发重排和重绘:

• 页面首次渲染

• 浏览器窗口大小发生改变

• 元素尺寸或位置发生改变

• 元素内容变化(文字数量或图片大小等等)• 元素字体大小变化

• 添加或者删除可见的 DOM 元素

减少重绘和重排:

避免频繁的样式操作,最好一次性重写 style,或者一次性更改 class,避免频繁 操作 dom,对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引 起父元素及后续元素频繁回流。

15.vue 监听不到 data 中的数组变化的情况

对于普通的 js 对象

- Vue 将遍历此对象所有的 property,

- 并使用 Object.defineProperty 把这些 property 全部转为 getter/setter,

- 使得 vue 可以在内部对这些数据进行追踪依赖, 在 property 被访问和修改时通知变更, 重新渲染相关联的组件。

关于对象

Vue 不允许动态添加根级别的响应式 property。但是我们可以利用 vue 的内置方法,

- 使用 Vue.set(object, propertyName, value)方法

- 该方法向嵌套对象添加响应式 property,此时 vue 可以监听到对象的变化。

关于数组

Vue 不能检测以下数组的变动,因为这些都是不是响应式的。

- 如利用索引直接设置一个数组项,即使用下标修改某个元素(vm.arr[indexOfItem] =

newValue)

- 直接修改数组的长度(vm.arr.length = newLength)

16.虚拟 dom 的理解

虚拟 dom 和原生 dom

/*

(1)原生 dom 是浏览器通过 dom 树渲染的复杂对象,属性非常多;

(2)虚拟 dom 是存在于内存中的 js 对象,属性远少于原生的 dom 对象,它用来描 述真实的 dom,并不会直接在浏览器中显示;

(3)原生 dom 操作、频繁排版与重绘的效率是相当低的,虚拟 dom 则是利用了计 算机内存高效的运算性能减少了性能的损耗;

(4)虚拟 DOM 进行频繁修改,然后一次性比较并修改真实 DOM 中需要改的部分, 最后并在真实 DOM 中对修改部分进行排版与重绘,减少过多 DOM 节点排版与重绘损耗

*/

虚拟 DOM 的优劣如何?实现原理?

/*

虚拟 dom 是用 js 模拟一颗 dom 树,放在浏览器内存中,相当于在 js 和真实 dom 中 加了一个缓存,利用 dom diff 算法避免了没有必要的 dom 操作,从而提高性能。

优点:

(1)虚拟 DOM 具有批处理和高效的 Diff 算法,最终表现在 DOM 上的修改只是变更 的部分,可以保证非常高效的渲染,优化性能;

(2)虚拟 DOM 不会立马进行排版与重绘操作,对虚拟 DOM 进行频繁修改,最后一 次性比较并修改真实 DOM 中需要改的部分;(3)虚拟 DOM 有效降低大面积真实 DOM 的重绘与排版,因为最终与真实 DOM 比

较差异,可以只渲染局部;

缺点:

(1)首次渲染大量 DOM 时,由于多了一层虚拟 DOM 的计算,会比 innerHTML 插入 慢;

React 组件的渲染过程:

( 1 ) 使 用 JSX 编 写 React 组 件 后 所 有 的 JSX 代 码 会 通 过 Babel 转 化 为 React.createElement 执行;

(2)createElement 函数对 key 和 ref 等特殊的 props 进行处理,并获取 defaultProps 对默认 props 进行赋值,并且对传入的子节点进行处理,最终构造成一个 ReactElement 对象(所谓的虚拟 DOM)。

(3)ReactDOM.render 将生成好的虚拟 DOM 渲染到指定容器上,其中采用了批处 理、事务等机制并且对特定浏览器进行了性能优化,最终转换为真实 DOM。

虚拟 DOM 的组成——ReactElementelement 对象结构:

(1)type:元素的类型,可以是原生 html 类型(字符串),或者自定义组件(函 数或 class)

(2)key:组件的唯一标识,用于 Diff 算法,下面会详细介绍

(3)ref:用于访问原生 dom 节点

(4)props:传入组件的 props,chidren 是 props 中的一个属性,它存储了当前 组件的孩子节点,可以是数组(多个孩子节点)或对象(只有一个孩子节点)

(5)owner:当前正在构建的 Component 所属的 Component

(6)self:(非生产环境)指定当前位于哪个组件实例

(7)_source:(非生产环境)指定调试代码来自的文件(fileName)和代码行数

(lineNumber)

*/

10、v-if 和 v-show 的区别

1、v-if 只有在判断为 true 的时候才会对数据进行渲染,false 的时候把包含的代码 进行删除。除非再次进行数据渲染,v-if 才会重新判断。可以说是用法比较倾向 于对数据一次操作。

2、v-show 是无论判断是什么都会先对数据进行渲染,只是 false 的时候对节点进 行 display.none;的操作。所以再不重新渲染数据的情况下,改变数据的值可以使 数据展示或隐藏。

使用 频繁切换时用 v-show,运行时较少改变时用 v-if

(从 Vue 源码的角度上来看,v-if 的判断应该是发生在 template 编译成 render function 的过程中)

11、vue 的生命周期,什么时候使用,哪个使用的比较频繁

常用的生命周期有,beforeCreate,

created,beforeMount,mounted,beforeUpdate,

updated,beforeDestroy,destroyed

你的接口请求一般放在哪个生命周期中?接口请求一般放在 mounted 中,但需要注意的是服务端渲染时不支持 mounted, 需要放到 created 中。

7、 怎么理解 MVVM

对 MVC,MVP,MVVM 的理解

mvc 和 mvvm 其实区别并不大。都是一种设计思想。主要就是 mvc 中 Controller 演变成 mvvm 中的 viewModel。mvvm 主要解决了 mvc 中大量的 DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。和当 Model 频 繁发生变化,开发者需要主动更新到 View 。

MVVM 是 Model-View-ViewModel 的缩写。mvvm 是一种设计思想。

1:Model 层代表数据模型,也可以在 Model 中定义数据修改和操作的业务逻 辑;View 代表 UI 组件,它负责将数据模型转化成 UI 展现出来,ViewModel 是 一个同步 View 和 Model 的对象。

2:在 MVVM 架构下,View 和 Model 之间并没有直接的联系,而是通过 ViewModel 进行交互,Model 和 ViewModel 之间的交互是双向的, 因此 View 数据的变化会同步到 Model 中,而 Model 数据的变化也会立即反应到 View 上。

3:ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而 View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只 需关注业务逻辑,不需要手动操作 DOM, 不需要关注数据状态的同步问题, 复杂的数据状态维护完全由 MVVM 来统一管理。

8、 Vue 是工作中学的还是大学课程

工作中学的 大学哪讲这些啊 大学静的都是 html、css 写静态页面 用 js 渲染都 没讲的太深

10、v-if 和 v-show 的区别

1、手段:v-if 是动态的向 DOM 树添加或者删除 DOM 元素;v-show 是通过设 置 DOM 元素的 display 样式属性控制显示和隐藏。

2、编译过程:v-if 切换有一个局部编译/卸载的过程, 切换过程中合适地销毁 和重建内部的事件监听和子组件;v-show 只是简单的基于 css 切换。

3、编译条件:v-if 是惰性的,如果初始条件为假,则什么也不做;只有在条件 第一次变为真时才开始局部编译(编译被缓存?编译被缓存后,然后再切换的 时候进行局部卸载); v-show 是在任何条件下(首次条件是否为真)都被编译, 然后被缓存,而且 DOM 元素保留

4、性能消耗:v-if 有更高的切换消耗;v-show 有更高的初始渲染消耗 使用场 景:v-if 适合运营条件不大可能改变;v-show 适合频繁切换

6、相同点:v-show 都可以动态控制着 dom 元素的显示隐藏 不同点:v-if 的 显示隐藏是将 DOM 元素整个添加或删除,v-show 的显示隐藏是为 DOM 元 素添

7、加 css 的样式 display,设置 none 或者是 block,DOM 元素是还存在的8、在渲染多个元素的时候,可以把一个 元素作为包装元素,并使用 v-if 进行 条件判断,最终的渲染不会包含这个元素,v-show 是不支持 语法

15、vue 中用过哪些性能优化,遇到的性能问题一般怎么解决,前端展示后台数

据慢的问题怎么解决方案

1、首屏加载优化

2、路由懒加载

3、开启服务器 Gzip

4、启动 CDN 加速

5、代码层面优化

6、Webpack 对图片进行压缩

7、避免内存泄漏

8、减少 ES6 转为 ES5 的冗余代码

16、怎么解决跨域问题

在 AJAX 应用环境中,由于安全的原因,浏览器不允许 XMLHttpRequest 组件请求跨域资源。在很多情况下,这个限制给我来带来的诸多不 便。很多 同行,研究了各种各样的解决方案:

1. 通过修改 document.domain 和隐藏的 IFrame 来实现跨域请求。这种 方案可能是最简单的一种跨域请求的方案,但是它同样是一种限制最大的方 案。首先,它只能实现在同一个*域名下的跨域请求;另外,当在一个页面 中还包含有其它的 IFrame 时,可能还会产生安全性异常,拒绝访问。

2.通过请求当前域 的代理,由服务器 代理去访问另一个域的资源。 XMLHttpRequest 通过请求本域内的一个服务器资源 ,将要访问的目标资源 提供给服务器,交由服务器 去代理访问目标资源。这种方案,可以实现完全 的跨域访问,但是开发,请求过程的消费会比较大。

3. 通过 HTML 中可以请求跨域资源的标签引用来达到目的,比如 Image,Script,LINK 这些标签。在这些标签中,Script 无疑是最合适的。在 请求每一个脚本资源时,浏览器都会去解析并运行脚本文件内定义的函数,或

需要马上执行的 JavaScript 代码,我们可以通过服务器返回一段脚本或 JSON 对象,在浏览器解析执行,从而达到跨域请求的目的。使用 script 标 签来实现跨域请求,只能使用 get 方法请求服务器资源。

阿里问了 ts 与 js 的不同,hooks 里的 use effect 的参数,react 代码优化的方法, 数组长度可以赋值吗,数组遍历方法有哪些以及区别,webpack 的使用,箭头题 怎么解决的,最近在看的技术书籍和新技术,umijs 了解吗,git 里的 cherry-pick 用过吗,git 平时用的指令,build 后的上线流程了解吗

Arry.isarry 判断是否是数组

object.prototype.tostring.call(obj)==='[object object]' 判断是否是对象

清除浮动

content: ".";

clear: both;

height: 0;visibility: hidden;

display: block;

数组里面是对象然后去重

简述 cookie 和 localStorage 以及 sessionStorage 的区别。

关于 cookie、sessionStorage、localStorage 三者的区别主要有以下几点:

存储大小:cookie 数据大小不能超过 4k,sessionStorage 和 localStorage 虽然也 有存储大小的限制,但比 cookie 大得多,可以达到 5M 或更大

有效时间:localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除

数据;sessionStorage 数据在当前浏览器窗口关闭后自动删除;cookie 设置的 cookie 过期时间之前一直有效,即使窗口或浏览器关闭 数据与服务器之间的交互方式,cookie 的数据会自动的传递到服务器,服务器端

也可以写 cookie 到客户端;sessionStorage 和 localStorage 不会自动把数据发给 服务器,仅在本地保存

antDesign 和 element-ui 哪个好用

我更加倾向于 elementUI, UI 上更加漂亮,使用起来更加容易上手。 一开始,我最新接触的就 是 elementUI,感觉 elementUI 这个框架更加适合于面向外部开发。而作为对比的 Ant Design, 也有一定的优势。 从功能上来讲,后者更加齐全。

遍历数组的方法

For、 while 、for…in 、for…of 、for…each 、 map、do…while

为什么使用 use Memo 记忆组件

set.state 第二个参数是用来干什么的

setState 的“异步”并不是说内部由异步代码实现,其实本身执行的过程和代码都是同步的, 只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿 到更新后的值,形式了所谓的“异步”,当然可以通过第二个参数 setState(partialState,

callback) 中的 callback 拿到更新后的结果。

git 命令

git config。配置 Git 的相关参数。Git 一共有 3 个配置文件:1.仓库级的配置文件:

在仓库的 ...

git clone。从远程仓库克隆一个版本库到本地。# 默认在当前目录下创建和版本库名

相同的文件夹并 ...

git init。初始化项目所在目录,初始化后会在当前目录下出现一个名为 .git 的目录。

# 初始化本地仓 ...

git status。查看本地仓库的状态。# 查看本地仓库的状态 $ git status # 以简短模

式查看本地仓库的

git init

# 初始化本地代码仓

git add .

# 添加本地代码

git commit -m "add local source"

# 提交本地代码

git pull origin master

# 下载远程代码

git merge master

# 合并 master 分支git push -u origin master

# 上传代码

http 状态码

1**

信息,服务器收到请求,需要请求者继续执行操作

2**

成功,操作被成功接收并处理

3**

重定向,需要进一步的操作以完成请求

4**

客户端错误,请求包含语法错误或无法完成请求

5**

服务器错误,服务器在处理请求的过程中发生了错误

状态码

含义

100

客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接

收, …

101

服务器已经理解了客户端的请求,并将通过 Upgrade ...

102

由 WebDAV(RFC ...

200

请求已成功,请求所希望的响应头或数据体将随此响应返回。 ...

400 Bad Request:表示请求报文中存在语法错误;

401 Unauthorized:未经许可,需要通过 HTTP 认证;

403 Forbidden:服务器拒绝该次访问(访问权限出现问题)

404 Not Found:表示服务器上无法找到请求的资源,除此之外,也可以在服务器

拒绝请求但不想给拒绝原因时使用;

display 有哪些属性

3、数组和字符串的相互装换

1.字符串变成数组,split

2.数组变字符串,join

11.你理解的 Promise

一、Promise 是什么?

Promise 是最早由社区提出和实现的一种解决异步编程的方案,比其他 传统的解决方案(回调函数和事件)更合理和更强大。

ES6 将其写进了语言标准,统一了用法,原生提供了 Promise 对象。

ES6 规定,Promise 对象是一个构造函数,用来生成 Promise 实例。

二、Promise 是为解决什么问题而产生的?

promise 是为解决异步处理回调金字塔问题而产生的三、Promise 的两个特点

1、Promise 对象的状态不受外界影响

1)pending 初始状态

2)fulfilled 成功状态

3)rejected 失败状态

Promise 有以上三种状态,只有异步操作的结果可以决定当前是哪一种 状态,其他任何操作都无法改变这个状态

2、Promise 的状态一旦改变,就不会再变,任何时候都可以得到这个结果,状 态不可以逆,只能由 pending 变成 fulfilled 或者由 pending 变成 rejected

四、Promise 的三个缺点

1)无法取消 Promise,一旦新建它就会立即执行,无法中途取消

2)如果不设置回调函数,Promise 内部抛出的错误,不会反映到 外部

3)当处于 pending 状态时,无法得知目前进展到哪一个阶段,是刚刚开 始还是即将完成

3、es6 新增的语法、数组方法,箭头函数等

ES6新增的常用语法. - let,

const,

export/import

(ES6的模块化),

class (类)

ES6 的新特性

const 与 let

ES6 箭头函数

for...of 循环

展开运算符

模板字符串

类和继承

解构赋值

对象简写法

剩余参数(可变参数)

参数默认值

模块化规范

ES6 箭头函数和普通函数有什么差异?

1. 相比普通函数更简洁的语法

2. 没有 this,捕获其所在上下文的 this 值,作为自己的 this 值

3. 不能使用 new,箭头函数作为匿名函数,是不能作为构造函数的,不能使用

new

4. 不绑定 arguments,用 rest 参数...解决

let test3=(...a)=>{console.log(a[1])} //22

5. 使用 call()和 apply()调用:由于 this 已经在词法层面完成了绑定,通过

call() 或 apply() 方法调用一个函数时,只是传入了参数而已,对 this 并

没有什么影响:

6. 箭头函数没有原型属性

7. 不能简单返回对象字面量

let fun5 = ()=>({ foo: x })

//如果 x => { foo: x } //则语法

出错8. 箭头函数不能当做 Generator 函数,不能使用 yield 关键字

9. 箭头函数不能换行

let a = ()

=>1; //SyntaxError: Unexpected token =>

1. 用箭头函数会遇到哪些问题。

(1) this 问题

箭头函数没有它自己的 this 值,箭头函数内的 this 值继承自外围作用域,谁定义的函数,this 指向

箭头函数要实现类似纯函数的效果,必须剔除外部状态。所以箭头函数不具备普通函数里常见的 this、

arguments 等,当然也就不能用 call()、apply()、bind() 去改变 this 的指向

对于箭头函数来说,并没有自己的 this ,它的 this 将始终指向让它生效的对象,即它的外部调用 者:

(2) arguments 关键字

在函数中,可以通过 arguments 关键字来获取到当前函数中传入的参数,但是在箭头函数中是没有 这个关键字的,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

不可以使用 yield 命令,因此箭头函数不能用作 Generator 函数。

不可以当作构造函数,也就是说,不可以使用 new 命令,否则会抛出一个错误。

4.用到哪些方法实现路由懒加载。

什么是路由懒加载?

也叫延迟加载,即在需要的时候进行加载,随用随载。

1

官方解释:

1:当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。

2:如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被 访问的时候才加载对应组件,这样就更加高效了。

1

2

官方在说什么呢?为什么需要懒加载?

1:首先,我们知道路由中通常会定义很多不同的页面。

2:这个页面这项目 build 打包后,一般情况下,会放在一个单独的 js 文件中

3:但是,如果很多的页面都放在同一个 js 文件中,必然会造成这个页面非 常大

4:如果我们一次性的从服务器中请求下来这个页面,可能会花费一定时间, 用户体验不好

5:如何避免这种情况发生呢?使用路由懒加载就可以了

1

23

4

5

继续解释原由?

1:像 vue 这种单页面应用,如果没有应用懒加载,运用 webpack 打包后的 文件将会异常的大。

2:造成进入首页时,需要加载的内容过多,时间过长,会出啊先长时间的 白屏,即使做了 loading 也是不利于用户体验。

3:而运用懒加载则可以将页面进行划分,需要的时候加载页面,可以有效 的分担首页所承担的加载压力,减少首页加载用时

1

2

3

也就是说:进入页面不用也不需要一次性加载过多资源造成加载时间过程!

路由懒加载做了什么事情?

1:主要作用是将路由对应的组件打包成一个个的 js 代码块

2:只有在这个路由被访问到的时候,才加载对应的组件,否则不加载!

1

2

即:只有在这个路由被访问到的时候,才加载对应的组件,否则不加载!

1:.如何实现路由懒加载??

vue 项目实现路由按需加载(路由懒加载)的三种方式:

1:Vue 异步组件

2:ES6 标准语法 import()---------推荐使用!!!!!

3:webpack 的 require,ensure()

1

2

3

4

2.Vue 异步加载技术

1:vue-router 配置路由,使用 vue 的异步组件技术,可以实现懒加载,此时 一个组件会生成一个 js 文件。

2:component: resolve => require(['放入需要加载的路由地址'], resolve)

1

5

3.ES6 推荐方式 imprort ()----推荐使用

1:直接将组件引入的方式,import 是 ES6 的一个语法标准,如果需要浏览 器兼容,需要转化成 es5 的语法。

2:推荐使用这种方式,但是注意 wepack 的版本>2.4

3:vue 官方文档中使用的也是 import 实现路由懒加载

4:上面声明导入,下面直接使用4.webpack 提供的 require.ensure()实现懒加载:

1:vue-router 配置路由,使用 webpack 的 require.ensure 技术,也可以实现按 需加载。

2:这种情况下,多个路由指定相同的 chunkName,会合并打包成一个 js 文 件。

3:require.ensure 可实现按需加载资源,包括 js,css 等。他会给里面 require 的文件单独打包,不会和主文件打包在一起。

4:第一个参数是数组,表明第二个参数里需要依赖的模块,这些会提前加 载。

5:第二个是回调函数,在这个回调函数里面 require 的文件会被单独打包成一 个 chunk,不会和主文件打包在一起,这样就生成了两个 chunk,第一次加载时只加 载主文件。

6:第三个参数是错误回调。

7:第四个参数是单独打包的 chunk 的文件名

4.import 和 require 的比较(了解)

1:import 是解构过程并且是编译时执行

2:require 是赋值过程并且是运行时才执行,也就是异步加载

3:require 的性能相对于 import 稍低,因为 require 是在运行时才引入模块并且还 赋值给某个变量

5.你接触过哪些浏览器,出现过哪些兼容问题,css 兼容,event 等等

一、css 兼容

1. 不同浏览器的标签默认的 margin 和 padding 不同

问题症状:随便写几个标签,不加样式控制的情况下,各自的 margin 和 padding

差异较大。

碰到频率: 100%

解决方案:

CSS 里 *{margin:0;padding:0;} 但是性能不好

一般我们会引入 reset.css 样式重置;

2. css3 新属性,加浏览器前缀兼容早期浏览器

-moz- /* 火狐浏览器 /

-webkit- / Safari, 谷歌浏览器等使用 Webkit 引擎的浏览器 /

-o- / Opera 浏览器(早期) /

-ms- / IE */

哪些 css3 属性需要加:

定义关键帧动画 @keyframes

css3 中的变形(transform)、过渡(transtion)、动画(animation)

border-radius 圆角box-shadow 盒子阴影

flex 弹性布局

3. 块属性标签 float 后,又有横行的 margin 情况下,IE 浏览器 margin 加倍的 问题

问题症状: 常见症状是 IE6 中后面的一块被顶到下一行

解决方案: 设置为 float 的 div 在 ie 下设置的 margin 会加倍。这是一个 ie6 都 存在的 bug。解决方案是在这个 div 里面加上 display:inline;

4. 设置较小高度标签(一般小于 10px),在 IE6,IE7,遨游中高度超出自己设 置高度

问题症状: 设置 div 高度小于 10px,IE6、7 和遨游里 div 的高度,超出自己设 置的 10px.

给超出高度的标签设置 overflow:hidden; 或者设置行高 line-height 小于你设置的高度。

5. 行内属性标签,设置 display:block 后采用 float 布局,又有横行的 margin 的 情况,IE6 间距 bug

问题症状: IE6 里的间距比超过设置的间距

解决方案: 在 display:block;后面加入 display:inline;display:table;

6. IE 浏览器 div 最小宽度和高度的问题

问题症状: IE 浏览器 div 最小宽度和高度不生效

IE 不认得 min-这个定义,但实际上它把正常的 width 和 height 当作有 min 的情 况来使。这样问题就大了,如果只用宽度和高度,正常的浏览器里这两个值就 不会变,如果只用 min-width 和 min-height 的话,IE 下面根本等于没有设置宽 度和高度。

比如要设置背景图片,这个最小宽度是比较重要的。要解决这个问题,可以这 样:

7. 超链接访问过后 hover 样式就不出现的问题

被点击访问过的超链接样式不在具有 hover 和 active 了,很多人应该都遇到过这

个问题,解决技巧是改变 CSS 属性的排列顺序: L-V-H-A

8. 图片默认有间距

问题症状: 几个 img 标签放在一起的时候,有些浏览器会有默认的间距,通配

符清除间距也不起作用。

解决方案: 使用 float 属性为 img 布局(所有图片左浮)

9. css hack 解决浏览器兼容性不同浏览器,识别不同的样式,csshack 本身就是处理浏览器兼容的。

下面是 css hack 写法:

background-color:yellow0; 0 是留给 ie8 的

+background-color:pink;

+ ie7 定了;

_background-color:orange; _专门留给神奇的 ie6;

二、js 兼容

1. 事件绑定

IE: dom.attachEvent();

标准浏览器: dom.addEventListener(‘click',function(event){},false);

标准浏览器采用事件捕获的方式对应 IE 的事件冒泡机制(即标准由最外元素至 最内元素或者 IE 由最内元素到最外元素)最后标准方亦觉得 IE 这方面的比较 合理,所以便将事件冒泡纳入了标准,这也是 addEventListener 第三个参数的 由来,而且事件冒泡作为了默认值第三值默认 false,表示事件冒泡方式。

如果浏览器不支持 addEventListener()方法, 你可以使用 attachEvent()方法替 代。

2. event 事件对象问题

document.οnclick=function(ev){//谷歌火狐的写法,IE9 以上支持,往下不支 持;

var e=ev;

console.log(e);