YUI 读码日记之 YAHOO.util.Dom - Part.1

  先绕开头部很多的 if...else (其实就是定义 toCamel 与 getStyle 两个函数) - 由于浏览器的实现不统一,才造成如此麻烦的情况,回头可以聊聊这些代码。

  下面我们在 YAHOO.util.Dom 类中看看有哪些宝藏。目前思想已经逐步的分裂,我看见个函数说个函数。

  // 基本上可以认为是 document.getElementById 的翻版

  get: function(el) {

  // 如果已经是 HTMLElement ,那么就直接返回

  if (el && (el.nodeType || el.item)) {

  return el;

  }

  // 如果是字符串,那么就返回有这个 ID 的 Element

  if (YAHOO.lang.isString(el) || !el) {

  return document.getElementById(el);

  }

  // 看起来是个数组,循环调用自身,获取 Eelement

  if (el.length !== undefined) {

  var c = [];

  for (var i = 0, len = el.length; i < len; ++i) {

  c[c.length] = Y.Dom.get(el[i]);

  }

  return c;

  }

  return el;

  },这段代码写得非常的精妙。坦白的说,上述代码中的循环体,如果不加思索的话,恐怕就会写成

  for (var i = 0, len = el.length; i < len; ++i) {

  c[c.length] = document.getElementById(el[i]);

  }虽然也能正常工作,但是前面的判断就失去了意义。

  继续走马观花,现在看看 getElementsByClassName 的内部机制。有关 getElementsByClassName 的详细调用,可以参看 YUI 文档。

  getElementsByClassName: function(className, tag, root, apply) {

  // 获取 tag 标签,默认为所有(“*”)

  tag = tag || '*';

  // 指定跟节点名

  root = (root) ? Y.Dom.get(root) : null || document;

  if (!root) {

  return [];

  }

  // 初始化节点信息

  var nodes = [],

  elements = root.getElementsByTagName(tag),

  re = getClassRegEx(className);

  // 滤掉不符合规则的节点

  for (var i = 0, len = elements.length; i < len; ++i) {

  if ( re.test(elements[i].className) ) {

  // 你一定很奇怪为什么用 nodes.length 而不是用 i

  // 仔细考虑下 :^)

  nodes[nodes.length] = elements[i];

  // 执行回调函数

  if (apply) {

  apply.call(elements[i], elements[i]);

  }

  }

  }

  return nodes;

  },教科书式的 DOM 节点获取和过滤,初始化数据以及操作数据都显得非常的严谨而且正规,YUI 的代码让我有几分的“安全感”。类似的,再来一个 getElementsBy 函数,相应代码如下

  getElementsBy: function(method, tag, root, apply) {

  // 与上述函数相同,略

  tag = tag || '*';

  root = (root) ? Y.Dom.get(root) : null || document;

  if (!root) {

  return [];

  }

  var nodes = [],

  elements = root.getElementsByTagName(tag);

  for (var i = 0, len = elements.length; i < len; ++i) {

  // 根据自定义函数返回值判断节点的属性

  if ( method(elements[i]) ) {

  nodes[nodes.length] = elements[i];

  if (apply) {

  apply(elements[i]);

  }

  }

  }

  return nodes;

  },OK,今天就先到这里。