内心os:
1.准备充分
2.知识系统
3.沟通简洁
4.内心诚实
5.态度谦虚
6.回答灵活
一面:
1.页面布局
H5最大的特点就是标签语义化,可以使我们和浏览器更好的理解结构与阅读
解决方式:5种
1.float
2.position
3.flexbox
4.table
5.网格布局
1.float详解
Layout
浮动解决方案
1.这是三栏布局中间部分
1.这是三栏布局中间部分
优点:兼容性很好
缺点:浮动是脱离文档流,如果处理不好,会产生很多的局限。
文档流详解:本来这个标签是属于文档流管理的,那么它应该按照文档流的正常布局方式从左至右从上之下,并且符合标签本身的含义。
脱离文档流是指,这个标签脱离了文档流的管理。不受文档流的布局约束了,并且更重要的一点是,这个标签在原文档流中所占的空间也被清楚掉了。
2.position
绝对定位解决方案
1.这是三栏布局中间部分
1.这是三栏布局中间部分
好处:快捷,不容易出问题
缺点:因为绝对定位本身脱离了文档流,这就要求下面的子元素也要脱离文档流,它的有效性不是很好
3.flexbox
flexbox解决方案
1.这是三栏布局中间部分
1.这是三栏布局中间部分
移动端很多都使用,基本比较完美
flex https://www.jianshu.com/p/37f950238261
这里flex:1 和 flex:2 甚至 flex:10 都是一样的
4.table
表格解决方案
1.这是三栏布局中间部分
1.这是三栏布局中间部分
优点:兼容性很好
缺点:当3栏布局中,有一栏的布局,高度增加的时候,其他2个也会同步增加。这个也不算缺点,只是有点局限,根据情况自行使用。
5.grid(网格)
网格解决方案
1.这是三栏布局中间部分
1.这是三栏布局中间部分
相当于栅格布局,还是比较完美,
question2:
如果去掉高度已知,哪个布局不再适用:
float position 网格
页面布局小结:
1.语义化掌握到位
2.页面布局理解深刻
3.css基础知识扎实
4.第思维灵活 积极上进
5.代码书写规范
2.CSS盒模型
2.1基本概念:标准模型+IE模型
2.2标准模型和IE模型的区别
标准模型是content的width height
IE模型是 border+padding+content
2.3CSS如何设置这两种模型
通过设置box-sizing:content-box;(标准,浏览器默认)
box-sizing:border-box; (IE)
来区分两种模型
2.4JS如何获取盒模型对应的宽和高
- dom.style.width/height (只能取到内联样式)
- dom.currentSytle.width/height
这个是等到浏览器渲染后,再去取当前dom节点的宽和高,这个是比较准确的,但是有一个缺点,现在只有IE支持。
3.window.getComputedStyle(dom).width/height
原理相似,只是这个兼容性更好
4.dom.getBoundingClientRect().width/height
同2,3 计算一个元素的绝对位置 能拿到4个 left top width height
2.5实例题 根据盒模型解释边距重叠
100px 为子元素的高度
问父模型的高度
父模型的高度是100px 还是110px?
这个还是要看父模型的盒模型
这种情况父元素的height为100px;
如果在#sec中加了overflow:hidden;
父元素的height变成了110px;
BFC的概念 块级格式化上下文
IFC 内联元素的格式化上下文(问的比较少)
BFC的原理就是BFC渲染规则:
1.在BFC这个元素的垂直方向的边距会发生重叠
2.BFC的这个区域不会与浮动元素的box重叠 (这个是用来清除浮动 和布局的)
3.BFC在页面上是个独立的容器,里面的不会影响外面,外面的不会影响里面。
4.计算BFC元素高度时,浮动元素也会参与计算
如何创建BFC:
overflow:hidden
1.float值不为none 设置浮动-->创建BFC
2.position值不为position: relative或者position: static; -->就为创建了BFC
3.display为
display: table;
display: table-caption;
display: inline-table;
或者table-其他的 都为创建了BFC
4.只要不是overflow:visible;其他的都视为创建了BFC
2.6BFC(边距重叠解决方案)
BFC使用场景:
在这里,因为父元素是BFC:overflow:hidden,所以在BFC这个元素的垂直方向的边距会发生重叠。如何解决?
1
3
这里给p元素加一个父盒子,然后在父盒子中加了overflow:hidden 让父元素成为了BFC 可以解决p标签垂直方向边距重叠问题
这里将right div变为BFC float就不会重叠 跑过去 填左边那缺少的10px
我是浮动元素
让子元素为BFC的时候,父元素的高度不再为0px,会加上子元素的高度。
3.DOM事件
基本概念:DOM事件的级别
false用于判断捕获还是冒泡
dom1 没有跟事件相关的 所以这里跳过dom1
dom3增加了很多事件,比如:鼠标事件 键盘事件
DOM事件模型 (捕获+冒泡)
DOM事件流
大白话来解释事件流:浏览器在当前这个页面,也用户做交互的时候,比如说,我点击了鼠标左键,这个左键传递到你的页面上。这就是个事件流。
一个完整的事件流分3个阶段:
1.捕获
2.目标阶段 比如我点了个按钮,这个按钮就是目标阶段
事件通过捕获,到达目标元素,这个就是目标阶段。
3.从目标元素上传到window对象,这就是冒泡
捕获---->目标元素---(上传到window 事件)--->冒泡
描述DMO事件捕获的具体流程
捕获 就是从上-->下
冒泡的流程 刚好完全相反
如何获取html? 很简单 document.documentelement
Event对象的常见应用
1.捕获跟冒泡的事件流程
2.怎么去注册事件 监听用户的交互行为
3.响应的时候
event.preventDefault()
作用:阻止默认事件
event.stopPropagation()
作用:阻止冒泡
event.stopImmediatePropagation()
作用:事件响应优先级 比如有2个事件,a和b,如果在a里面添加了这个,那么响应的时候,就会执行a不执行b;
paragraph
很多时候面试的时候会问一个问题:
用for循环给很多li加上点击事件,如何优化这种情况?
这个时候,可以回答使用事件代理,给li的父元素加上一个点击事件,然后当它的子元素得到点击的时候,再去寻找相应的子元素。
如何找到相应的子元素?event.target
事件代理 ---> targe 当前被点击
currentTarget当前被绑定的事件 也就是那个父元素
这篇文章写的比较详细:
https://www.cnblogs.com/liugang-vip/p/5616484.html
自定义事件
customEvent和event都是自定义事件,区别在于:customEvent可以加参数
模拟捕获过程:
鼠标元素
冒泡 反之
模拟自定义事件:
在这里模拟customEvent:
//customEvent
var myEvent=new CustomEvent("userLogin",{
detail:{
username:"zhangjing"
}
});
ev.addEventListener('userLogin',function(e){
console.log(e.detail.username)
})
ev.dispatchEvent(myEvent);
输出结果:
zhangjing
4.HTTP协议
HTTP协议的主要特点
简单快速:因为为http中每一个资源 也就是uri的是固定的,比如一个页面一张图片都是固定的,叫做统一资源符(uri),所以要访问就很轻松快速。
灵活:它在头部有一个数据类型,通过一个http协议可以完成不同的数据类型的传输。
无连接:连接一次就会断掉 不会保存连接
无状态:不能区分2次连接者的身份
HTTP报文的组成部分
请求行包含什么?HTTP方法、页面地址、HTTP协议、版本
请求头包含什么?key value值 告诉服务端 我要的内容需要注意什么格式,协助客户端对服务器的请求
空行:区分请求头跟请求体
请求体:请求的东西
响应实例:
响应行:
响应头:
HTTP方法
POST和GET的区别
get请求在url中传送的参数 一般<2kb 不要拼接太长,太长了服务器会截断,然后http就没法发出去,导致错误。
HTTP状态码
401 一般来说该错误消息表明您首先需要登录(输入有效的用户名和密码)。 如果你刚刚输入这些信息,立刻就看到一个 401 错误,就意味着,无论出于何种原因您的用户名和密码其中之一或两者都无效(输入有误,用户名暂时停用等) 。
403被禁止 也可表示资源不可用
什么是持久连接
http1.1版本才支持
什么是管线化
->表示没有断开
重点:1.2.3
5.原型链
原型链
输出结果:
注意:
任何一个函数 只要被new了 就可以被称为构造函数
for example:var o2=new M(); -》M是一个构造函数
强调:
函数才有prototype 对象是没有prototype的
只有对象才有proto 函数既是函数 也是对象 js万物皆对象
用constructor去判断o3是谁的实例 比 用instanceof判断更加准确。instanceof会将一整条原型链上的 都判断为true。
// 第三种方式:object.create
var p={name:'p'};
//Object.create 创造的o4是通过原型链 来连接的
var o4=Object.create(p);
m.prototype.say=function(){
console.log('say hi');
}
var o5=new m();
//new 背后的工作原理
var new2=function(func){
var o=Object.create(func.prototype);
var k=func.call(o);
if(typeof k ==='object'){
return k
}else{
return o
}
}
6.面向对象
面向对象
输出结果
继承的本质就是原型链
js的继承有几种方式,优缺点?
//借助构造函数实现继承(部分继承)
function parent1(){
this.name='parent1';
}
parent1.prototype.say=function(){
this.say='123';
}
function child1(){
//实现继承 将父级元素的this指向子构造函数上去
parent1.call(this);//apply 皆可
this.type='child1';
}
console.log(new child1())
它的本质是将父元素的this指向子元素的构造函数上,并没有通过原型链,所以他只能部分继承,child1没有继承say方法。
//借助原型链实现继承
function parent2(){
this.name='parent2';
}
function child2(){
this.type='child2';
}
child2.prototype=new parent2();
console.log(new child2());
console.log(new child2().__proto__);
输出
缺点:
先用代码演示一遍:
首先 我们在父级构造函数中加一个play属性
function parent2() {
this.name = 'parent2';
this.play = [1, 2, 3]
}
然后new 2个实例对象出来
var s1 = new child2();
var s2 = new child2();
console.log(s1.play, s2.play);
s1.play.push(4);
这时候我们在console去看一下
改变s1的同时 s2也得到了改变 为什么呢?
因为他们俩的 “proto”都是new出来的parent2对象,根据原型链,找到play,并且push一个4 ,所以所有都会变
但是不会改变父构造函数。
如果再加上这句:
s2.play.push(5);
//组合方式
function parent3(){
this.name='parent3';
this.play=[1,2,3];
}
function child3(){
parent3.call(this);
this.type='child3';
}
child3.prototype=new parent3();
var s3=new child3();
var s4=new child3();
s3.play.push(4);console.log(s3.play,s4.play);
优点:结合了构造函数继承和原型链继承的优缺点,比较完美
缺点:new了2次parent3 将parent3实例化了2次 2次的意义不大,浪费资源
//组合继承的优化
function parent4(){
this.name='parent4';
this.play=[1,2,3];
}
function child4(){
parent4.call(this);
this.type='child4';
}
child4.prototype=parent4.prototype;
var s5=new child4();
var s6=new child4();
console.log(s5,s6);
console.log(s5 instanceof child4,s5 instanceof parent4);
console.log(s5.constructor,child4.constructor);
优点:解决了上一个问题 不再new2次
缺点:他们的constructor指向的同一个构造函数,无法区分是又子类创建的还是由父类创建的
//组合继承优化2
function parent5(){
this.name='parent5';
this.play=[1,2,3];
}
function child5(){
parent5.call(this);
this.type='child5';
}
child5.prototype=Object.create(parent5.prototype);
//观察__.proto__,以下为优化步骤
child5.prototype.constructor=child5;
var s7=new child5();
console.log(s7 instanceof child5,s7 instanceof parent5);
console.log(s7.constructor);
输出:
在执行优化步骤之前:
执行之后:
完美解决。
Q4:typeof 和 instanceof 区别。
A:
typeof 的返回值为‘number’,‘string’,’boolean’,’function’,’undefined’,’object’。所以在判断数组时,返回值为 ‘object’;
instanceof 是判断变量是否为某个对象的实例,返回值布尔值。
7.通信 跨域+普通前后端
IndexDB利用数据键(key)访问,通过索引功能搜索数据,适用于大量的结构化数据,如日历,通讯簿或者记事本。
一个源包含什么?协议+域名+端口(默认端口:80)
这3个当中 如果有一个不一样,那就是跨域通信
不是同一个源的文档 无法去操作另一个源的文档或者资源
这里的限制有这么几个:
1.ajax是同源下面的通信
2.websocket 是没有限制的 就是不受同源限制
3.cors 支持跨域,支持同源
XMLHttpRequest只有高级浏览器才支持 IE是不支持的 所以要考虑兼容性的处理
手写ajax,第一版本:
function ajax(url, fnSucc, fnFaild) {
//1.创建Ajax对象
if(window.XMLHttpRequest) { //该判断是为了兼容ie6
var oAjax = new XMLHttpRequest();
} else {
var oAjax = new ActiveXObject("Microsoft.XMLHTTP");
};
//2.连接服务器
//open(方法,文件名,异步传输)
//'a.txt?t='+new Date().getTime()可以组织缓存
oAjax.open('GET', url, true);
//3.发送请求
oAjax.send();
//4.接收返回
oAjax.onreadystatechange = function() {
// oAjax.readyState //服务器和浏览器,进去到哪一步了
if(oAjax.readyState == 4) {
if(oAjax.status == 200) {
fnSucc(oAjax.responseText);
} else {
if(fnFaild) {
fnFaild(oAjax.status);
}
}
}
}
}
readyState的5个状态码:
0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可以在客户端调用了
版本二,详细版本:
if(opt.url){
var xhr=XMLHttpRequest?new XMLHttpRequest():new window.ActiveXObject('Microsoft.XMLHTTP');
var data=opt.data,
url=opt.url;
type=opt.type.toUpperCase(),
dataArr=[];
for(var k in data){
dataArr.push(k+'='+data[k]);
}
if(type==='GET'){
url=url+'?'+dataArr.join('&');
xhr.open(type,url.replace(/\?$/g,''),true);
xhr.send();
}
if(type==='POST'){
xhr.open(type,url,true);
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xhr.send(dataArr.join('&'));
}
xhr.onload=function(){
//206 适用于媒体资源 可以再加一个xhr.status===206
if(xhr.status===200||xhr.status===304){
var res;
if(opt.success&&opt.success instanceof Function){
res=xhr.responseText;
if(typeof res==='string'){
res=JSON.parse(res);
opt.success.call(xhr,res);
}
}
}else{
if(opt.error && opt.error instanceof Function){
opt.error.call(xhr,res);
}
}
}
}
框架下 如何使用ajax
1.jquery
$.ajax({
type: 'POST',
url: url,
data: data,
success: success,
dataType: dataType
});
2.mui下的
mui.ajax('http://server-name/login.php',{
data:{
username:'username',
password:'password'
},
dataType:'json',//服务器返回json格式数据
type:'post',//HTTP请求类型
timeout:10000,//超时时间设置为10秒;
headers:{'Content-Type':'application/json'},
success:function(data){
//服务器返回响应,根据响应结果,分析是否登录成功;
...
},
error:function(xhr,type,errorThrown){
//异常处理;
console.log(type);
}
});
jsonp应该接触的都比较多了
很简单,就是利用 并提供一个回调函数来接收数据(函数名可约定,或通过地址参数传递)。 第三方产生的响应为json数据的包装(故称之为jsonp,即json padding),形如: callback({"name":"hax","gender":"Male"}) 这样浏览器会调用callback函数,并传递解析后json对象作为参数。本站脚本可在callback函数里处理所传入的数据。 补充:“历史遗迹”的意思就是,如果在今天重新设计的话,也许就不会允许这样简单的跨域了嘿,比如可能像XHR一样按照CORS规范要求服务器发送特定的http头。
hash是什么?就是你url地址中#后面的东西 hash的变动页面不会刷新 这就是用hash做页面快通讯的一个原理 hash改变 页面不刷新
search是url中?后面的东西,search改变,页面是会刷新的 search不能做快通讯
postMessage H5中新增的处理快通讯
websocket 不收同源限制
CORS支持跨域通讯的ajax 大白话来理解就是:浏览器在识别你发送了一个ajax的跨域请求的时候,它会在你的http头中加一个origin来允许跨域通信。这就是cors,如果是普通的ajax的话,如果要跨域请求的时候,浏览器就会把你拦截了。
jsonp的原理是什么?
这里data=name 这一块可要可不要 主要是要把callback=jsonp 然后jsonp是个本地的全局函数 执行了script的时候就会去找jsonp这一块。
var util = {};
//在页面中注入js脚本
util.createScript = function(url, charset) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
charset && script.setAttribute('charset', charset);
script.setAttribute('src', url);
//script标签异步执行
script.async = true;
return script;
}
util.jsonp = function(url, onsuccess, onerror, charset) {
//告诉它回调名称
var callbackName = util.getName('tt_player');
//在全局注册这么个回调函数
window[callbackName] = function() {
if(onsuccess && util.isFunction(onsuccess)) {
onsuccess(arguments);
}
}
//动态创建script标签
var script = util.createScript(url + '&callback=' + callbackName, charset);
//script加载
script.onload = script.onreadystatechange = function() {
if(!script.readyState || /loaded|complete/.test(script.readyState)) {
script.onload = script.onreadystatechange = null;
// 移除该script的 DOM 对象
if(script.parentNode) {
script.parentNode.removeChild(script);
}
// 删除函数或变量
window[callbackName] = null;
}
};
script.onerror = function() {
if(onerror && util.isFunction(onerror)) {
onerror();
}
};
//向html中增加这个标签
document.getElementsByTagName('head')[0].appendChild(script);
}
使用jsonp的例子:
$.ajax({
type: "get",
async: false,
url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
dataType: "jsonp",
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
success: function(json){
alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');
},
error: function(){
alert('fail');
}
});
这里针对ajax与jsonp的异同再做一些补充说明:
1、ajax和jsonp这两种技术在调用方式上”看起来”很像,目的也一样,都是请求一个url,然后把服务器返回的数据进行处理,因此jquery和ext等框架都把jsonp作为ajax的一种形式进行了封装。
2、但ajax和jsonp其实本质上是不同的东西。ajax的核心是通过XmlHttpRequest获取非本页内容,而jsonp的核心则是动态添加
Hash:
// 利用hash,场景是当前页面 A 通过iframe或frame嵌入了跨域的页面 B
// 在A中伪代码如下:
var B = document.getElementsByTagName('iframe');
B.src = B.src + '#' + 'data';
// 在B中的伪代码如下
//当hash变化的时候
window.onhashchange = function () {
var data = window.location.hash;
};
postMessage:
// postMessage
// 窗口A(http:A.com)向跨域的窗口B(http:B.com)发送信息
Bwindow.postMessage('data', 'http://B.com');
// 这里的data一般是string字符串, 'http://B.com'是源,也可以用*,*代表任意的都可以,但是不安全,不建议使用
// 在窗口B中监听
Awindow.addEventListener('message', function (event) {
console.log(event.origin);
console.log(event.source);
console.log(event.data);
}, false);
websocket:
// Websocket【参考资料】http://www.ruanyifeng.com/blog/2017/05/websocket.html
var ws = new WebSocket('wss://echo.websocket.org');
//wss 用于加密
ws.onopen = function (evt) {
console.log('Connection open ...');
ws.send('Hello WebSockets!');
};
ws.onmessage = function (evt) {
console.log('Received Message: ', evt.data);
ws.close();
};
ws.onclose = function (evt) {
console.log('Connection closed.');
};
CORS:
// CORS【参考资料】http://www.ruanyifeng.com/blog/2016/04/cors.html
// url(必选),options(可选)
fetch('/some/url/', {
method: 'get',
}).then(function (response) {
}).catch(function (err) {
// 出错了,等价于 then 的第二个参数,但这样更好用更直观
});
8.安全 xss
用户--登录--->网站A 然后 网站A---下发cookie--->用户
这个过程就是一个网站登录验证的过程
这个用户必须要登录过
会产生csrf:
1.网站中某个接口有问题
2.用户在该网站登录过
token验证:
比如:用户要去访问一个网站,然后服务器那边会自动给出一个token,这时候就不止是cookie还有token,如果想上一个环节那样,引诱用户去点一个链接,这个链接只会自动携带cookie而不会携带token,就避免了那个攻击。
referer验证:referer指的就是页面来源,服务器可以判断来的这个页面是不是我的站点下的页面,如果是,我就执行你的这个动作,如果不是,一律拦截,这样也可以避免攻击。
隐藏令牌:类似token,只是它放的比较隐蔽,比如说我隐藏在http head头中,而不会放在链接上,这样比较隐蔽。
攻击原理:就是注入js脚本,找各种合法路径,然后给你注入js脚本。
防御措施:就是让xss不执行。
xss跟crfs的区别:
xss是向你的页面注入js脚本运行,在js函数体里面去做它想做的事情。
crfs是利用你本身漏洞,帮你去执行那些接口,且依赖于用户必须要登录注册该网站。
9.算法
堆栈 先进后出 队列 先进先出