DOM事件、HTTP协议类、原型链、js面向对象、通信

一、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'
});

猜你喜欢

转载自blog.csdn.net/snow_small/article/details/79501505