- 标准盒模型,怪异盒模型 弹性盒模型
标准盒模型:**box-sizing:content-box;**
总宽:width+2*padding+2*border
怪异盒模型:**box-sizing:border-box;**
总宽=width;
内容区宽=总宽-2*padding-2*border
弹性盒模型: display:flex;
是父元素控制子元素(不包含孙元素以下),的布局方式
- BFC
把BFC理解成一块独立的渲染区域,BFC看成是元素的一种属性, 当元素拥有了BFC属性后,
这个元素就可以看做成隔离了的独立容器。容器内的元素不会影响容器外的元素
实现方法:
1. 浮动元素,float 除 none 以外的值
2. 定位元素,position的值不是static或者relative。
3. display 为 inline-block 、table-cell、table-caption、table、table-row、table-row-group、
4. overflow 除了 visible 以外的值(hidden,auto,scroll)
5. 根元素<html> 就是一个 BFC
作用
1.避免外边距重叠(防止margin塌陷)
2. 清除浮动
3.防止普通文档流被浮动元素遮挡(即实现多栏布局)
- 跨域
- ngix配置
- http请求状态 / 请求方式
100 继续。客户端应继续请求
200 请求成功
201 以创建,成功请求并创建新资源
202 以接受,但未处理完成
301 永久性移动
302 临时重定向 临时移动
400 客户端请求的语法错误,服务器无法理解
403 服务器理解请求客户端的请求,但是拒绝执行此请求
404 服务器无法根据客户端的请求找到资源(网页)
500 服务器内部错误,无法完成请求
501 服务器不支持请求的功能,无法完成请求
505 服务器不支持请求的HTTP协议的版本,无法完成处理
请求方式
GET 从服务器端获取数据
POST 向服务器端推送数据
PUT 向服务器上存在一些内容
Delete 删除指定的资源。
PATCH:对资源应用部分修改。
HEAD:请求一个与 GET 请求的响应相同的响应,但没有响应体。
OPTIONS:一般使用它向服务器发送一个探测性请求,如果服务器端返回了信息,说明当前客户端和服务器端建立了连接
TRACE:沿着到目标资源的路径执行一个消息环回测试
- TCP
传输控制协议(TCP,TransmissionControlProtocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC793定义。TCP旨在适应支持多网络应用的分层协议层次结构。连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务。TCP假设它可以从较低级别的协议获得简单的,可能不可靠的数据报服务。原则上,TCP应该能够在从硬线连接到分组交换或电路交换网络的各种通信系统之上操作。
TCP是一种面向广域网的通信协议,目的是在跨越多个网络通信时,为两个通信端点之间提供一条具有下列特点的通信方式:
1、基于流的方式;
2、面向连接;
3、可靠通信方式;
4、在网络状况不佳的时候尽量降低系统由于重传带来的带宽开销;
- Link @import区别用法
1.从属关系区别
@import是 CSS 提供的语法规则,只有导入样式表的作用;link是HTML提供的标签,不仅可以加载 CSS 文件,还可以定义 RSS、rel 连接属性等。
2.加载顺序区别
加载页面时,link标签引入的 CSS 被同时加载;@import引入的 CSS 将在页面加载完毕后被加载。这意味着使用link标签可以并行加载CSS文件,而@import则会阻塞页面的渲染。
<head>
<link rel=``"stylesheet"` `href=``"styles.css"``>
</head>
<style>
@import ``url``(``"styles.css"``)
</style>
- call apply bind区别
相同点:
都是动态修改this的指向;都不会修改原先函数的this指向
第一个参数都是this要指向的对象
不同点
call和apply是对函数直接调用;bind是返回一个新函数
call和bind的参数依次传参。 apply只有两个参数,以二个参数是数组
- 浏览器缓存有哪些,有什么区别
强缓存:
强缓存是指当浏览器第一次请求后,通过设置Http Header实现缓存,在缓存有效时间内,
当浏览器需要再次加载资源时不需要请求服务器,直接使用浏览器本地的缓存资源
强缓存的控制字段:
http1.0: Expires
http1.1: Cache-Control
判断过程:
请求再次发起 -> 浏览器根据 `expires` 和 `cache-control` 判断目标资源是否命中"强缓存" -> 若命中,直接从缓存获取资源,不再与服务器发生通讯。
**ache-Control**取值:
在HTTP/1.1中,`Cache-Control`是最重要的规则,主要用于控制网页缓存,主要取值为:
public:所有内容都将被缓存(客户端和代理服务器都可缓存)
private:所有内容只有客户端可以缓存,`Cache-Control`的默认取值
no-cache:客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定
no-store:所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
max-age=xxx (xxx is numeric):缓存内容将在xxx秒后失效
must-revalidate: 强制浏览器严格遵守你设置的cache规则
proxy-revalidate: 强制proxy严格遵守你设置的cache规则
协商缓存:
在浏览器端,当对某个资源的请求没有命中强缓存时,浏览器就会发一个请求到服务器,
验证协商缓存是否命中,如果协商缓存命中,请求响应返回的 HTTP 状态为 304
控制协商缓存的字段
http1.0:`Last-Modified`和`if-modified-since`
http1.1: `Etag`和`If-None-Match`、
Last-Modified 与 If-Modified-Since
`Last-Modified` 是服务器响应请求时,返回该资源文件在服务器最后被修改的时间
流程:
- 首次请求
- 服务器告知启用协商缓存规则,并在响应头中带上 `Last-Modified`,告知缓存到期时间
- 随后的每次请求,请求头上都会携带 `If-Modified-Since`,该值等于上一次响应头中的 `Last-Modified` 的值
- 服务器收到 `If-Modified-Since` 后,会将该属性的值与服务器上资源的最后修改时间进行匹配,从而判断资源是否发生了变化
- 如果发生变化会返回一个完整的响应内容,在响应头中添加新的 `Last-Modified` 值,否则,只返回 header 部分,状态码为304,响应头不会再添加 `Last-Modified`
Etag && If-None-Match
`Etag` 是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)
流程:
- 首次请求
- 服务器启用协商缓存情况下,会在响应头中带上 `Etag`
- 随后每次请求,请求头上都会带上 `If-None-Match`,该值等于上一次响应头中的 `Etag` 的值
- 服务器收到 `If-None-Match` 后,会进行比对,从而判断资源是否发生变化
- 如果变化返回一个完整响应内容,在响应头上添加新的 `Etag` 值,否则返回 304,响应头不会在添加 `Etag`
不能被缓存的请求
1. HTTP信息头中包含`Cache-Control:no-cache,pragma:no-cache(HTTP1.0)`,或`Cache-Control:max-age=0`等告诉浏览器不用缓存的请求
2. 需要根据`Cookie`,认证信息等决定输入内容的动态请求是不能被缓存的
3. 经过HTTPS安全加密的请求
4. POST请求无法被缓存
5. HTTP响应头中不包含`Last-Modified/Etag`,也不包含`Cache-Control/Expires`的请求无法被缓存
- 浏览器获取到资源后到渲染的过程
1,从输入一个网址到浏览器显示页面经历的过程
a,DNS解析,找到对应网址的IP地址
b,根据IP地址,找到对应的服务器
c,建立TCP连接(三次握手)
d,连接建立完后,发出HTTP请求
e,服务器根据请求作出HTTP响应
f,浏览器得到响应内容,进行解析与渲染,并显示出来
g,断开连接(四次挥手)
2,浏览器的渲染机制
1.解析HTML生成DOM树。
2.解析CSS生成CSS规则树。
3.将DOM树与CSS规则树合并在一起生成渲染树。
4.遍历渲染树开始布局,计算每个节点的位置大小信息。
5.将渲染树每个节点绘制到屏幕。
- div实现拐角边框高亮
利用伪元素 ::before ::after
- 自己实现弹出框剧中
一: flex布局
display: flex;
justify-content: center;
align-items: center;
二:使用绝对定位/固定定位
postiont: absolue;
top: 50%
left: 50%
transfrom: translate(-50%, -50%)
- 实现轮播图
- 微信公众号免登陆流程
- canvas
var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");
// 第一条线从 (50, 50) 处开始,至 (200, 50) 处结束。第二条线从 (50, 90) 处开始,至 (280, 120) 处结束。
ctx.moveTo(50, 50); // Begin first sub-path
ctx.lineTo(200, 50);
ctx.moveTo(50, 90); // Begin second sub-path
ctx.lineTo(280, 120);
ctx.stroke(); //结束
ctx.fillStyle = 'green';// 设置不同的颜色
ctx.fill(); // 填充
- vue生命周期
Vue2
beforeCreate( 创建前 ) setup
created ( 创建后 )
beforeMount (挂载前) onBeforeMount
Mounted (挂载后) onMounted
beforeUpdate (组件更新前) onBeforeUpdate
Updated (挂组件更新后) onUpdated
beforeDestroy (销毁前) onbeforUnmounted
destroyed(销毁后) onUnmounted
- vue数据双向绑定的原理
在vue2中:使用Object.defineProperty对象以及对象属性的劫持+发布订阅模式,
只要数据发生变化直接通知变化 并驱动视图更新。
Object.defineProperty(目标对象,属性名,修饰符);
Object.defineProperty(obj, 'nmae', {
get:() => {},
set: () => {}
})
Vue3.0中的响应式采用了ES6中的 Proxy 方法。
Proxy 对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)
let p = new Proxy(obj, {
get:(target, prop, p) => {},
set: (target, prop, p) => {}
})
proxy 是用来操作对象并且扩展对象能到,而 Object.defineProperty() 只是单纯的操作对象的属性;
Vue2.X 是用 Object.defineProperty() 实现数据响应的,但是受限于 defineProperty() 的实现,必须递归遍历至对象的最底层;
vue3.0 用 Proxy 来拦截对象,不管对目标执行任何操作,都会先通过 Proxy 的处理逻辑;
- wabpack有哪些模块以及作用
entry(入口): 入口起点开始打包,分析构建依赖图,可以定义单个或者多个
output(输出): 打包后的资源输出到哪里(位置path),以及命名规则(filename)输出格式[name].js,
表示出口的文件名和多入口的文件名保持一致,这样的话可以做到不同的页面加载不同的js页面。
Loader(加载器): webpack只能处理js/json资源,不能处理类似css/img等其他资源,所以需要通过loader支持来处理其他资源,
以下是常用的loader:
babel-loader: 转换es6,es7的语法 — 文件转换
css-loader: css文件的加载和解析 — 文件转换
less-loader: 将less转换成css — 文件转换
ts-loader: TS转JS — 文件转换
file-loader: 静态资源加载 — 文件转换
raw-loader: 静态资源内联,使用rem时,需要计算根节点的字体大小,计算rem的代码以内联脚本的形式插入html中优先执行
Plugins(插件): 插件的范围包括,从打包优化到压缩,到定义环境变量等
CommonsChunkPlugin: 将chunk相同的模块代码提取成公共Js
CleanWebpackPlugin: 清理构建目录
ExtractTextWebpackPlugin: 将css从bundle文件中提取成一个独立的css文件
CopyWebpackPlugin: 文件或者目录拷贝
minimizer: 压缩代码 ,css-minimizer-webpack-plugin 这个插件也可以用来压缩 css 文件。和 optimize-css-assets-webpack-plugin 加 cssnano 的效果是一样的。
Mode: 开发模式(development)和生产模式(production)
webpack-dev-server -----webpack开发服务器
- get post请求区别
1)post请求更安全(不会作为url的一部分,不会被缓存、保存在服务器日志、以及浏览器浏览记录中,get请求的是静态资源,则会缓存,如果是数据,则不会缓存)
(2)post请求发送的数据更大(get请求有url长度限制,http协议本身不限制,请求长度限制是由浏览器和web服务器决定和设置)
(3)post请求能发送更多的数据类型(get请求只能发送ASCII字符)
(4)传参方式不同(get请求参数通过url传递,post请求放在request body中传递)
(5)get请求的是静态资源,则会缓存,如果是数据,则不会缓存
(6)get请求产生一个TCP数据包;post请求产生两个TCP数据包(get请求,浏览器会把http header和data一并发送出去,服务器响应200返回数据;post请求,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 返回数据)
注意:在发送 POST 的时候都没有带 Expect 头,server 也自然不会发 100 continue。
- 切片上传,断点续传
- iosH5兼容处理,如页面跳转时下面出现前进后退的按钮
window.location.href="{:url('index')}";
- 百度地图使用
- 数据去重
- 移动适配
- rem 媒体查询
- rem px em区别
都是css的单位
rem是相对根节点字号的单位 1rem等于根节点(html)字号的大小
Px是屏幕的像素点 1px=1像素点
em是相对元素内的字号大小 没有设置相当于浏览器默认字号
- alt title的区别
alt图片无法显示时的替代
Title 元素的额外信息 鼠标移入显示
- 大屏开发方案
- js数据类型
- 对于前端模块化的理解,模块化的方法
- nodejs
- 实现类似百度搜索输入框的下拉数据的方案
- ssr
- 浏览器缓存
- 虚拟DOM和真实DOM的区别
Virtual DOM 只是js模拟的DOM结构。 虚拟DOM是HTML DOM的抽象 。
虚拟DOM是由js实现的避免DOM树频繁更新,通过js的对象模拟DOM中的节点,然后通过特定的render方法将它渲染成真实的节点,数据更新时,渲染得到新的 Virtual DOM,与上一次得到的 Virtual DOM 进行 diff,得到所有需要在 DOM 上进行的变更,然后在 patch 过程中应用到 DOM 上实现UI的同步更新。
虚拟DOM与真实DOM的区别(注意:需不需要虚拟DOM,其实与框架的DOM操作机制有关):
1、虚拟DOM不会进行排版与重绘操作
2、虚拟DOM进行频繁修改,然后一次性比较并修改真实DOM中需要改的部分(注意!),最后并在真实DOM中进行排版与重绘,减少过多DOM节点排版与重绘损耗
3、真实DOM频繁排版与重绘的效率是相当低的
4、虚拟DOM有效降低大面积(真实DOM节点)的重绘与排版,因为最终与真实DOM比较差异,可以只渲染局部(同2)
- docunment.ready和window.onload的作用以及区别
docunment.ready: 表示文档结构已经加载完成(不包含图片等非文字媒体文件)
window.onload: 示页面包含图片等文件在内的所有元素都加载完成
ready要比onload先执行
- url传递参数参数是路由处理方式
- async/await的优缺点
- js监听数据变化
- vue2和vue3的区别
- 浏览器从输入url到页面渲染完成经历了什么
- vue通信
- Promise.allSettled(),Promise.all(),Promise.race(),Promise.any()方法
- react合成事件和原生事件
- 数组去重
- 箭头函数,普通函数, 构造函数区别
构造函数与普通函数区别
调用方式不同,普通函数直接调用,构造函数用new调用
作用不一样,构造函数用来创建新的实例对象
this指向不同,普通函数指向window,构造函数this指向它创建的实例对象
箭头函数与普通函数区别
箭头函数都是匿名函数,普通函数可以是匿名函数
箭头函数不能使用new关键字,
箭头函数没有this,它的this指向定义它时的上下文this, this一旦捕获不能改变
普通函数this指向调用它的对象,普通函数的this可以通过call, apply, bind去改变
箭头函数不能绑定arguments,取而代之用。。。参数解决
箭头函数没有prototype原型对象
- 多维数组改变成一维数组(3种方式)
.join(',').split(',') // undefined null 会变成‘’, 数字会转成字符串,不能是引用类型数据
es6的flat()方法
递归
var arr = [1,[2,3],[4,[5,6,[7]]]]
while(arr.some(Array.isArray)){
arr = [].concat(...arr)
}
- 递归组件
- get post区别
- 文件断点续传
- useMemo 和 useCallback区别
- vue/react路由跳转的方式
- 小程序内嵌H5
- H5跳转小程序
- 生成小程序二维码
- uinapp编译小程序的注意事项
- H5和原生的交互方式
- 块元素和内元素的区别
- 剧中显示的方式
- c3动画和js动画 的比较
- vue的diff算法(vue2和vue3)
- dom绑定多个点击事件
dom.addEvenListener('click')
- 事件委托的原理以及优势
- 事件捕获和事件委托的区别
事件冒泡:目标元素事件先触发,然后父元素事件触发, 事件从目标元素向外执行,直到最外层
事件捕获:父元素事件先触发,然后目标元素事件触发,事件从最外层依次向内执行,直到到目标元素
事件委托(即事件代理),是利用事件冒泡原理,把事件监听绑定在元素的父级上。当元素被点击时,父级上绑定的点击事件就会被触发,事件触发函数里通过判断e.target上的data-name或class等标识来执行不同的逻辑。
事件委托 在外层拦截子元素的事件做集中管理
事件委托基于冒泡,对于不冒泡的事件不支持。
- 项目优化
- webpack打包速度慢优化
- webpack优化项目
- webpack 和 vite对比
webpack是一个模块打包工具
vite是一个快速、轻量级的现代Web开发构建工具
1. 底层的语言
webpack是基于node.js构建的,js是以毫计数;
vite是基于esbuild预构建依赖,esbuild是采用go语言编写的,go语言是纳秒级的
总结: 所以vite比webpack打包速度快10-100倍
2.打包过程
webpacck:分析各个模块之间的依赖=>然后进行编译打=>打包后的代码在本地服务器渲染。随着模块增多,打包的体积变大,造成热更新速度变慢。
vite:启动服务器=>请求模块时按需动态编译显示。(vite遵循的是ES Modlues模块规范来执行代码,不需要打包编译成模块即可在浏览器运行。)
总结:
vite启动的时候不需要分析各个模块之间的依赖关系、不需要打包编译。vite可按需动态编译缩减时间。当项目越复杂、模块越多的情况下,vite明显优于webpacck
3.热更新
webpacck:模块以及模块依赖的模块需重新编译
vite:浏览器重新请求该模块即可
4.使用方面
vite开箱即用,更加简单,基于浏览器esm,使得hmr更加优秀,达到极速的效果;
webpack更加灵活,api以及插件生态更加丰富。
5. 原理不同
webpack是bundle,自己实现了一套模块导入导出机制。vite是利用浏览器的esm能力,是bundless。
- websocket 和 http的区别
相同点:
都是基于TCP的可靠的传输协议,
都是应用层的协议
不同点:
1、含义不同
websocket:WebSocket是一种在单个TCP连接上进行全**双工通信**的协议。
http:超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上,是**单向的**通信协议。
2、连接方式不同
websocket:WebSocket是需要浏览器和服务器握手进行建立连接的。
http:http是浏览器发起向服务器的连接,服务器预先并不知道这个连接。
3、连接长度不同
websocket:websocket是持久连接。
http:http 是短连接(http可以通过Ajax一直发送请求和长轮询保持一段时间内的连接,但本质上还是短连接)。
4、连接状态不同
websocket:websocket是有状态的双向连接。
http:http 是无状态的单向连接。
5、协议开头不同
websocket:websocket的协议是以 ws/wss 开头。
http:http 对应的是 http/https。
联系:
WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的。
- ajax和fetch、axios三者的区别
ajax: 它的全称是:Asynchronous JavaScript And XML,翻译过来就是“异步的 Javascript 和 XML”。
简单来说,Ajax 是一种思想,XMLHttpRequest 只是实现 Ajax 的一种方式。其中 XMLHttpRequest 模块就是实现 Ajax 的一种很好的方式,这也是很多面试官喜欢让面试者手撕的代码之一。
特点: 局部刷新页面,无需重载整个页面
fetch
fetch 是在 ES6 出现的,它使用了 ES6 提出的 promise 对象。它是 XMLHttpRequest 的替代品。
fetch 是一个 API,它是真实存在的,它是基于 promise 的。
特点:
使用 promise,不使用回调函数。
采用模块化设计,比如 rep、res 等对象分散开来,比较友好。
通过数据流对象处理数据,可以提高网站性能。
axios
Axios 是一个基于 promise 封装的网络请求库,它是基于XHR进行二次封装。
所以说,Axios 可以说是 XHR 的一个子集,而 XHR 又是 Ajax 的一个子集。
特点:
从浏览器中创建 XMLHttpRequests。
从 node.js 创建 http 请求
支持 Promise API
拦截请求和响应
转换请求数据和响应数据
取消请求
自动转换 JSON 数据
客户端支持防御 XSRF
总结
ajax 一种技术统称,主要利用XHR实现网络请求
Fetch 具体API,基于promise,实现网络请求
axios 一个封装库,基于XHR封装,较为推荐使用
Ajax、Fetch、axios三者之间的关系可以用一张图来清晰的表示,如图:
- canvas 和 svg的区别
分别的作用
Canvas是用**笔刷**进行2D绘图的
SVG是用**标签**绘制矢量图的
它们都用于绘制2D图像
区别
canvas取决于分辨率。SVG与分辨率无关。
SVG是用来描述XML中2D图形的语言,canvas借助JavaScript动态描绘2D图形
Canvas是用来绘制**位图**的,而SVG是绘制**矢量图**的
SVG节点较多,渲染较慢。Canvas渲染快,但是写起来稍显复杂
SVG支持分层和事件,Canvas不支持,但是有库支持
canvas取决于分辨率。SVG与分辨率无关。
- 一个大图片显示优化
- [1, 2, 3, 4, 5, 6, 7, 8, 9] 找出和为10的数组和
function getIndexsum (a,sun) {
let j = new Set();
let arr = [];
a.map((val, i) => {
const c = sun - val;
const _i = a.indexOf(c);
if(_i > -1 && !j.has(i) && _i != i){
j.add(i);
j.add(_i);
arr.push([val, c]);
}
});
return arr;
};
74. 数字相等比较
const TOLERANCE = 1E-6
function areEqual(v1, v2, tolerance) {
return Math.abs(v1 - v2) < tolerance
}
function equal(v1, v2) {
return areEqual(v1, v2, TOLERANCE)
}
75.ie适配
## ie9以上 兼容
npm install --save-dev babel-polyfill
npm install --save core-js@3
//src/index.ts
import "babel-polyfill";
.babelrc文件
"@babel/preset-env" 修改成 ["@babel/preset-env", {"useBuiltIns": "entry"}],
.babelrc文件内容
{
"presets": [
["@babel/preset-env", {"useBuiltIns": "entry"}],
"@babel/preset-react",
"@babel/preset-typescript"
],
"plugins": [
"@babel/plugin-transform-runtime",
"react-hot-loader/babel",
"babel-plugin-styled-components",
["import", {
"libraryName": "antd",
"libraryDirectory": "es",
"style": "css"
}]
]
}
.browserlistrc 文件修改
0.25% in CN
android >= 4.4
ios >= 8
not ie <= 9
app.tsx
// import {hot} from "react-hot-loader/root"; 注释掉
最后的抛出改变
// export default hot(App);
export default App;
### 代码ie兼容
路由跳转要这样`<Link to={"/seat/editor"}><Button type={'primary'} style={{marginRight: '20px'}}>新增坐席</Button></Link>`
这样不起作用`<Button type={'primary'} style={{marginRight: '20px'}}><Link to={"/seat/editor"}>新增坐席</Link></Button>`
FormData set方法不支持,要用append方法
const imageData = new FormData();
imageData.append('key', 'seat' + new Date().getTime());
imageData.append('image', _base64ImgUtil.getBlob(canvas.current.toData()));
图片高度跟随宽度等比例改变 要加上height
max-width: 100%;
height: auto;
ie有些图片不显示 解析失败
https://www.gaitubao.com/jpg-gif-png 再次转换下图片格式
antd switch 高度问题
.ant-switch{
min-height: auto;
}
get请求中文 encodeURI() 包裹
创建文件
try {
newfile = new File([_base64ImgUtil.getBlob(canvas.current.toData())], 'seat.png', { type: "image/jpeg"});
} catch (e) {
const blod = _base64ImgUtil.getBlob(canvas.current.toData());
blod.lastModifiedDate = new Date();
blod.name = 'seat.png';
newfile = blod;
}
<!-- ie 只支持setData text-->
绑定值
e.dataTransfer.setData("text", id);
获取值
e.e.dataTransfer.getData('id') 改成 e.e.dataTransfer.getData('text')
white-space: nowrap :nowrap 不生效
解决方法:添加一行样式:
word-break: keep-all
inherit 属性不生效、避免在ie中使用该属性
includes()方法报错
解决方法:用indexOf()方法替代