一、DOM事件模型:捕获和冒泡
1、级别
(1)DOM0:onclick事件
(2)DOM2:addEventListener事件,注册事件
(3)DOM3:鼠标事件、键盘事件
2、事件流:1、事件通过捕获到达目标元素2、目标阶段3、目标元素在上传到window对象(冒泡)
事件捕获的具体过程:
window对象接收事件->document->html(document.documentElement)->body(document.body)->…..一直传递直到目标元素
事件冒泡的具体过程:
目标元素-> … -> body -> html -> document -> window
3、event对象
preventDefault:阻止默认行为比如a,不连接
stopPropagation:阻止事件冒泡
stopImmediatePropagation:阻止其他绑定事件的执行(不会冒泡且该元素有其他事件都不会执行)
currentTarget:当前发生事件的元素(父级绑定事件,==父级的)
target:触发事件的节点(父级绑定事件,子节点触发)
4、自定义事件
<div id="ev">自定义事件</div> <script type="text/javascript"> var ev = document.querySelector('#ev'); var eve = new Event('test'); // 注册 ev.addEventListener('test', function() { // 绑定 console.log('eve event'); }); setTimeout(function() { ev.dispatchEvent(eve); // 触发 }, 1000); </script>
二、HTTP协议类
1、HTTP协议特点:无连接、无状态、简单快速、灵活
2、报文组成:请求报文(请求行(方法、地址、版本、协议)、请求头(key-value值)、空行、请求体)+响应报文(状态行、响应头、空行、响应体)
3、方法:get、post、put、delete、head
4、持久连接:从http1.1版本开始
5、管线化:将多个http请求整批提交,相应的时候整批响应
(1)在持久连接下,需要1.1支持
(2)只有get和head才能支持,post有所限制
(3)初次连接最好不要启动管线机制,防止对方服务器不支持
三、原型链
1、js创建对象方法
对象就是一个实例
<script type="text/javascript"> // 通过字面量 var o1 = {name: 'xueer'}; var o2 = new Object({name: 'xueer'}); // 通过构造函数(一个函数只要被new,就可以叫做构造函数) var M = function (name) { this.name = name; } var o3 = new M('o3'); // 通过object.create var o4 = Object.create({name: 'xueer'}); </script>
当声明一个函数时,浏览器会自动创建一个对象,这个对象就是这个函数的原型对象,这个原型对象有个constructor属性执行了这个函数。
M.prototype.constructor === M // 函数的原型对象的构造函数就是这个函数
当声明一个函数时,会有一个默认的属性prototype,prototype属性指向这个原型对象。
o3是M的实例对象,o3的__proto__指向了M的原型对象
o3.__proto__ === M.prototype
给原型对象加方法
M.prototype.say = function () { console.log('say hi'); }; var o5 = new M('o5');
2、原型链:__proto__是所有对象都拥有的属性,会形成一条由__proto__连起来的链条。
3、instanceof运算符用来检测前面的是不是后面的实例(原型对象是否在该对象的原型链上)
o3 instanceof M // o3是M的一个实例,M的原型对象在o3的原型链上
o3 instanceof Object // o3是Object的一个实例,Object的原型对象在o3的原型链上
四、js面向对象
1、声明类和实例化对象
<script type="text/javascript"> // 通过构造函数声明类 var o1 = function () { this.name = 'o1'; } // 通过es6方式声明类 class o2 { constructor () { this.name = 'o2'; } } // 实例化 console.log(new o1(), new o2()); </script>
2、实现继承
(1)通过构造函数实现继承(部分继承)
function Parent1 () { this.name = 'parent1'; } function Child1 () { Parent1.call(this); // 相当于把parent1借给了this,this就是Child1 this.type = 'child'; } console.log(new Child1);
注:并没有继承原型对象,当
Parent1.prototype.say = function () { };时,child1中没有say方法。
(2)通过原型链实现继承
function Parent2 () { this.name = 'parent2';
this.play = [1, 2, 3]}function Child2 () {this.type = 'child2';}Child2.prototype = new Parent2(); // 相当于继承,child2得实例中的__proto__就是parent2缺点:子类属性改变,父类属性也改变,因为原型对象是公用的
var s1 = new Child2(); var s2 = new Child2(); console.log(s1.play, s2.play); s1.play.push(4); // 当s1改变时,s2也改变,不独立
(3)组合方法
function Parent3 () { this.name = 'parent3'; this.play = [1, 2, 3]; } function Child3 () { Parent3.call(this); // 1次 this.type = 'child3'; } Child2.prototype = new Parent2(); // 2次
缺点:parent3的构造函数执行了两次
(4)优化
Child2.prototype = Parent2.prototype; // 将上面的一行修改为缺点:console.log(s3.constructor); === Parent3,构造方法为父类
(5)再次优化
Child5.prototype = Object.create(Parent5.prototype);
Child5.constructor = Child5;
child5的原型对象 = parent5的原型对象 = object的原型对象
五、通信类
1、同源策略及限制:从一个源(协议、域名、端口)加载的文档或脚本如何与来自另一个源的资源进行交互(跨域)
2、前后端如何通信
(1)ajax
<script> var xhr = new XMLHttpRequest(); xhr.open('post', url); xhr.send(data); // get时send(null) xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { alert(xhr.responseText); } else { alert(xhr.status.statusText); } } </script>
(2)WebScoket
(3)CORS:跨源资源共享;浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin
字段。
fetch('/test/url', { method: 'get' }).then(function (res) { }).catch(function (err) { // 出错了,等价于then的第二个参数 });
3、跨域通信的方式
(1)jsonp
定义和用法:通过动态插入一个script标签。浏览器对script的资源引用没有同源限制,同时资源加载到页面后会立即执行(没有阻塞的情况下)。
特点:通过情况下,通过动态创建script来读取他域的动态资源,获取的数据一般为json格式。
<script> function testjsonp(data) { console.log(data.name); // 获取返回的结果 } </script> <script> var _script = document.createElement('script'); _script.type = "text/javascript"; _script.src = "http://localhost:8888/jsonp?callback=testjsonp"; document.head.appendChild(_script); </script>
(2)hash
<script type="text/javascript"> // 利用hash,当前页面A,通过iframe嵌入了跨域的页面B,A到B通信 // 在A中 var B = document.getElementsByTagName('iframe'); B.src = B.src + '#' + 'data'; // 在B中 window.onhashchange = function() { var data = window.location.hash; } </script>
(3)postMessage
// 通过postMessage // 窗口A(http://A.com)向跨域的窗口B(http://B.com)发送消息 // 在A中 window.postMessage('data', 'http://B.com'); // 在B中 window.addEventListener('message', function (event) { console.log(event.origin); // http://A.com console.log(event.source); // window(A窗口的对象) console.log(event.data); // data(A窗口的) }, false);
(4)webscoket
var ws = new WebSocket('wss://echo.webscoket.org'); // 实例化,wss:与ws:区别:前面的加密 ws.onopen = function (evt) { ws.send('hello Websocket'); // 发送信息 } ws.onmessage = function (evt) { console.log('receviced message' + evt.data); // 接受信息evt.data ws.close(); // 关闭,调下面的方法 } ws.onclose = function (evt) { console.log('connection closed'); // 确认是否关闭 }
(5)cors
定义和用法:是现代浏览器支持跨域资源请求的一种最常用的方式。
使用方法:一般需要后端人员在处理请求数据的时候,添加允许跨域的相关操作。如下:
res.writeHead(200, { "Content-Type": "text/html; charset=UTF-8", "Access-Control-Allow-Origin":'http://localhost', 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', 'Access-Control-Allow-Headers': 'X-Requested-With, Content-Type' });