CSS三列布局
CSS盒模型
标准模式/IE模型的区别
标准模型:Width=ContentIE模型:Width=Content+Padding+Border
CSS如何设置两种模型
box-sizing属性==content-box(标准模型,默认),border-box(IE模型)
JS如何设置获取盒模型对应的宽和高
1)domElem.style.width/height//只能取到内联样式的宽和高)domElem.curntStyle.width/height//获取到即时的宽和高,但只有IE支持,通用使用第三种)window.getComputedStyle(domElem).width/height4)domElem.getBoundingClientRect().width/height//根据视窗,计算元素绝对位置,还可获取top和left
实例:根据盒模型解释边距重叠
当两个垂直外边距相遇时,它们将形成一个外边距。合并后的外边距的高度等于两个发生合并的外边距的高度中的较大者一个元素包含在另一个元素中时(假设没有内边距或边框把外边距分隔开),它们的上和/或下外边距也会发生合并只有普通文档流中块框的垂直外边距才会发生外边距合并。行内框、浮动框或绝对定位之间的外边距不会合并。
BFC(边距重叠解决方案)
基本概念:块级格式化上下文
渲染规则:
BFC元素的垂直方向的边距会发生重叠BFC区域不会与浮动元素的Box重叠(可用于清除浮动)BFC是一个独立的容器,外面的元素不会影响里面的元素,里面的元素也不会影响外面的元素计算BFC高度时,浮动元素也会参与计算创建BFC:
float值不为noneposition值不为static/lativeoverflow值不为visible(等于auto/hidden)display值为table-cell实例:BFC垂直方向重叠问题(创建包裹div,设置overflow属性为hidden)
sectionp1/pdivstyle="overflow:hidden"p/p/divp/p/section{margin:0;padding:0;}#margin{background:pink;overflow:hidden;}#marginp{background:d;margin:5pxauto5px;}
实例:两栏浮动布局,高度较低一侧会被侵染
sectiondivclass="left"/divdivclass="right"/div/section{margin:0;padding:0;}#layout{background:d;}#layout.left{background:pink;width:px;height:px;float:left;}#layout.right{background:#ccc;height:px;overflow:auto;}
实例:清除浮动(BFC即使子元素是浮动元素,高度也会参与计算)
sectiondiv我是浮动元素/div/section{margin:0;padding:0;}#float{background:d;//overflow:auto;float:left;}#float.float{float:left;font-size:0px;}
原型链
创建对象的几种方法
字面量
varo1={name:o1};varo11=newObject({name:o11});
构造函数
varM=function(){this.name=o;}varo=newM();
Object.cate
varP={name:o};varo=Object.cate(P);
原型链概念
原型链是JS实现类与继承的基础,从实例对象向上找,直Object.prototype(原型链顶端)函数都具有prototype属性,构造函数的prototype属性指向原型对象,该原型对象的constructor属性指回构造函数
Func.prototpye.constructor===Func;//true
实例对象的__proto__属性指向构造函数的原型对象
obj.__proto__===Func.prototype;//true
函数也具有__proto__属性(函数也是对象),指向Function的原型对象,说明该函数的构造函数Function
Func.__proto__===Function.prototype;//true
instanceof的原理
判断实例对象的__proto__和构造函数的prototype是否是同一引用AinstanceofB:查看对象B的prototype属性指向的原型对象是否在对象A的原型链上,若在则返回true,若不在则返回false
new运算符
一个新对象被创建,它继承自Func.prototype(构造函数的原型对象)构造函数Func被执行,相应的参数被传入,上下文(this)会被指定为这个新实例若构造函数Func返回一个“对象”,那么这个对象会取代整个new出来的结果;若构造函数Func没有返回“对象”,那么new出来的结果为步骤1创建的对象。
//实现方法_new,模拟new的作用function_new(f){//返回一个functionturnfunction(){varobj={"proto":f.prototype};f.apply(obj,arguments);turnobj;}}//测试functionPerson(name,age){this.name=name;this.age=age;}varpp=_new(Person)("Jialin",5);ppinstanceofPerson;//true;
//使用Object.cate模拟new方法var_new=function(func){varobj=Object.cate(func.prototype);vark=func.call(obj);if(typeofk===object){turnk;}else{turnobj;}}
面向对象
借助构造函数实现继承(部分继承)
缺点:该方法无法继承父类的原型方法
functionPant(){this.name=pant;this.arr=[1];}functionChild(){Pant.call(this);this.type=child;}
借助原型链实现继承
缺点:原型链中的原型对象是共用的(同一对象)
functionPant(){this.name=pant;this.arr=[1,,];}functionChild(){this.type=child;}Child.prototype=newPant();varc1=newChild();varc=newChild();console.log(c1.arr);//[1,,]c1.arr.push(4);console.log(c.arr);//[1,,,4]c1.proto===c.proto;//true
组合方式
缺点:父类构造函数执行了次,子类的protype被修改(共用),继而子类的构造函数将指向父类构造函数(子类的原型方法也丢失)
functionPant(){this.name=pant;this.arr=[1,,];}functionChild(){Pant.call(this);this.type=child;}Child.prototype=newPant();varcc=newChild();cc.constructor;//Pant(){...}
优化1:将父类构造函数的执行次数减少至1次
functionPant(){this.name=pant;this.arr=[1,,];}functionChild(){Pant.call(this);this.type=child;}Child.prototype=Pant.prototype;varcc=newChild();cc.constructor;//Pant(){...}
优化:使用Object.cate创建Child.prototype,之后再修改子类原型的constructor
functionPant(){this.name=pant;this.arr=[1,,];}functionChild(){Pant.call(this);this.type=child;}Child.prototype=Object.cate(Pant.prototype);Child.prototype.constructor=Child;
原型式继承
该方法借助原型可以基于已有的对象创建新对象,从而不必因此创建自定义类型
functionobject(o){functionF(){};F.prototype=o;turnnewF();}复制代码
Object.cate()规范了原型式继承
寄生式继承
创建一个仅仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后返回对象
functioncateAnother(originalObj){varclone=object(originalObj);clone.sayHi=function(){//...}turnclone;}
DOM事件
DOM事件类
DOM0
element.onclick=function(){}
DOM
//WCelement.addEventListener(click,function(){},false);//IEelement.attachEvent(click,function(){},false);
DOM(增加了许多事件)
element.addEventListener(keyup,function(){},false);
DOM事件捕获/冒泡过程
window==document==html(通过document.docuemntElement获得)==...==目标元素反向为冒泡
Event对象的常见应用
event.pventDefault();表示阻止默认事件event.stopPropagation();表示阻止冒泡行为event.stopImmediatePropagation();应用于:事件响应的优先级,场景:一个按钮绑定两个click事件A和B,要求让点击A时,不执行Bevent.curntTarget;表示:当前绑定事件的对象,恒等于this,特殊情况:在父子嵌套关系中,父元素绑定了事件,单击子元素,此时,curntTarget指向的是父元素(因为它是绑定事件的对象);此时,target指向了子元素(因为它是触发事件的具体对象)event.target;表示:触发事件的某个具体对象
//IEevent.sourceElement
自定义事件(无需使用回调)
使用Event类,但是只能指定事件名称,无法添加数据
vareve=newEvent(custom);ev.addEventListener(custom,function(){console.log(custom);});//触发ev.dispatchEvent(eve);复制代码
使用CustomEvent不但可以指定事件名称,还可以指定一个object类型的参数
类型转换
7种数据类型
Boolean,Null,Undefined,Number,String,SymbolObject
显示类型转换
Number函数
//原始类型数值==原始值字符串==数值(空字符为0)orNaN布尔值==true为1,false为0undefined==NaNnull==0
对象,先调用该对象自身的valueOf方法,
若返回原始类型的值,则执行Number方法转换;若返回符合类型的值,调用自身的toString方法,若返回原始类型的值,使用Number方法转换若仍返回复合类型的值,则报错失败
varobj={a:1};console.log(Number(obj));其中,obj.valueOf()返回{a:1},{a:1}的toString()返回[objectObject]
String函数
//原始类型数值==对应字符串字符串==原始值布尔值==true变为true,false变为falseundefined==undefinednull==null
复合类型,先调用该对象自身的toString方法,
若返回原始类型的值,则执行String方法转换;若返回符合类型的值,调用自身的valueOf方法,若返回原始类型的值,使用String方法转换若仍返回复合类型的值,则报错失败复制代码Boolean函数
//原始类型undefined,null,-0,+0,NaN,空字符串均转为false
隐式类型转换
四则运算判断语句Native调用console.log自动转换为字符串alert自动转换为字符串
常见题目
[]+[]==[]+{}=={}+[]==0
第一个大括号被作为代码块若被console.log()包括的话结果为[objectObject]
{}+{}=="[objectObject][objectObject]"true+true==1+{a:1}==
typeof返回值
undefined,boolean,number,string,symbolfunction,object
设计模式
单例模式观察者模式适配器模式工厂模式
通信类
同源*策及其限制
源:协议+域名+端口Cookie、LocalStorage和IndexDB无法读取DOM无法获取Ajax无法请求
补充:cookie,localStorage和sessionStorage区别复制代码
前后端如何通信
Ajax(同源下通信方式)WebSocket(不受同源策略限制)CORS(支持跨域,支持同源)Fetch(兼容性不好)
如何创建Ajax
XHR对象的工作流程兼容性处理(IE,FiFox)事件触发条件事件的触发顺序
varxhr=XMLHttpRequest?newXMLHttpRequest():newwindow.ActiveXObject(Microsoft.XMLHTTP);vardata=opt.data;varurl=opt.url;vartype=opt.type.toUpperCase();vardataArr=[];for(varkindata){dataArr.push(k+=+data[k]);}if(type===GET){url=url+?+dataArr.join();xhr.open(type,url.place(/?$/g,),true);xhr.send();}if(type===POST){//第三个参数:默认为true,表示异步发送xhr.open(type,url,true);xhr.setRequestHeader(Content-type,application/x-