tranform
tranform: translate(30px, 0) rotate(45deg) 和 tranform: rotate(45deg) translate(30px, 0) 有区别吗?
有区别:tranform的转换,在没有改变原点的情况下,是以元素的中心点为transfrom-origin。(默认样下)水平发方向为x轴,竖直方向为y轴
详解:CSS3 transform属性的使用
transform原理
transform的原点默认是 50% 50%
XY轴是和元素关联的,对于元素来说,永远都是不会改变的
http chunk
浏览器地址栏中输入url后发生了什么
- 浏览器进程中的网络线程请求获取到html数据后,通过IPC将数据传递给渲染器进程的主线程
- 主线程将html解析构造dom树,然后进行样式计算,根据dom树和生成好的样式生成
Layout tree
- 通过遍历
Layout tree
生成绘制顺序表,遍历Layout tree
生成Layer tree
- 然后主线程将
Layer tree
和绘制顺序一起传给合成器线程 - 合成器线程按照规则进行分图层,并把图层分为更小的图块(
tiles
)传给栅格线程 - 栅格线程进行栅格化,栅格化完成后
- 合成器线程会获得栅格化线程传过来的
draw quads
图块信息,根据这些信息合成了一个合成器帧 - 然后将该合成器帧通过IPC传回给浏览器进程
- 浏览器进程在传给GPU进行绘制,最后就展示到了我们屏幕
详细分析:浏览器如何运作-页面渲染
px的理解,dpr是怎么计算的
px: 逻辑像素。
dpr: 设备像素比。 dpr = 物理像素 / 逻辑像素
CSS中的<length>(<number> + 单位)
原型题
输出结果以及原因
Function.prototype.a = 'function';
Object.ptototype.a = 'object';
function Person () {};
let child = new Person();
console.log(child.a); // 'object'
console.log(Parent.a); // 'function'
输出结果: object 、function
原因:child自身没有a属性,就会沿原型链查找,child的__proto__属性,指向其构造函数Person的原型prototype属性,此时仍然无法查找到a属性,继续沿上查找,Person.prototype.__proto__指向Object.prototype,所以最后返回的结果是object
查找关系如下
child --> child.__proto --> Person.prototype --> Person.prototype.proto --> Object.prototype --> 返回a属性的值
详细知识点:原型和原型链
AO 和 GO
AO:Active Object 执行上下中的一个
GO:Global Object
JS预编译-执行上下文
垃圾回收机制
编程题
function timeout(time) {
return new Promise(resolve => {
setTimeout(() => {
resolve();
}, time);
});
}
const supervene = new Supervene();
function addTask(time, name) {
supervene.add(() => timeout(time)).then(() => {
console.log(`任务${name}完成`);
});
}
addTask(10000, 1); // 10000ms后输出 任务1完成
addTask(5000, 2); // 5000ms后输出 任务1完成
addTask(3000, 3); // 8000ms后输出 任务3完成
addTask(4000, 4); // 11000ms后输出 任务4完成
addTask(5000, 5); // 15000ms后输出 任务5完成
题解:
function SuperTask(maxTaskNumber = 2) {
this.tasks = [];
this.runTaskNumber = 0;
this.maxTaskNumber = maxTaskNumber;
}
SuperTask.prototype.add = function(fn) {
return new Promise(resolve => {
const task = () => {
return fn.call(null).then(() => {
resolve();
})
}
this.tasks.push(task);
this.run();
})
}
SuperTask.prototype.run = function() {
while(this.runTaskNumber < this.maxTaskNumber && this.tasks.length) {
this.runTaskNumber++;
const task = this.tasks.shift();
task().then(() => {
this.runTaskNumber--;
this.run();
})
}
}
详解:JS实现并发任务调度