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,今天就先到这里。

(0)

相关推荐

  • Javascript YUI 读码日记之 YAHOO.util.Dom - Part.2 0

    batch: function(el, method, o, override) {     // 让 el 始终为 HTMLElement     el = (el && (el.tagName || el.item)) ? el : Y.Dom.get(el); if (!el || !method) {         return false;     } //  确定返回的对象     var scope = (override) ? o : window; // 看起来是个 H

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

    先绕开头部很多的 if...else (其实就是定义 toCamel 与 getStyle 两个函数) - 由于浏览器的实现不统一,才造成如此麻烦的情况,回头可以聊聊这些代码. 下面我们在 YAHOO.util.Dom 类中看看有哪些宝藏.目前思想已经逐步的分裂,我看见个函数说个函数. // 基本上可以认为是 document.getElementById 的翻版 get: function(el) {     // 如果已经是 HTMLElement ,那么就直接返回     if (el &

  • Javascript YUI 读码日记之 YAHOO.util.Dom - Part.3

    var patterns = {     HYPHEN: /(-[a-z])/i,     ROOT_TAG: /^body|html$/i }; var toCamel = function(property) {     // 如果没有 -[a-z] 字母,则直接返回     if ( !patterns.HYPHEN.test(property) ) {         return property;     } // 如果有缓存,直接返回替换后的值     if (propertyCa

  • javascript YUI 读码日记之 YAHOO.util.Dom - Part.4

    var getXY = function() {     // 判断是否是 IE     if (document.documentElement.getBoundingClientRect) {         // 注1         return function(el) {             var box = el.getBoundingClientRect(); var rootNode = el.ownerDocument;             return [box.

  • YUI 读码日记之 YAHOO.lang.is*

    YAHOO.lang = YAHOO.lang || {     isArray: function(o) {          if (o) {            var l = YAHOO.lang;            // 如果该对象有 length 这个属性,同时支持 splice 方法,            // 那么就认为它为数组.            return l.isNumber(o.length) && l.isFunction(o.splice);   

  • 学习YUI.Ext第五日--做拖放Darg&Drop

    拖放某个元素Darg&Drop是windows(视窗)问世时的一个重要特征.现在我们要在浏览器里面实现,怎么做呢?先看看基本例子: 复制代码 代码如下: YAHOO.example.DDApp = function() {      var dd;      return {          init2: function() { //   var dropzone =["dz"];  //   for(i in dropzone){  //           new YA

  • Javascript的一种模块模式

    Douglas Crockford已经传授了一个有用的单例模式(singleton pattern)实现此规则,我认为他的模式有益于你基于YUI的那些应用.Douglas叫它模块模式(module pattern).它是如下工作的: 创建一个命名空间对象:如果你使用YUI,可以用YAHOO.namespace()方法: YAHOO.namespace("myProject");这分配了一个空的myProject对象,是YAHOO的一个成员(如 果myProject已存在的话,则不会被覆

  • Javascript模块模式分析

    Douglas Crockford已经传授了一个有用的单例模式(singleton pattern)实现此规则,我认为他的模式有益于你基于YUI的那些应用.Douglas叫它模块模式(module pattern).它是如下工作的: 创建一个命名空间对象:如果你使用YUI,可以用YAHOO.namespace()方法: YAHOO.namespace("myProject");这分配了一个空的myProject对象,是YAHOO的一个成员(如 果myProject已存在的话,则不会被覆

  • js innerHTML 的一些问题的解决方法

    然而,你需要知道 innerHTML 有一些自身的问题: 1.当 HTML 字符串包含一个标记为 defer 的 script 标签(<script defer>-</script>)时,如 innerHTML 属性处理不当,在 Internet Explorer 上会引起脚本注入攻击.  2.设置 innerHTML 将会破坏现有的已注册了事件处理函数的 HTML 元素,会在某些浏览器上引起内存泄露的潜在危险. 还有几个其他次要的缺点,也值得一提的: 1.你不能得到刚刚创建的元素

  • 小议javascript 设计模式 推荐

    记得早前就说过要和大家分享"javascript设计模式",迟迟没写不是因为我懒,最近确实太忙,忙工作,忙旅游(啊哦?),好不容易这几天空闲了,接下来是兑现之前空口白话的时间了. 在讨论设计模式之前,请确认您已经有一定的脚本编程基础,如果不甚了解,建议可以先查阅本人很久之前写的这篇<浅谈javascript面向对象编程>请看下一篇文章. 讲到设计模式,不得不先重点着墨于"接口设计",因为接口设计在设计模式中的意义太大了,大于模式本身.直观起见,先介绍一下

随机推荐