TWaver - 專注UI技術

          http://twaver.servasoft.com/
          posts - 171, comments - 191, trackbacks - 0, articles - 2
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          TWaver HTML5 繼承結構和成員說明

          Posted on 2012-11-16 16:46 TWaver 閱讀(1883) 評論(0)  編輯  收藏

          JavaScript是一門動態(tài)語言,但是面向對象的特征沒有Java那么明顯,導致我們開發(fā)起來非常不習慣。拿繼承來說,Java中有專門的extends和implements關鍵字實現,但是在JavaScript卻引入了一個"別扭的"prototype,而且實現方式有很多種,雖然靈活,卻很容易讓初學者一頭霧水不知所措。TWaver HTML5的doc是一個js文件,對編輯器很友好,但是我們看起來卻不是很方便,遠不如JavaDoc來得一目了然,于是我們做了另一個html,算是對原js格式doc的補充。先看一下最后完成的效果:

          運行截圖:

          這并不是一個靜態(tài)頁面,而是用JavaScript動態(tài)解析TWaver,所以即使TWaver更新也沒關系,只要在這個html中引入新的twaver.js就可以了。

          界面說明:整個頁面的布局借助twaver.controls.SplitPane實現,左側是TWaver的樹組件,中間是List組件,右側是一個pre標簽,借助beautify和prettify展現js代碼。


          接下來介紹一下頁面上三個部分的實現方式:
          • Tree的實現,下面是初始化Tree的全部代碼:
           1 //twaver.Util.getAllClassNames()返回TWaver所有的內部類型
           2 var allClassNames = twaver.Util.getAllClassNames();
           3 //遍歷類名
           4 allClassNames.forEach(function (data) {
           5      addClass(data);
           6 });
           7 var elementBox = new twaver.ElementBox();
           8 var map = {};
           9 //初始化Tree box
          10 function addClass(name) {
          11     var node = new twaver.Node(name);
          12     node.setName(name);
          13 //分割字符串,找我們需要的類或對象
          14     var clazzArr = name.split(".");
          15     var clazz = window;
          16     for (var i = 0; i < clazzArr.length; i++) {
          17           clazz = clazz[clazzArr[i]];
          18     } 
          19 //根據不同的類型設置Icon     
          20     if (typeof clazz === "object") {
          21           node.setIcon("object");     
          22     } else if (typeof clazz === "function") {
          23           node.setIcon("class");     
          24     }     
          25     //同時將node存入map,方便查詢使用
          26     map[name] = node;
          27     node.clazz = clazz;
          28     elementBox.add(node); } 
          29     // 
          30     var tree = new twaver.controls.Tree(elementBox); 

          getAllClassNames返回的是類或對象的名字,但是我們要獲得實際的類和對象以便可以解析它們的屬性和方法。思考一下:在瀏覽器環(huán)境下window是根對象,所有全局對象都是window對象的屬性而已,TWaver也不例外,所以我們分割字符串,通過window對象一層一層找屬性,最終找到我們要的類或對象。然后我們生成Node,填充box數據容器;同時做了一個< 名字---Node>的映射,后面會用到。 初始化Tree以后設置節(jié)點的父子關系:

          1 elementBox.toDatas().forEach(function (data) { 
          2 //TWaver所有內置類型都有superClass屬性,指向實際的父類或父對象,通過它可以得到父類然后從map中取出樹上相應的節(jié)點     
          3      var superClass = data.clazz.superClass;     
          4      if (superClass && superClass.getClassName) { 
          5          data.setParent(map[superClass.getClassName()]);  
          6      } 
          7 }); 

          大家注意到,Tree的上方還有一個用來過濾數據的文本框,我們看一下它的事件處理:

           1 //Tree的過濾文本框 
           2 var treeFilter = document.createElement("input");
           3 treeFilter.type = "text"; 
           4 treeFilter.addEventListener("input", function () {
           5      var value = treeFilter.value.trim().toLowerCase();     
           6      if (value.length > 0) {
           7              tree.setVisibleFunction(function (data) {
           8                  if(data.getName().toLowerCase().indexOf(value)>=0){return true};
           9                  //如果當前節(jié)點的名字與過濾字符串不匹配,就去查詢是否有子節(jié)點匹配
          10                  //如果子節(jié)點匹配,父節(jié)點同樣可見
          11                  return isChildVisible(data, value);
          12              });
          13      } else {
          14             tree.setVisibleFunction(null);
          15      }
          16 });
          17 //
          18 //遞歸是否有子節(jié)點可見
          19 function isChildVisible(parent, value) {
          20     var children = parent.getChildren();
          21     for (var i = 0; i < children.size(); i++) {           
          22           var child = children.get(i);           
          23            if (child.getName().toLowerCase().indexOf(value) >= 0) {
          24                return true;
          25           } else if (isChildVisible(child, value)) {
          26                 return true;
          27           }
          28      }
          29      return false;
          30 }
          31 

          對于Tree過濾器,不能簡單的判斷當前節(jié)點,因為可能當前節(jié)點的名字不符合過濾字符串,但是子節(jié)點符合,這種時候父節(jié)點也要顯示,所以需要做遞歸處理:如果當前節(jié)點的子節(jié)點符合過濾字符串,當前節(jié)點同樣可見。
          • List的實現
          List比Tree要簡單的多,監(jiān)聽Tree的選中改變事件,得到選中的Node然后解析屬性和方法,填充進List的數據容器

           1 tree.getSelectionModel().addSelectionChangeListener(function (e) {
           2      var selectedData = tree.getSelectionModel().getLastData();
           3      if (selectedData) {
           4            var html = '';
           5            list.getDataBox().clear();
           6            //TWaver內置的屬性和方法都在prototype上,所以如果data的類型是function,我們就遍歷它的prototype
           7            var obj = typeof selectedData.clazz === "function" ? selectedData.clazz.prototype : selectedData.clazz;
           8            for (var name in obj) {
           9                 if (obj.hasOwnProperty(name)) {
          10                       var listNode = new twaver.Node();
          11                       if (typeof obj[name] === "function") {
          12                             listNode.setIcon("method");
          13                       } else {
          14                             listNode.setIcon("property");
          15                       }
          16                       listNode.setName(name + " - " + typeof obj[name]);
          17                       //注意getContent方法,對于function直接返回,對于Object再進行一次遍歷
          18                       listNode.content = "" + getContent(obj[name]);
          19                       html += name + ":" + listNode.content;
          20                       list.getDataBox().add(listNode);
          21                  }
          22             }
          23             pre.innerHTML = '';
          24             html = js_beautify(html);
          25             pre.appendChild(document.createTextNode(html));
          26             prettyPrint();
          27        }
          28 });

          除了填充list,我們還直接把對象屬性的js代碼組合起來放到右側pre中,為了規(guī)范js代碼,我們用到了js_beautify和prettify兩個類庫,感興趣的同學可以谷歌一下。
          • pre的實現
          在List上點擊某個屬性或方法的時候,更新pre的內容為屬性值或方法代碼

           1 //list選中的節(jié)點發(fā)生變化時更新pre
           2 list.getSelectionModel().addSelectionChangeListener(function (e) {
           3      var data = list.getSelectionModel().getLastData();
           4      if (data) {
           5          pre.innerHTML = '';
           6          var html = js_beautify(data.content + "");
           7          pre.appendChild(document.createTextNode(html));
           8          prettyPrint();
           9       }
          10 });

          這三部分介紹完,實際上這個頁面也就寫完了,通過這些代碼,大家應該可以感受到JavaScript的靈活之處,頁面布局部分的代碼就不介紹了,大家可從下載附件自行研究,最后附上附件見原文最下方

          只有注冊用戶登錄后才能發(fā)表評論。


          網站導航:
           
          主站蜘蛛池模板: 定襄县| 惠州市| 麻城市| 呼伦贝尔市| 乐昌市| 仙桃市| 湾仔区| 仪征市| 石台县| 黔江区| 喀什市| 罗源县| 凤凰县| 萨迦县| 新营市| 曲阳县| 沿河| 合作市| 崇州市| 潮安县| 茌平县| 丽水市| 黎城县| 新津县| 长汀县| 永靖县| 海阳市| 武威市| 蕉岭县| 行唐县| 威海市| 井陉县| 白城市| 内黄县| 改则县| 体育| 普洱| 历史| 平山县| 元氏县| 深泽县|