`
meladet
  • 浏览: 27256 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

YUI Tree入门(二)各类Node详细分析

阅读更多
   之前简单介绍过TreeView的使用,现在来仔细分析一下YUI TreeView的结构,Tree相关的类如下:

    我们分成3部分看,第一部分是前面几个以Node结尾的类,这些类代表是树上的节点,其中最顶层的是Node,这个类是其他几种Node的父类。Node中有节点所具有的所有属性和方法,比如children,parent,depth,expand(),collapse()等等。
    第二部分是TreeView这个类,这个类就像是一棵树的骨架,他有根有树干有树枝,可以把上面介绍的Node节点挂在Treeview上,Treeview会统一管理记录这些节点。通过TreeView你可以很方便的定位到一个或一些节点,比如 getNodeByElement(),getNodeByIndex,
getNodeByProperty(),getNodesByProperty()。通过TreeView可以控制一棵树是展开还是合拢,可以移除一些节点等等。TreeView就是在全局上控制树上的Nodes。
    第三部分是最后三个类,这三个类主要是个树增加一些动画的效果。

    既然TreeView是整棵树的总枢纽,我们就先从TreeView入手(由于TreeView的 源码太长,我就不直接贴出来,大家可以对照着源码看,碰到比较重要的代码我会把它们贴出来)。   
    首先是TreeView的构造函数:YAHOO.widget.TreeView ( id ),构造方法只有一个参数,就是HTML中的Div元素的ID,这就像是给树挖个坑中下去,以后树在页面上显示就有地方了。构造方法里面调用了TreeView的Init方法,这个方法我们稍后再说。
    TreeView里面有不少属性,不过大多都不用太深究,无非是用来与HTML元素做绑定,记录TreeView的状态等等,这些属性我们只要构建好了树,就由树内部做管理,一般情况下我们都不会使用到。下面挑几个重要的属性做说明:
    YAHOO.widget.TreeView.nodeCount,这是一个静态属性,这个属性记录TreeView上面Node的个数,也就是每次生成一个Node到TreeView上,这个属性值就增加1,这个属性有一个作用就是给Node分配一个唯一的标识,每个Node都有一个属性叫做index,这个index就是由这个属性来分配的。由于这个属性值只增不减,所以永远不会出现重复的。
    YAHOO.widget.TreeView.trees,这是一个私有属性,它是一个关联数组,用来缓存所有的TreeView实例,每次生成一个TreeView的实例就会往trees里面设置一个key(TreeView的Id)和value(TreeView的实例)。这样方便以后通过Id可以直接取到TreeView的实例。TreeView有一个方法:YAHOO.widget.TreeView.getTree(treeId),看看它的实现:
YAHOO.widget.TreeView.getTree = function(treeId) {
    var t = YAHOO.widget.TreeView.trees[treeId];//通过trees属性取值
    return (t) ? t : null;
};

YAHOO.widget.TreeView.counter,这个也是私有属性,用来给TreeView生成一个唯一的ID,
generateId: function(el) {
        var id = el.id;
        if (!id) {
            id = "yui-tv-auto-id-" + YAHOO.widget.TreeView.counter;
            ++YAHOO.widget.TreeView.counter;
        }
        return id;
    },

这个属性的值同样是递增的,generateId方法生成的Id,在TreeView的init方法中就直接赋值给Treeview实例。
    说到TreeView的init方法,我们就仔细看看它做了什么。
init: function(id) {
        this.id = id;
        if ("string" !== typeof id) {
            this._el = id;
            this.id = this.generateId(id);//通过YAHOO.widget.TreeView.counter生成
        }
        this.createEvent("animStart", this);
        this.createEvent("animComplete", this);
        this.createEvent("collapse", this);
this.createEvent("collapseComplete", this);
        this.createEvent("expand", this);
        this.createEvent("expandComplete", this);
this._nodes = [];
        // store a global reference
        YAHOO.widget.TreeView.trees[this.id] = this;
        // Set up the root node
        this.root = new YAHOO.widget.RootNode(this);
        var LW = YAHOO.widget.LogWriter;
        this.logger = (LW) ? new LW(this.toString()) : YAHOO;
        this.logger.log("tree init: " + this.id);
    },

    Init方法做的事情很简单,给TreeView分配一个Id,创建一些事件,把TreeView实例加入到YAHOO.widget.TreeView.trees数组中,生成一个RootNode。还记得我们往树上加第一个节点的时候,父节点就是用的这个RootNode,通过treeView.getRoot()这个方法可以取得。
    在上次的那个例子中,最后调用了treeView.draw()来显示树,现在我们看看这个方法的实现:
draw: function() {
        var html = this.root.getHtml();
        this.getEl().innerHTML = html;
        this.firstDraw = false;
    },

    this.root.getHtml()这个方法通过RootNode的getHtml得到节点的Html表示,this.getEl(),取得TreeView对应Div的对象,然后设置innerHTML。
    TreeView类的介绍就到这,TreeView还有很多控制相关的方法,比如expand,collpase(),removeChildren(),getNodeByIndex()等等,这些方法实现都比较简单,而且不知道他们的实现对使用也没有什么影响,所以就不对这些方法做具体的介绍,有兴趣可以自己查看源码。
    下面要说的是几个以Node结尾的类,先从顶层的YAHOO.widget.Node开始。
YAHOO.widget.Node = function(oData, oParent, expanded) {
    if (oData) { this.init(oData, oParent, expanded); }
};
……….
init: function(oData, oParent, expanded) {
        this.data       = oData;
        this.children   = [];
        this.index      = YAHOO.widget.TreeView.nodeCount;
        ++YAHOO.widget.TreeView.nodeCount;
        this.expanded   = expanded;
        this.logger     = new YAHOO.widget.LogWriter(this.toString());
        this.createEvent("parentChange", this);
if (oParent) {
            oParent.appendChild(this);
        }
},
………


    上面这个是构造函数和Init方法,生成一个Node需要三个参数,第一个oData,这个属性可以是任意类型的,可以是Object,这一点很重要,以后扩展树的时候可以传入你定义好的数据。第二个属性是oParent,就是你构造这个节点的父亲,值可以是树上的其他节点,第三个属性expanded,有true和false两个值,true的时候默认节点展开,false的时候不展开。
    Init方法做一些初始化工作,this.index = YAHOO.widget.TreeView.nodeCount;这个是给每个Node一个唯一Id,之前介绍TreeView类的时候有说到YAHOO.widget.TreeView.nodeCount这个属性。This.children用来存储它的所有子节点,最后oParent.appendChild(this);把新生成的Node加入到oParent的children数组中。
    下面把构造的过程画一张图 (图中的椭圆为属性):

我把余下的方法进行了下简单的分类便于大家理解掌握
/*插入节点的方法*/
appendTo(parentNode) {
        return parentNode.appendChild(this);
    }//很常用的插入节点的方法 但被插入到了参数节点子节点的最后一个
insertBefore: function(node)
     如果这个节点在一个树里则先从这棵树里把该节点删除(注意:appendTo可没有删)
     然后获取参数Node父节点的孩子列表以及该参数Node的位置以此操作该孩子列表在参数节点的位置前面添加
     实现添加。然后重定向该节点和参数Node的前后sibling属性
     最后一步 调用applyParent()方法 重设depth同时也把自己的子节点也引过来了
insertAfter: function(node)
     机理同上 只在第二步操作的位置不一样罢了

/*几个获取ID的方法*/
getElId() 返回这个节点容器div的id  id结构:"ygtv" + this.index
getChildrenElId() 返回节点的Children节点DIV的id 注意是所有子节点在一个DIV里  id结构 "ygtvc" + this.index;
getToggleElId()   返回节点的toggle的id   id结构:"ygtvt"+ this.index  toggle区域就是 树种节点的左边的+ -号的区域
*这些个方法都对应有通过id获取到对象的方法 getEl() getChildrenEl() getToggleEl()

/*节点的收起展开*/(可以添加一些自定义的事件)
collapse() 隐藏起子节点(如果有必要的话可创建子节点)
           核心是:一堆判断之后 调用 this.hideChildren()方法 此方法即获取孩子区域的对象将其display属性设为none
           当然了,也调用了this.updateIcon()方法 此方法用于更新了左边的+ -显示
expand(boolean)     显示子节点 核心:也是一堆的判断 之后调用this.showChildren() 此方法即获取孩子区域的对象将其display属性设为""
expandAll() 和 collapseAll() 很显然 这两个方法是同时展开或收起所有节点以下的节点

/*这个跟动态加载相关*/
setDynamicLoad(fnDataLoader, iconMode) 设置第一次展开节点时动态加载子节点数据的方法 获取方法通过参数fnDataLoader传递给节点的dataLoader属性  fnDataLoader方法的参数  第一个是Node节点类型 第二个是回调函数 如果不设置回调函数的话 在第一次加载之后节点  会关闭动态生成(即设dynamicLoadComplete为true )因为你不指定的话 会调用默认的
setDynamicLoad()第二个参数可选 int型  会赋给iconMode属性(具体用途见前面的属性解析)

/*这个很重要跟自定义节点有关*/
getNodeHtml()   这个方法被设计用来被重写的 本身返回空字符串 以便支持不同种的Node. 方法会在生成节点的时候把取得的html写入节点,从而产生了各种不同的节点样式
getHtml()  这个方法= getNodeHtml()+getChildrenHtml()
getChildrenHtml() 在构建树的时候会被调用 我们总是先构建装子节点的div 但并不提供进去信息 除非这个节点被展开
refresh()  将节点getHtml()获得的html写入到子节点的区域里

getStyle() 获取节点应有的左边+ -号状态 updateIcon()方法会调用
isRoot() 返回节点是否为根节点
isChildOf(parentNode) 获取该节点在父节点的孩子节点列表中的位置 insertBefore/insertAfter方法第二步调用了该方法我自己测试的从0开始。
getSiblings() 返回所有的兄弟节点 包括节点自己
isDynamic() 返回节点的子节点是否应该是被动态生成的 
getAncestor: function(depth) 返回节点某一深度的祖先

    YAHOO.widget.Node就介绍到这,接下来看看继承自YAHOO.widget.Node的其他Node。YAHOO.widget.RootNode的源码如下:
YAHOO.widget.RootNode = function(oTree) {
	this.init(null, null, true);
	this.tree = oTree;
};
YAHOO.extend(YAHOO.widget.RootNode, YAHOO.widget.Node, {
    
    // overrides YAHOO.widget.Node
    getNodeHtml: function() { 
        return ""; 
    },

    toString: function() { 
        return "RootNode";
    },

    loadComplete: function() { 
        this.tree.draw();
    },

    collapse: function() {},
    expand: function() {}

});

    很简单的实现,从构造函数来看,就是给RootNode指定一个tree属性。其Init方法都基本传入的是null,调用YAHOO.widget.Node的Init方法。getNodeHtml返回””,就是说RootNode不能显示出来,是一个隐藏的节点。其他几个方法的实现都很简单,不用多说。
    YAHOO.widget.HTMLNode继承自YAHOO.widget.Node,看源码可以发现HTMLNode多加了三个属性,构造函数也加了一个属性,叫hasIcon,这个属性是用来控制是否要显示树前面的那些加号、减号以及虚线等图标的。
YAHOO.widget.HTMLNode = function(oData, oParent, expanded, hasIcon) {
    if (oData) { 
        this.init(oData, oParent, expanded);
        this.initContent(oData, hasIcon);
    }
};

YAHOO.extend(YAHOO.widget.HTMLNode, YAHOO.widget.Node, {
	contentStyle: "ygtvhtml",
contentElId: null,
html: null,	

增加的三个属性分别是:
    contentStyle: "ygtvhtml",设置显示的CSS样式
    contentElId: null,给Content Element设置一个ID
    html: null,用来显示的Html内容
它重写的方法有toString(),getNodeHtml(),getNodeHtml()是节点显示的主要方法。
它增加的方法有initContent: function(oData, hasIcon),setHtml: function(o),这些方法的实现都很简单,不用详细说明。
    YAHOO.widget.TextNode是比较常用的一种Node,它根据你传入的oData来构造显示,如果传入的oData是String,则把String当作Label显示出来,如果传入的是Object,则根据Object的label属性来显示,同时还可以给Object设置style,title等属性,可以很灵活的控制节点要显示成什么样,要显示哪些信息。
    具体的显示它重写了getNodeHtml()方法。新加了onLabelClick方法,在点击树节点的Label的时候触发。
    最后是YAHOO.widget.MenuNode ,它继承自YAHOO.widget.TextNode,只从写了toString()方法。
   
    通过分析上面几个继承自YAHOO.widget.Node的Node,可以发现实现一个Node很简单,在init方法里面加入一些新的操作,加入一些新的属性,最后重写一些方法,就能得出符合自己要求的Node。YUI在Node的设计上做得是相当不错的,给了我们很方便的方法来扩展已有的Node。下一次我将会详细的讲解如何构建满足自己需求的Node。




分享到:
评论

相关推荐

    YUI3 中tree的两种实现

    这篇博文“YUI3 中tree的两种实现”探讨了如何在YUI3中创建和管理树形结构。 1. **YUI3 TreeView组件** YUI3 TreeView组件是YUI3核心库的一部分,它允许开发者创建交互式的树结构。这个组件支持节点的添加、删除、...

    YAHOO YUI3简单入门

    本教程将带你入门YUI3的基础知识。 **模块化设计** YUI3的核心理念是模块化,这意味着你可以根据需要只加载所需的组件,从而降低页面加载时间和资源消耗。例如,`yui-min.js`就是YUI3的最小核心模块,它包含了YUI...

    YUI 入门教程YUI 入门教程YUI 入门教程

    本教程将深入介绍YUI的基础知识和关键特性,帮助开发者快速入门。 首先,YUI提供了一系列强大的DOM操作工具,例如`YAHOO.util.Dom.get`用于通过ID查找页面元素,类似于`document.getElementById`。`YAHOO.util.Dom....

    基于yui的layout,tree的demo

    基于yui的layout,tree的一个demo

    yui3-master.zip

    在“yui3-master.zip”的“node”模块中,可以找到`Y.Node`, `Y.all`等方法,它们使得DOM操作更加符合JavaScript的编程习惯。 5. **动画效果** YUI3还包含了丰富的动画功能,如“anim”模块,能够实现复杂的CSS...

    YUI 详细说明文档

    ### YUI 详细说明文档 #### 一、YAHOO工具库 YUI是一个由Yahoo!开发的强大且灵活的开源JavaScript框架,它包含了丰富的库和工具集,旨在帮助开发者更轻松地构建高质量的Web应用程序。YAHOO工具库是YUI的核心组成...

    yahoo Tree组件

    在博文链接中,作者可能详细介绍了如何使用YUI Tree组件,包括实例代码和常见问题解答。如果需要深入了解,可以查阅该博客获取更多实践经验和技巧。 总之,Yahoo Tree组件作为YUI库的一个强大工具,为开发人员提供...

    YUi文档(中文的哦)

    ### YUI3中文文档知识点详解 ...通过以上详细介绍,可以看出YUI3提供了非常强大且灵活的API,可以帮助开发者高效地开发复杂的Web应用。无论是基本的DOM操作还是复杂的事件处理,YUI3都能提供简洁有效的解决方案。

    yahoo yui 实例教程

    利用Yahoo YUI库做的一个TREE实例,很详细的阐述了YUI的使用原理

    yui 资源包

    1. **DOM操作**:YUI的Node和Selector模块提供了高效的DOM操作接口,包括选择、操作、遍历DOM元素。 2. **Ajax**:IO模块用于实现异步数据请求,支持JSONP、XHR等通信方式。 3. **表格与表单**:DataTable和Form模块...

    YUI3.7.3 最新版本 带API

    8. **API文档**:YUI3.7.3附带的API文档详细阐述了每个模块的功能和用法,是开发者学习和使用YUI的重要参考资料。 9. **响应式设计支持**:YUI3包含了一些工具,如Resize Utility,帮助开发者实现响应式设计,使...

    YUI Compressor压缩JS和Css工具(包含详细配置)

    ### 二、YUI Compressor的使用方法 使用YUI Compressor通常有以下几种方式: 1. **命令行工具**:通过安装Java Development Kit (JDK),然后下载YUI Compressor的jar文件,可以在命令行中使用`java -jar yui...

    YUI js方法使用列子

    2. **选择DOM元素**:使用YUI的Node模块,可以像jQuery那样选择和操作DOM元素。 ```javascript YUI().use('node', function(Y) { var element = Y.one('#myElementId'); element.setStyle('color', 'red'); // ...

    yui.rar 例子

    而YUI Profiler则可以分析性能瓶颈,优化代码执行效率。这些工具与例子中的代码相结合,可以为开发者提供一个完整的开发和调试环境。 总结来说,“yui.rar 例子”为我们揭示了YUI在实际项目中的应用,从简单的布局...

    yui_3.8.1.zip

    二、YUI 3.8.1的主要特性 1. **模块系统**:YUI 3.8.1采用CommonJS规范,通过YUI.use()方法按需加载模块,降低初始页面加载时间。此外,还支持AMD(异步模块定义)模式,适应不同的开发需求。 2. **事件处理**:...

    【YUI组件】基于YUI的表单验证器

    描述中提到的“NULL”意味着没有提供额外的详细信息。不过,我们可以从“博文链接:https://every-best.iteye.com/blog/750967”推断,可能存在一篇关于这个YUI表单验证器的博客文章,提供了更深入的讲解和示例。...

    雅虎YUI组建

    综上所述,雅虎YUI组件是一个强大而全面的前端开发框架,其模块化设计、丰富的组件库以及详细的实例,使得开发者能够高效地构建功能完善的Web应用。无论你是前端新手还是经验丰富的开发者,YUI都能成为你得力的助手...

    YUI3.6文档及示例

    在这个文档及示例的压缩包中,你将找到关于YUI3.6的详细信息,包括API文档和实践示例,这将有助于你深入理解和应用YUI。 YUI3.6主要包含以下几个核心部分: 1. **模块系统**:YUI3引入了模块化设计,允许开发者按...

    yui3-3.17.2最新版

    YUI 3包含了一系列核心模块,如Event(事件处理)、Node(DOM操作)、IO(异步数据交互)等,同时还有许多可选的组件,如Grids(表格)、Charts(图表)、Form(表单元素)等,覆盖了前端开发的多个方面。...

    yuicompressor-yui compressor

    yuicompressor-2.4.2.jar yuicompressor-2.4.7.jar jsZip.exe yuicompressor yui compressor js压缩工具 javascript压缩工具 css压缩工具 ------------------------------------ //压缩JS java -jar yui...

Global site tag (gtag.js) - Google Analytics