精通JavaScript: 分离式JavaScript开发

 

* DOM *

---------------------------------------------------------------------------

1. 遍历DOM

  1) 要注意处理空格(空格类文本占用一个节点)

  2) DOM家谱中的定位指针: 

   firstChild  <--> parentNode

   lastChild   <--> parentNode

   nextSibling <--> previousSibling

  3) 节点类型:

   --> 元素 nodeType = 1

   --> 文本 nodeType = 3

   --> 文档 nodeType = 9  在HTML文档内,即<html>元素

  4) 标准DOM方法

   document.getElementById('id');

   document.getElementsByTagName('tagName');

2. 等待HTML DOM的加载

  1) 浏览器渲染和操作的大致顺序:

    A. HTML解析完毕

    B. 外部脚本和样式表加载完毕

    C. 脚本在文档内解析并执行

    D. HTML DOM完全构造起来

    E. 图片和外部内容加载

    F. 网页完成加载

  2) 等待加载策略

    A. 等待整个页面的加载

      利用window对象的load事件绑定一个函数

      缺点: 慢! 若页面包含大量图片、视频等,需等待很长时间才能执行javascript

    B. 等待大部分DOM的加载

      在页面最后元素之前嵌入脚本(通常认为是不合理的,不推荐使用)

    C. 判断DOM何时加载完毕

      检查HTML DOM是否可用的要点:

       (1) document

       (2) document.getElementsByTagName 和 document.getElementById

       (3) document.body 额外补充(理论上使用前一个检查足够判断)

      实现:

 

      function domReady(fn){
        if(domReady.done)
          return fn();
        if(domReady.timer){
          domReady.ready.push(fn);
        }else{
          domReady.ready = [fn];
          domReady.timer = setInterval(isDOMReady, 13);
        }
      }
      function isDOMReady(){
        if(domReady.done)
          return false;
        if(document && document.getElementsByTagName 
              && document.getElementById && document.body){
          clearInterval(domReady.timer);
          domReady.timer = null;
          for(var i=0,len=domReady.ready.length; i<len; ++i)
            domReady.ready[i]();
          domReady.ready = null;
          domReady.done = true;
        }
      } 

 

3. 在HTML文档中查找元素

  1) 通过类值查找元素

  2) 使用css选择器查找元素

  3) XPath

4. 获取元素的内容

  1) 获取元素内文本

    A. 所有非Mozilla的浏览器中都有一个 innerText 属性可获取文本

    B. 元素并非直接包含文本,而是包含在一个子文本节点中

  2) 获取元素内HTML

    A. 所有现代浏览器都实现的属性: innerHTML

    B. 依赖于浏览器的实现,实现的潜在问题:

      --> 基于Mozilla的浏览器不会返回<style>元素

      --> IE返回的元素字符都是大写

      --> 只能在HTML DOM文档中使用,在XML DOM文档中返回null

5. 操作元素特性

  1) 获取和设置特性的值

    A. 兼容XML DOM的方法:  getAttribute('name');  setAttribute('value', 'zhangsan');

    B. HTML DOM文档的额外方式:  var name = elem.name;  elem.value = zhangsan;

    C. 特殊情况:  

      --> getAttribute/setAttribute对class属性不一定通用(如IE会返回null)

      --> 简单的写法应该形如: elem.className 而非 elem.class(class是js的关键字)

      --> label标签的for属性也是如此: elem.htmlFor

      --> 一些css属性: elem.style.cssFloat, elem.style.cssText

      --> 处理方式: name = {'for': 'htmlFor', 'class': 'className'}[name] || name

6. 修改DOM

  1) 创建

     document.createElement  创建新元素,它不会马上插入到DOM中

     document.createTextNode 创建文本节点

  2) 插入

     parentNode.insertBefore(nodeToInsert, beforeNode);

     不指定beforeNode时在最后插入,类似:

     parentNode.appendChild(nodeToInser);

  3) 注入

     利用innerHTML属性. 缺陷:

       --> 对于XML DOM不通用

       --> innerHTML完全删除了元素内容的任何节点,没法像DOM方法一样追加或插入

  4) 删除

     parentNode.removeChild(nodeToRemove);

 


* 事件 *

---------------------------------------------------------------------------

