一、页面布局
CSS盒模型
-
标准模型和IE模型
标准模型和IE模型的区别
标准模型计算宽高时,只包含content的宽高
IE模型计算宽高时,包含content、padding和borderCSS如何设置这两种模型
box-sizing:content-box // 设置为标准模型(浏览器默认)
box-sizing:border-box // 设置为IE模型
- JS如何设置及获取盒模型的宽和高
var dom = document.getElementById('dom')
dom.style.width/height // 普适
dom.currentStyle.width/height // 仅IE浏览器支持
window.getComputedStyle(dom).width/height // Chrome、Firefox
dom.getBoundingClientRect().width/height/left/top // 获取元素相对viewport(视窗)左上角的位置
边距重叠问题
两个兄弟盒子和包含关系的盒子,同时设置margin时,会以数值大的为主,数值小的会被忽略。解决办法是创建BFC。如何创建BFC(块级格式化上下文)
float的值不为none时;
position不为static或relative时,比如设置为absolute、fixed等
display为table时
overflow不为visible时,比如设置为hidden,scroll等
二、DOM事件
DOM事件的级别
DOM0:element.onclick = function(){} 或 <div onclick="alert('Hi~')"></div>
DOM1:没有涉及事件标准的制定
DOM2:element.addEventLister('click',function(){},false) // false 表示冒泡阶段触发
DOM3:element.addEventLister('keyup',function(){},false) // 新增了很多事件类型DOM事件模型
冒泡、捕获DOM事件流
DOM事件捕获的具体流程
window --->document--->html--->body
js中获取html节点的方法document.documentElement
Event对象的常见应用
function(event){
event.preventDefault() // 阻止事件默认行为
event.stopPropagation() // 阻止冒泡,防止事件往上传递
event.stopImmediatePropagation() // 同一个元素绑定了多个方法,这个方法可以阻止剩下未触发的事件
event.currentTarget // 当前事件实际绑定的元素
event.target // 事件代理时,实际触发事件的子元素,IE不支持
}
- 自定义事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>customEvent</title>
</head>
<style>
.target {
width: 200px;
height: 40px;
line-height: 40px;
text-align: center;
color: white;
background: red;
}
</style>
<body>
<div class="target" id="target">目标元素</div>
</body>
<script>
// 事件捕获演示
var target = document.getElementById('target')
window.addEventListener('click', function () {
console.log('window 捕获')
}, true)
document.addEventListener('click', function () {
console.log('document 捕获')
}, true)
document.documentElement.addEventListener('click', function () {
console.log('html 捕获')
}, true)
document.body.addEventListener('click', function () {
console.log('body 捕获')
}, true)
target.addEventListener('click', function () {
console.log('target 捕获')
}, true)
// 事件捕获演示
var target = document.getElementById('target')
window.addEventListener('click', function () {
console.log('window 冒泡')
}, false)
document.addEventListener('click', function () {
console.log('document 冒泡')
}, false)
document.documentElement.addEventListener('click', function () {
console.log('html 冒泡')
}, false)
document.body.addEventListener('click', function () {
console.log('body 冒泡')
}, false)
target.addEventListener('click', function () {
console.log('==== 华丽的分割线 ======')
console.log('target 冒泡')
}, false)
// 需要抛出事件的地方
var eve = new Event('myEvent')
target.addEventListener('myEvent', function () {
console.log('dispatch自定义事件')
})
setTimeout(function () { // 3s后触发事件
target.dispatchEvent(eve) // 注意这里dispatchEvent的是事件对象eve,而不是事件myEvent
}, 3000)
</script>
</html>
三、 HTTP协议
http协议是一种无连接、无状态的协议
http报文的组成部分
请求报文:请求行(协议)、请求头、空行、请求体
响应报文:状态行、响应头、空行、响应体http方法
GET:获取资源
POST:传输资源
PUT:更新资源
DELETE:删除资源
HEAD:获取报文首部GET和POST的区别
GET在浏览器回退时是无害的,而POST会再次发送请求;
GET产生的URL可以被收藏,而POST不可以;
GET请求会被浏览器主动缓存,而POST不会,除非手动设置;
GET请求只能进行url编码,而POST支持多种编码方式;
GET请求参数会被完整保留在浏览器历史记录中,而POST中的参数不会被保留;
GET请求在URL中传送的参数是有长度限制的,而POST没有限制;
GET只接受ASCII字符,而POST没有限制;
GET比POST更不安全,因为参数直接暴露在URL中,不能用来传敏感信息;
GET参数通过URL传递,POST参数放在Request body中传递;HTTP状态码
1xx:指示信息—表示请求已经接受,正在处理
2xx:成功—表示请求已经被成功接收
3xx:重定向—要完成请求必须进行更进一步的操作
4xx:客户端错误—请求有语法错误或请求无法实现
5xx:服务端错误—服务器未能实现合法的请求
例如:
200 OK : 客户端请求成功;
206 Partial Content:客户端发送了一个带有Range头的GET请求,服务器完成了它(请求音视频文件时);
301 Moved Permanently:所请求的页面已经转移到新的url;
304 Not Modified:客户端有缓存的文档发出了一个条件性的请求,服务器告诉客户端,原来的缓存的文档还可以继续使用;
400 Bad Request:客户端请求有语法错误,不能被服务器所理解;
403 Forbidden:被请求的页面禁止访问;
500 Internal Server Error:服务器发生不可预期的错误;
503 Server Unavailable:请求未完成,服务器临时过载或宕机。持久链接
普通模式:http采用“请求-->应答”模式,每次请求或者应答,客户端和服务器都要重新建立一个连接,完成后立即断开;
Keep-Alive模式:又称持久链接,连接重用,该模式使客户端到服务端的连接持久有效,当出现后继请求时,Keep-Alive功能避免建立或重连,http1.1 版本开始支持Keep-Alive模式。管线化
管线化通过持久连接完成,仅http1.1支持此技术
持久连接:请求1-->响应1-->请求2-->响应2-->请求3-->响应3
管线化:请求1-->请求2-->请求3-->响应1-->响应2-->响应3
四、原型链
- 创建对象有几种方法
// 第一种方式:字面量
var o1 = {name:'o1'}
var o2 = new Object({name:'o2'})
// 第二种方式:构造函数
function M(name){name:'03'}
var o3 = new M()
// 第三种方式:
var M = function(name){this.name=name}
var o3 = new M('o3')
// 第四种方式
var p = {name:'o4'}
var o4 = Object.create(p)
-
原型对象、构造函数、实例、原型链
原型对象:构造函数的Prototype所指的对象,原型对象的contractor属性指向构造函数
构造函数:使用new运算符操作的函数就是构造函数
实例:构造函数new出来的
instanceof的原理
instanceof通过比较实例对象__proto__
属性所指的原型和构造函数prototype
属性所指的原型,是否指向同一个原型,如果是则成立。
var M = function(name){this.name=name}
var o3 = new M('o3')
o3 instanceof M // true
o3 instanceof Object // false
// 因此,instanceof无法准确判断实例的直接构造函数
// 要准确判断,可以借助__proto__和constructor,例如:
o3.__proto__.constructor===M // true
- 使用new运算符,发生了什么?
1.创建一个新对象,它继承自foo.prototype;
2.执行构造函数,传入相应参数,上下文(this)被指定为新实例;没有参数时,则省略传参这一步,因此,没有参数时new foo 等价于 new foo();
3.如果构造函数返回了一个“对象”,则这个对象会取代new出来的结果。否则,new出来的结果为步骤1所创建的对象。
五、面向对象
<!-- 面向对象 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>OOP</title>
</head>
<body>
<div>面向对象,请打开控制台</div>
<script type="text/javascript">
// ==== 类的声明 ====
function Animal() {
this.name = 'name'
}
// ==== ES6中的class声明类 ====
class Animal2 {
constructor() {
this.name = 'name'
}
}
console.log('==== 类的声明与实例化 ====')
console.log('Animal', new Animal())
console.log('Animal2', new Animal2())
// ==== 借助构造函数实现继承(无法继承父类原型链上的属性和方法) ====
function Parent1() {
this.name = 'Parent1'
}
Parent1.prototype.p1 = 'p1'
Parent1.prototype.say = function () { console.log('Say Hi~') }
function Child1() {
Parent1.call(this) // 用apply也可以,只是传参的方式不一样
this.type = 'Child1'
}
console.log('==== 借助构造函数实现继承 ====')
console.log('Child1', new Child1)
console.log('Parent1', new Parent1)
// ==== 借助原型链实现继承 ====
function Parent2() {
this.name = 'Parent2'
this.arr = [1, 2, 3]
}
function Child2() {
this.type = 'Child2'
}
Child2.prototype = new Parent2() // Parent2的实例赋值给Child2的prototype属性
console.log('==== 借助原型链实现继承 ====')
console.log('Child2的原型链上有了Parent2的属性和方法', new Child2()) // Child2的原型链上有了Parent2的属性和方法
// 这种方法的缺点,实例共享父类的属性
var s1 = new Child2()
var s2 = new Child2()
console.log('s1.arr', s1.arr)
console.log('s2.arr', s2.arr)
s1.arr.push('4') // 改变实例1的arr值
// 改变实例1的arr值
console.log('借助原型链实现继承缺点:实例共享父类的属性')
console.log('s1.arr', s1.arr)
console.log('s2.arr', s2.arr) // s2的值也被改变了
// ==== 组合方式实现继承 ====
function Parent3() {
this.name = 'Parent3'
this.arr = [1, 2, 3]
console.log('Parent3被调用了')
}
console.log('==== 借助原型链实现继承,解决了构造函数和原型链的缺点。但是这个方法中,父类被调用了2次 ====')
function Child3() {
Parent3.call(this)
this.type = 'Child3'
}
Child3.prototype = new Parent3()
console.log('Child3', new Child3())
// ==== 组合方式实现继承优化1,解决父类被调用两次问题 ====
function Parent4() {
this.name = 'Parent4'
this.arr = [1, 2, 3]
console.log('Parent4被调用了')
}
function Child4() {
Parent4.call(this)
this.type = 'Child4'
}
Child4.prototype = Parent4.prototype
console.log('==== 组合方式实现继承优化1,解决父类被调用两次问题,但无法确定实例的直接构造函数了 =====')
console.log('Child4', new Child4())
// ==== 组合方式实现继承优化2,解决父类被调用两次问题 ====
function Parent5() {
this.name = 'Parent5'
this.arr = [1, 2, 3]
console.log('Parent5被调用了')
}
function Child5() {
Parent5.call(this)
this.type = 'Child5'
}
Child5.prototype = Object.create(Parent5.prototype) // Object.create只拷贝了原型链的部分,不包含新
Child5.prototype.constructor = Child5
console.log('==== 组合方式实现继承优化2,Object.create方法 =====')
var s7 = new Child5()
console.log('s7 instanceof Child5', s7 instanceof Child5)
console.log('s7 instanceof Parent5', s7 instanceof Parent5)
console.log('s7.__proto__.constructor === Child5', s7.__proto__.constructor === Child5)
</script>
</body>
</html>
六、通信
什么是同源策略
协议、域名、端口任何一个不一致就是跨域,同源策略是用于隔离潜在的恶意文件的关键的安全机制。同源策略有哪些限制
1.Cookie、localStorage 和 indexDB无法获取
2.DOM无法获取
3.Ajax请求不能发送前后端如何通信
1.Ajax:不支持跨域
2.WebSocket:允许跨域
3.CORS:新的通信标准,支持跨域通信和同源通信如何创建一个Ajax请求
1.XMLHttpRequest对象的工作流程
2.兼容性处理
3.事件的触发条件
4.事件的触发顺序跨域通信的集中方式
1.JSONP
window.hhh = function () { // 定义全局函数名
console.log('window.hhh')
}
var script = document.createElement('script') // 创建script标签
script.src = 'https://www.baidu.com?callback=hhh' // 向服务端传递callback名
script.onload = script.onreadystatechange = function () { // 监听onload事件
console.log('hahah')
window.hhh() // 运行服务端返回的hhh函数,格式类似:hhh({data:xxx})
}
document.body.append(script) // append到body中,发起请求
// 运行结果:
// hahah
// window.hhh
2.Hash(地址中,"#"号后面的内容,hash值改变浏览器不刷新)
3.postMessage
4.WebSocket
5.CORS(参考资料 http://www.ruanyifeng.com/blog/2016/04/cors.html)
七、安全
1.CSRF(Cross-site request forgery)跨站请求伪造
攻击原理:用户登录A网站,访问网站B,网站B伪造了一个指向A网站的GET请求并携带相关参数,此时浏览器会自动携带Cookie,A网站验证Cookie通过,并执行B网站伪造的GET请求。
防御措施:Token验证、Referer验证、隐藏令牌
2.XSS(Cross-site scripting)跨域脚本攻击
攻击原理:不需要登录,利用漏洞,执行恶意脚本。
防御措施:参考 http://www.imooc.com/learn/812
3.两者区别
XSS向页面注入脚本,在脚本中做想做的事情;CSRF利用接口漏洞,自动执行接口(一般要求用户已登录)
算法
- 排序
- 堆栈、队列、链表
- 递归
- 波兰式和逆波兰式
参考资料:https://coding.imooc.com/class/315.html
八、一道经典的题目,考考大家对布局的掌握程度
三栏布局:
- 答案:浮动、绝对定位、flex布局、表格布局、网格布局。
- 拔高点:高度未知的情况下,哪种还能用?哪种不能用了?为什么?
- 总结:语义化、代码书写规范、页面布局理解深刻、CSS基础要扎实、思维灵活且积极上进(掌握新的grid布局)
参考答案:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>layout</title>
</head>
<style>
html * {
padding: 0;
margin: 0;
}
.layout {
margin-top: 20px;
}
.layout article>div {
min-height: 100px;
}
</style>
<body>
<section class="layout float">
<style>
.left {
float: left;
width: 300px;
background: red;
}
.right {
float: right;
width: 300px;
background: blue;
}
.center {
background: green;
}
</style>
<article class="left-right-center">
<div class="left">300px</div>
<div class="right">300px</div>
<div class="center">
<h1>浮动解决方案</h1>
<p>这是内容</p>
<p>这是内容</p>
<p>这是内容</p>
</div>
</article>
</section>
<section class="layout absolute">
<style>
.layout.absolute .left-right-center>div {
position: absolute;
}
.layout.absolute .left {
left: 0;
width: 300px;
background: red;
}
.layout.absolute .center {
left: 300px;
right: 300px;
background: green;
}
.layout.absolute .right {
right: 0;
width: 300px;
background: blue;
}
</style>
<article class="left-right-center">
<div class="left">300px</div>
<div class="right">300px</div>
<div class="center">
<h1>绝对定位解决方案</h1>
<p>这是内容</p>
<p>这是内容</p>
<p>这是内容</p>
</div>
</article>
</section>
<section class="layout flexbox">
<style>
.layout.flexbox {
margin-top: 140px;
}
.layout.flexbox .left-right-center {
display: flex;
}
.layout.flexbox .left {
width: 300px;
background: red;
}
.layout.flexbox .center {
flex: 1;
right: 300px;
background: green;
}
.layout.flexbox .right {
width: 300px;
background: blue;
}
</style>
<article class="left-right-center">
<div class="left">300px</div>
<div class="center">
<h1>flexBox解决方案</h1>
<p>这是内容</p>
<p>这是内容</p>
<p>这是内容</p>
</div>
<div class="right">300px</div>
</article>
</section>
<section class="layout table">
<style>
.layout.table .left-right-center {
width: 100%;
height: 100px;
display: table;
padding: 0;
margin: 0;
}
.layout.table .left-right-center>div {
display: table-cell;
}
.layout.table .left {
width: 300px;
background: red;
}
.layout.table .center {
width: 100%;
background: green;
}
.layout.table .right {
width: 300px;
background: blue;
}
</style>
<article class="left-right-center">
<div class="left">300px</div>
<div class="center">
<h1>表格布局解决方案</h1>
<p>这是内容</p>
<p>这是内容</p>
<p>这是内容</p>
</div>
<div class="right">300px</div>
</article>
</section>
<section class="layout grid">
<style>
.layout.grid .left-right-center {
width: 100%;
height: 100px;
display: grid;
grid-template-rows: 100px;
grid-template-columns: 300px auto 300px;
}
.layout.grid .left {
background: red;
}
.layout.grid .center {
background: green;
}
.layout.grid .right {
background: blue;
}
</style>
<article class="left-right-center">
<div class="left">300px</div>
<div class="center">
<h1>网格布局解决方案</h1>
<p>这是内容</p>
<p>这是内容</p>
<p>这是内容</p>
</div>
<div class="right">300px</div>
</article>
</section>
</body>
</html>