盘点js基本知识点(二)

DOM事件和事件监听

DOM事件可以细分为三个类型:普通型事件,捕获型事件和冒泡型事件,普通型事件就是指直接在目标元素上绑定一个事件,而捕获型事件和冒泡型事件是DOM事件流的两种方式。众所周知,DOM结构是一个树型结构,当用户触发某个事件时,先从document节点一级一级的往下传播,直到目标节点,这个事件过程就是事件捕获;事件再从目标节点一级级往上传播,直到根节点,这个过程就是事件冒泡。
在DOM标准中,是同时支持事件捕获和事件冒泡的,但IE8及以下版本只支持事件冒泡,也因此而导致了在实际开发中浏览器兼容问题。
在javascript中,有三种常用的绑定事件:在DOM元素中直接绑定,在js代码中获取目标元素绑定及通过监听事件来实现绑定。对于事件监听,W3C定义了三个事件阶段,依次是捕获阶段,目标阶段和冒泡阶段,相比其它两种,使用事件监听绑定事件需要考虑IE低级版本的兼容性。因此在PC端必须对监听器和event对象进行封装:

var EventUtils = {
    // 注册监听器
    addHandler: function(element, type, handler) {
        if(element.addEventListener) {
            element.addEventListener(type, handler, false);
        }else if(element.attachEvent) {
            element.attachEvent("on" + type, handler);
        }else{
            element["on" + type] = handler;
        }
    },
    // 移除监听器
    removeHandler: function(element, type, handler) {
        if(element.removeEventListener) {
            element.removeEventListener(type, handler, false);
        }else if(element.detachEvent) {
            element.detach("on" + type,  handler);
        }else{
            element["on" + type] = null;
        }
    },
    // 获取event对象
    getEvent: function(event) {
        return event || window.event;
    },
    // 获取target对象
    getTarget: function(event) {
        return event.target || event.srcElement;
    },
    // 阻止浏览器默认行为
    preventDefault: function(event) {
        if(event.preventDefalut) {
            event.preventDefalut();
        }else{
            window.event.returnValue = false;
        }
    },
    // 阻止浏览器冒泡
    stopPropagation: function(event) {
        if(event.stopPropagation) {
            event.stopPropagation();
        }else{
            window.event.cancelBubble = true;
        }
    }
};
浏览器对同步与异步的处理机制

javascript语言的一大特点就是单线程,同一时间内只能做一件事。既然是单线程,也就意味着多个任务时需要排队,等前一个任务执行完毕,才能开始下一个任务。一旦碰到耗时长的任务,便会阻塞后面任务的执行,这明显是不合理的。尤其对于如ajax操作从网络上获取数据,不可能每次都要等待服务器响应后才能往下执行,毕竟IO设备很慢。
因此,javascript就有了异步执行方式,即采用回调函数的方式,后一个任务不等前一个任务结束就执行,优先把同步任务处理,再执行异步任务。
异步执行的具体运行机制如下:

  • 所有的任务都在主线程上执行,形成一个执行栈。
  • 主线程之外还存在一个“任务队列”,系统会把异步任务(即回调函数中的任务)放到“任务列表”中,然后继续执行后续主线任务。
  • 一旦“执行栈”中的所有任务执行完毕,系统就会读取“任务队列”,如果此时异步任务已经结束等待状态,就会从“任务队列”中进入执行栈,恢复执行。
  • 主线程不断重复上面的第三步。
从上面的运行机制可看出几点:
  • 浏览器会优先执行所有的同步任务,即主线程任务,再执行异步任务,即回调函数中的任务。
  • “任务队列”中的任务排序是按照先到先执行原理,与主线程一致。
  • setTimeout和setInterval定时器中设置的时间值是指执行栈清空完毕隔多长时间执行。因此,回调函数并不能保证一定会在指定时间执行。
  • 后期页面上产生的事件(如点击/失焦),如果绑定了事件函数,均是添加在“任务队列”。
  • 同步执行相当于没有异步任务的异步执行。
js的四种异步模式
  • 回调函数(callback)。
  • 事件监听(Listener)。
  • 观察者模式。
  • promise对象。(bluebird, Q库)
浏览器同源策略

同源策略是浏览器的一种安全策略,是对javascript施加的安全限制,旨在禁止浏览器执行其它非同源网站的脚本。同源是指 域名,端口,协议均相同。
不同源举例:

域名不同:
http://www.begin.com 与 http://www.end.com --- 主域名不同(begin/end)
http://www.begin.com 与 http://asd.begin.com --- 子域名不同(www/asd)
端口不同
http://www.begin.com:8081 与 http://www.begin.com:3000
协议不同(http/https)
http://www.begin.com 与 https://www.begin.com
跨域

js跨域是指通过js在不同域之间进行数据传输或通信。只要域名,协议,端口有任何一个不同都可被当作不同的域。一般情况下,浏览器是不允许进行跨域的,但可通过以下几种方法解决跨域:

  • jsonp
    jsonp的基本原理: 动态添加一个script标签,因为script标签中的src属性是没有跨域限制的,因此该解决方案与ajax的XmlHttpRequest协议无关。因此,无论是原生的ajax还是jQ的ajax,其实现的方式最终都是构造script标签。
    如:

function funcJsop(json) {}

$.ajax({
    url: "http://localhost:3000/home/jsonp?name=李某某",
    dataType: "jsonp",
    jsonpCallback:"success_jsonpCallback", // 不设置默认jq返回随机生成的回调函数名
    success: function(json) {}, // 成功执行回调函数后的回调
    error: function(json){}
})

这里需要后端配合,jsonp返回的数据格式应当是“客户端传递的回调方法名称(json数据)”

  • window.name + iframe
    window有个name属性,在同一个窗口中加载的所有页面都能共享同一个window.name,每个页面都对window.name有读写权限
  • window.postMessage(message,targetOrigin)
    H5新特性,用来向其它的window对象发送消息。message-发送的消息,只能为字符串类型;targetOrigin--发送对象所在域,如果不想限定域,可以使用通配符 * 。
    接收消息的对象,可通过监听自身的message来获取消息内容,该内容储存在该事件对象的data属性中。
window.onmessage = function(event) {
    var data = event.data;
}
  • location.hash + iframe
    原理是利用location.hash来进行传值,而改变url中的hash值不会引起浏览器刷新。但需要镶套两层iframe。因为不同域的两个页面是不允许修改parent.location.hash的值,因此需要在iframe中再添加一个与主页面的域一样的iframe。
//因为parent.parent和自身属于同一个域,所以可以改变其location.hash的值
parent.parent.location.hash = self.location.hash.substring(1);
  • CORS
    通过使用自定义的响应HTTP头部让浏览器与服务器进行沟通。
Access-Control-Allow-Origin:*
Access-Control-Allow-Methods:POST,GET,UPDATE,PUT
Access-Control-Allow-Credentials:true
  • 服务器代理
    同源策略只是客户端的一种安全策略机制,在服务器端是不存在该限制的,因此可通过在服务器端获取其他域名下的数据再返回给前端,例如微信页面授权。

你可能感兴趣的:(盘点js基本知识点(二))