1. 事件简介

  1) 异步事件与线程

    JavaScript事件模型: 不使用任何线程,完全是异步的

    --> JavaScript目前不存在线程,最接近线程的是使用setTimeout()回调函数

        也就是说,js代码的执行,是阻塞的

    --> 异步回调: 当一个DOM元素触发某个特定事件时,通过一个回调函数来处理它

  2) 事件阶段

    --> 捕获: 事件会以 document => <body> => .... 的顺序捕获

    --> 冒泡: 事件处理函数反向冒泡执行

2. 常见事件特征

  1) 事件对象

    --> IE的实现与W3C规范有差别: 它使用独立的全局事件对象window.event

    --> 其他浏览器使用独立的包含事件对象的参数传递

    document.getElementById('id').onclick = function(e){

      e = e || window.event;

      //......

    };

  2) this关键字

    --> 只有部分浏览器和部分方法能正常运行并将this等同于当前元素

    --> 使用this关键字处理事件相关代码相当便利

  3) 取消事件冒泡

    --> 标准浏览器:  e.stopPropagation();

    --> IE浏览器:    window.event.cancelBubble = true;

  4) 重载浏览器的默认行为

    --> 浏览器的默认行为在捕获阶段、冒泡阶段都会发生

    --> 阻止事件冒泡或者完全没有绑定事件并不会影响默认行为的执行

    --> 阻止默认行为的途径:

         A. 标准浏览器:  e.preventDefault();

         B. IE浏览器:    window.event.returnValue = false;

    --> 防止默认行为是由浏览器决定的,未必总生效(尤其是在文本域中防止敲击和<iframe>内的行为)

3. 绑定事件监听函数

  1) 传统绑定

    目前为止,绑定事件处理函数最简单且兼容性最好的方式

      document.body.onkeypress = function(){...};

      window.onload = function(){...};

    --> 优点: A. 简单,稳定,兼容; 

              B. 处理事件时,this关键字引用的是当前元素

    --> 缺点: A. 只会在事件冒泡中运行; 

              B. 只能绑定一个事件处理函数; 

              C. 事件对象参数仅对非IE浏览器有效

  2) W3C方式

    使用: elem.addEventListener(事件名称, 处理事件的函数, 启用/禁用事件捕获的标示);

      document.getElementById('id').addEventListener('mouseover', function(e){

        this.style.border = '1px solid red';

      }, false);

    --> 优点: A. 同时支持捕获和冒泡阶段(true捕获,false冒泡);

              B. this关键字引用当前元素;

              C. 可以获取事件对象参数;

              D. 同一元素绑定多个事件时不会覆盖

    --> 缺点: IE不支持

  3) IE方式

    使用: elem.attachEvent(事件名称, 处理事件的函数);

    --> 优点: 同一元素绑定多个事件时不会覆盖

    --> 缺点: A. 仅支持事件冒泡阶段;

              B. this关键字指向window对象而非当前元素;

              C. 事件对象仅存在于window.event参数中;

              D. 事件必须以ontype的形式命名,如onclick;

              E. 仅IE可用,其他标准浏览器不支持

  4) 通用方法

function addEvent(element, type, handler){
      if(!handler.$$guid)
        handler.$$guid = addEvent.guid++;
      if(!element.events)
        element.events = {};
      var handlers = element.events[type];
      if(!handlers){
        handlers = element.events[type] = {};
        if(element['on'+type]){
          handlers[0] = element['on'+type];
        }
      }
      handlers[handler.$$guid] = handler;
      element['on'+type] = handleEvent;
    }
    addEvent.guid = 1;
    function removeEvent(element, type, handler){
      if(element.events && element.events[type]){
        delete element.events[type][handler.$$guid];
      }
    }
    function handleEvent(event){
      var returnValue = true;
      event = event || fixEvent(window.event);
      var handlers = this.events[event.type];
      for(var i in handlers){
        this.$$handleEvent = handlers[i];
        if(this.$$handleEvent(event)===false){
          returnValue = false;
        }
      }
      return returnValue;
    }
    function fixEvent(event){
      event.preventDefault = fixEvent.preventDefault;
      event.stopPropagation = fixEvent.stopPropagation;
      return event;
    }
    fixEvent.preventDefault = function(){
      this.returnValue = false;
    };
    fixEvent.stopPropagation = function(){
      this.cancelBubble = true;
    };
 

4. 事件类型

  1) 鼠标事件

  2) 键盘事件

  3) UI事件

 

你可能感兴趣的:(JavaScript)