DOM--1 遵循最佳实践

为重用命名空间而进行规划###

    (function() {
      function $(id) {
        return document.getElementById(id);
      }
      function alertNodeName(id) {
        alert($(id).nodeName);
      }
      window.myNamespace = {};
      window.myNamespace.showNodeName = alertNodeName;
    })();

myNamespace.showNodeName(test)

通过可重用,将对象事件简单化###

(function() {
    !window.A && (window['A'] = {});
    function $() {
      var elements = [], len = arguments.length;
      for(var i = 0; i < len; i++) {
        var element = arguments[i];
        if(typeof element === 'string') {
            element = document.getElementById(element);
        }
        if(len === 1) {
            return element;
        } else {
            elements.push(element);
        }
      } 
      return elements;   
    };
    //检查兼容性
    A.isCompatible = function(other) {
      if(other === false || !Array.prototype.push || !Object.hasOwnProperty 
        || !document.createElement || !document.getElementsByTagName) {
        return false;
      }
      return true;
    };
    A.$ = $;
    A.addEvent = function(node, type, listener) {
      if(!(node = $(node))) return false;
      if(node.addEventListener) {
        node.addEventListener(type, listener, false);
        return true;
      } else if(node.attachEvent) {
        node.attachEvent('on' + type, listener);
        return true;
      }
      return false;
    };
    A.removeEvent = function(node, type, listener) {
      if(!(node = $(node))) return false;
      if(node.removeEventListener) {
        node.removeEventListener(type, listener, false);
        return true;
      } else if(node.attachEvent) {
        node.detachEvent('on' + type, listener);
        return true;
      }
      return false;
    };
    A.getByClass = function(className, tag, parent) {
      parent = parent || document;
      tag = tag || '*';
      if(!(parent = $(parent))) return false;
      var allTags = (tag === '*' && parent.all) ? parent.all : parent.getElementsByTagName(tag);
      var matchingElements = [];
      className = className.replace(/\-/g, '\\-');
      var regex = new RegExp('(^|\\s)' + className + '(\\s|$)');
      var element;
      for(var i = 0, len = allTags.length; i < len; i++) {
        element = allTags[i];
        if(regex.test(element.className)) {
            matchingElements.push(element);
        }
      }
      return matchingElements;
    };
    A.toggleDisplay = function(node, value) {
      if(!(node = $(node))) return false;
      var display = node.style.display;
      node.style.display = (display === 'none') ? (value || '') : 'none';
      return true;
    };
    A.insertAfter = function(changeNode, referenceNode) {
      if(!(changeNode = $(changeNode))) return false;
      if(!(referenceNode = $(referenceNode))) return false;
      return referenceNode.parentNode.insertBefore(changeNode, referenceNode.nextSibling);
    };
    A.removeChild = function(parent) {
      if(!(parent = $(parent))) return false;
      while(parent.firstChild) {
        parent.firstChild.parentNode.removeChild(parent.firstChild);
      }
      return parent;
    };
    A.prependChild = function(parent, newChild) {
      if(!(parent = $(parent))) return false;
      if(!(newChld = $(newChld))) return false;
      if(parent.firstChild) {
        parent.insertBefore(newChild, parent.firstChild);
      } else {
        parent.appendChild(newChild);
      }
      return parent;
    };
    A.create = function(tag, html) {
      if(!tag) return false;  
      html = html || '';
      var node = document.createElement(tag);
      node.innerHTML = html;
      return node; 
    };
  })();

javascript中常见陷阱###

  • 区分大小写
  • 单引号和双引号
    • 一般使用内嵌配合转义使用;但注意再行内的单引号必须转义
  • 换行: 在js中拼接字符串的时候
    • 在一个字符串内使用反斜杠转义符
    • 多个字符串用加号拼接
  • 不支持重载而会直接替换
    所谓重载是指编程语言根据传递的函数或方法的参数的类型和个数区别不同函数或方法的能力
  • 作用域解析和闭包
    • 作用域解析中会形成路径,用作用域链来描述;
    • 闭包是与作用域相关的概念,指内部函数即使在外部函数执行完并终止之后,仍然可以访问其外部函数的属性;
function initAnchor() {
    for(var i = 0; i < 3; i++) {
      A.addEvent('anchor' + i, 'click', function() {
        alert('My id is anchor' + i);
      });
    }
  }
  A.addEvent(window, 'load', initAnchor);

上例中,当click事件监听器被调用时,在其内部作用域没有找到i;即到外部作用域中查找;而外部i的值为3
所以这种问题常发生在被定义后不马上执行的事件上

  function initAnchor() {
    for(var i = 0; i < 3; i++) {
      registerListener(i);
    }
  }
  function registerListener(i) {
    A.addEvent('anchor' + i, 'click', function() {
      alert('My id is anchor' + i);
    });
  }
  A.addEvent(window, 'load', initAnchor);

上例中,click的监听器的外部环境变成registerListener函数,该函数在其每一个实例(每次调用该函数都会生成一个该函数的副本,以维护正确的变量作用域)的内部作用域中都维护来一个i

function initAnchor() {
    for(var i = 0; i < 3; i++) {
      (function() {
        A.addEvent('anchor' + i, 'click', function() {
          alert('My id is anchor' + i);
        });
      })(i);
    }
  }

function initAnchor() {
    for(var i = 0; i < 3; i++) {
      (function(i) {
        A.addEvent('anchor' + i, 'click', function() {
          alert('My id is anchor' + i);
        });
      })(i);
    }
  }

所以上例中第二个例子匿名函数常见的每个实例会维护i;而第一个仍然会找外部的i

  • 迭代对象
    **常会用到 if(!all.hasOwnProperty(i)) continue; **
posted @ 2015-01-29 10:51  JinksPeng  阅读(235)  评论(0编辑  收藏  举报