备战校招第九天
- CSS模型
- 标准盒模型和IE盒模型
- 设置两种模型
- 获取盒模型的宽高
- BFC
- DOM事件类
- DOM事件级别
- DOM事件模型
- 事件 捕获/冒泡 流程
- Event 事件
- 原型链类
- 创建对象的几种方法
- 原型、构造函数、原型链、实例关系
- instanceof 原理
- new 运算符
- 模拟 new
CSS 盒模型
两种模型介绍
标准模型
width(总宽度) = width(内容宽度)
IE模型
width(总宽度) = width(内容宽度) + padding + border
设置两种模型
1 | /* 标准盒子模型,大多数浏览器默认设置 */ |
js获取盒模型的宽高
样式导入的方式有三种
- 通过 link 标签外联
- style标签
- 内联样式(元素内添加style属性)
dom.style.width/height
只能取出内联样式的属性,也就表示只能获取到内联属性的宽和高,对于使用其他两种方式导入获取不到
Element.currentStyle.width/height
可以获取到即使运行的结果,但只支持IE
Window.getComputedStyle(dom).width/height
等同于上面的 Element.currentStyle.width/height
,但兼容firefox、chrome
Element.getBoundingClientRect().width/height
方法返回元素的大小及其相对于视口的位置。
BFC(块格式化上下文)
与BFC相对应的还有IFC(内联格式化上下文)、GFC(网格格式化上下文 )、FFC(自适应格式化上下文)
BFC基本概念
块格式化上下文
BFC原理
- 在BFC元素垂直方向会发生边距重叠
- BFC元素的边距不会与浮动元素的边距重叠
- BFC元素是一个独立的容器,外面元素不回影响内部的元素,里面的元素也不回影响外面的元素
- 计算BFC元素高度时,浮动元素 也会参加计算
如何创建BFC
BFC使用场景
- margin 重叠问题
- 清除浮动
DOM事件类
DOM事件级别
DOM0
定义方式为 js 中的 element.onclick = function() {}
,或者在html标签中使用 onclick
属性定义。
DOM1
没有涉及和DOM事件相关的
DOM2
element.addEventListener(‘click’, function() {}, false)
DOM3
添加鼠标键盘等事件
element.addEventListener(‘keyup’, function() {}, false)
DOM事件模型
捕获
执行顺序,从上往下
定义事件时,addEventListener 的第三个参数为是否捕获事件
1
2
3element.addEventListener("click", function{
//...
}, false)
冒泡
执行顺序,从下往上
阻止继续冒泡
1
2
3
4p.addEventListener('click', function (event) {
event.stopPropagation();
console.log(1);
});
事件捕获流程
冒泡的流程与之相反
window - document - html - body - xxx - 目标元素
Event对象的常见应用
event.preventDefault()
阻止默认行为(事件)
event.stopPropagation()
阻止冒泡
event.stopImmediatePropagation()
阻止click事件冒泡,并且阻止当前元素上绑定的其他同类事件的事件监听函数的执行.
event.currentTarget
指向事件绑定的元素
event.target
事件触发的元素
自定义事件
new Event(typeArg, eventInit);
- dispatchEvent 触发事件
new CustomEvent(typeArg, customEventInit);
- dispatchEvent(event); 触发事件
原型链类
创建对象的几种方法
第一种 字面量1
var o1 = {name : 'o1'}
第二种(与第一种属于一类 )1
var o2 = new Object({name: 'o1'})
第三种 通过构造函数1
2
3
4var M = function(name) {
this.name = name
}
var o3 = new M('o3')
第四种 Object.create1
2
3
4var P = function() {
this.name = 'o4'
}
var o4 = Object.create(P)
原型、构造函数、原型链、实例关系
以上面的第三种举例
- 构造函数为 M
- 原型对象为 M.prototype
- 实例为 o3
- 原型对象的原型对象
o3.__proto__.__proto__
总结
- 对象有属性__proto__,指向该对象的构造函数的原型对象。
- 方法除了有属性__proto__,还有属性prototype,prototype指向该方法的原型对象。
mdn 总结
每个实例对象( object )都有一个私有属性(称之为
__proto__
)指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象(__proto__
) ,层层向上直到一个对象的原型对象为null
。根据定义,null
没有原型,并作为这个原型链中的最后一个环节。
instanceof 原理
mdn 文档解释这一句话解释的很清楚。
instanceof
运算符用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上。
typeof 原理
typeof
操作符返回一个字符串,表示未经计算的操作数的类型。除基本类型外,无论引用的是什么类型的对象,都会返回object
。
typeof 可能返回值的类型
类型 | 结果 |
---|---|
Undefined | "undefined" |
Null | "object" (见下文) |
Boolean | "boolean" |
Number | "number" |
BigInt(ECMAScript 2020 新增) | "bigint" |
String | "string" |
Symbol (ECMAScript 2015 新增) | "symbol" |
宿主对象(由 JS 环境提供) | 取决于具体实现 |
Function 对象 (按照 ECMA-262 规范实现 [[Call]]) | "function" |
其他任何对象 | "object" |
new 运算符
1 | var M = function(name) { |
以上代码new步骤
- 创建一个新对象,继承自
M.prototype
- 构造函数 M 执行,相应的参数传入(如果不传递参数,可以用
new M
代替new M()
)。this指向这个新实例。 - 如果构造函数没有返回对象,则默认为 new 的结果。如果构造函数返回一个对象,那么返回的这个对象取代整个 new 出来的结果。
自己动手实现 new
可以根据 new 步骤实现1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var M = function (name) {
this.name = name || "o33";
};
var P = function () {
var obj = Object.create(M.prototype);
var k = M.call(obj, ...arguments);
if(typeof k === 'object') {
return k
}else {
return obj
}
};
var o3 = new M();
console.log("o3 :>> ", o3);
var o4 = P('o4');
console.log("o4 :>> ", o4);