css兼容性有哪几种处理方案
- CSS初始化:每个浏览器的css默认样式不尽相同,所以最简单有效的方式就是对其进行初始化(覆盖默认样式)。相信很多朋友也都写过这样的代码,在所有CSS开始前,先把marin和padding都设为0。关于浏览器CSS样式初始化,经验不丰富的话,尤其对于刚入门的小白,可能也不知道该初始化什么,这里推荐一个库给大家,
Normalize.css
- 浏览器私有属性:-webkit- ,-moz- ,-ms-等,这是我们经常在某个CSS属性前添加的一些前缀,这些就是浏览器的私有属性。-moz代表firefox浏览器私有属性, -ms代表IE浏览器私有属性, -webkit代表chrome、safari私有属性,-o代表opera私有属性。对于书写顺序一定要注意,兼容性写法放到前面,把标准写法放到最后。
- CSS hack:除了以上的默认样式覆盖及私有属性添加,有时我们还需要针对不同的浏览器甚至不同版本编写特定的CSS样式,这一过程就叫做CSS hack! CSS hack的写法大致可以归纳为以下几种:条件hack、属性级hack、选择符级hack。
例如:条件hack:主要针对IE浏览器进行一些特殊的设置
<!--[if <keywords>? IE <version>?]>
代码块,可以是html,css,js
<![endif]-->
- 自动化插件:
Autoprefixer
是一款自动管理浏览器前缀的插件,它可以解析CSS文件并且添加浏览器前缀到CSS内容里。把Autoprefixe添加到资源构建工具(如webpack)后,可以完全忘记前面的东西,只需按照最新的W3C规范来正常书写CSS,剩下的工作交给插件来处理。另外,如果项目需要支持旧版浏览器,可修改browsers参数设置。目前webpack、gulp、grunt都有相应的插件
css新增属性
- 边框属性:border-image、border-radius、box-shadow
- 背景属性:
background-size
、background-origin
(背景图片的定位区域)、background-clip
(背景绘制区域-border-box、padding-box、content-box) - 文字效果:text-shadow、word-wrap(自动换行)
- 动画效果:
transform
变换效果(属性值:transform ;transform-origin:transform-origin 属性可以设置变换的起点。默认情况下,使用元素的中心作为起点。)、animation
动画效果(animation 实现动画效果主要由两个部分组成:1、通过类似 Flash 动画中的关键帧声明一个动画;2、在 animation 属性中调用关键帧声明的动画。) - 过渡效果:transition
- 渐变
怎么理解margin越界的问题
js的继承方式有哪些
- 原型链继承
- 构造函数继承
- 组合原型链继承和借用构造函数继承
- 。。。。。待补充
深拷贝怎么实现
- JSON方式实现(使用JSON.stringify、JSON.parse)
- 用for…in实现遍历和复制
function deepCopy(obj) {
var newObj = null;
if (typeof (obj) == "object" && obj != null) {
newObj = obj instanceof Array && [] || {}
for (var i in obj) {
newObj[i] = deepCopy(obj[i])
}
} else {
newObj = obj
}
return newObj;
}
- 利用数组的Array.prototype.forEach进copy
let deepClone = function (obj) {
let copy = Object.create(Object.getPrototypeOf(obj));
let propNames = Object.getOwnPropertyNames(obj);
propNames.forEach(function (items) {
let item = Object.getOwnPropertyDescriptor(obj, items);
Object.defineProperty(copy, items, item);
});
return copy;
};
let testObj = {
name: "weiqiujuan",
sex: "girl",
age: 22,
favorite: "play",
family: {brother: "wei", mother: "haha", father: "heihei"}
}
let testRes2 = deepClone(testObj);
console.log(testRes2);
js的事件轮训机制有了解吗
异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
- 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
- 主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
- 一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
- 主线程不断重复上面的第三步
"任务队列"是一个先进先出的数据结构,排在前面的事件,优先被主线程读取。主线程的读取过程基本上是自动的,只要执行栈一清空,"任务队列"上第一位的事件就自动进入主线程。但是,由于存在后文提到的"定时器"功能,主线程首先要检查一下执行时间,某些事件只有到了规定的时间,才能返回主线程。
主线程运行的时候,产生堆(heap)和栈(stack),栈中的代码调用各种外部API,它们在"任务队列"中加入各种事件(click,load,done)。只要栈中的代码执行完毕,主线程就会去读取"任务队列",依次执行那些事件所对应的回调函数。
-
setTimeout(fn,0)
它在"任务队列"的尾部添加一个事件,因此要等到同步任务和"任务队列"现有的事件都处理完,才会得到执行。 -
nodejs
process.nextTick setImmediate
process.nextTick方法可以在当前"执行栈"的尾部----下一次Event Loop(主线程读取"任务队列")之前----触发回调函数
setImmediate方法则是在当前"任务队列"的尾部添加事件,也就是说,它指定的任务总是在下一次Event Loop时执行,这与setTimeout(fn, 0)很像
process.nextTick和setImmediate的一个重要区别:多个process.nextTick语句总是在当前"执行栈"一次执行完,多个setImmediate可能则需要多次loop才能执行完。 -
Promise.resolve()
立即resolve的Promise对象,是在本轮“事件循环”(event loop)的结束时,所以在setTimeout前发生
说说call,apply,bind
聊聊es6的promise
对象的状态不受外界影响
。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)
。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。一旦状态改变,就不会再变
,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
为什么要用async,await
- async/await总的来说,是一个优秀的异步解决方案,能解决回调地狱,async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。
- 语法简洁,使代码可读性更高
- 能使用try catch捕获异常
- async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。
进一步说,async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖。