日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JavaScript内核系列 第8章 面向对象的JavaScript(下)

發(fā)布時(shí)間:2025/1/21 javascript 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript内核系列 第8章 面向对象的JavaScript(下) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.


原創(chuàng)作者: abruzzi?

接上篇:JavaScript內(nèi)核系列 第8章 面向?qū)ο蟮腏avaScript(上)

8.4實(shí)例:事件分發(fā)器

這一節(jié),我們通過學(xué)習(xí)一個(gè)面向?qū)ο蟮膶?shí)例來對(duì)JavaScript的面向?qū)ο筮M(jìn)行更深入的理解,這個(gè)例子不能太復(fù)雜,涉及到的內(nèi)容也不能僅僅為繼承,多態(tài)等概念,如果那樣,會(huì)失去閱讀的樂趣,最好是在實(shí)例中穿插一些講解,則可以得到最好的效果。

本節(jié)要分析的實(shí)例為一個(gè)事件分發(fā)器(Event Dispatcher),本身來自于一個(gè)實(shí)際項(xiàng)目,但同時(shí)又比較小巧,我對(duì)其代碼做了部分修改,去掉了一些業(yè)務(wù)相關(guān)的部分。

事件分發(fā)器通常是跟UI聯(lián)系在一起的,UI中有多個(gè)組件,它們之間經(jīng)常需要互相通信,當(dāng)UI比較復(fù)雜,而頁面元素的組織又不夠清晰的時(shí)候,事件的處理會(huì)非常麻煩。在本節(jié)的例子中,事件分發(fā)器為一個(gè)對(duì)象,UI組件發(fā)出事件到事件分發(fā)器,也可以注冊(cè)自己到分發(fā)器,當(dāng)自己關(guān)心的事件到達(dá)時(shí),進(jìn)行響應(yīng)。如果你熟悉設(shè)計(jì)模式的話,會(huì)很快想到觀察者模式,例子中的事件分發(fā)器正式使用了此模式。

?

?

?

Js代碼

var?uikit?=?uikit?||?{};?? uikit.event?=?uikit.event?||?{};?? ??? uikit.event.EventTypes?=?{?? ????EVENT_NONE?:?0,?? ????EVENT_INDEX_CHANGE?:?1,?? ????EVENT_LIST_DATA_READY?:?2,?? ????EVENT_GRID_DATA_READY?:?3?? };?? var uikit = uikit || {};uikit.event = uikit.event || {}; uikit.event.EventTypes = { EVENT_NONE : 0, EVENT_INDEX_CHANGE : 1, EVENT_LIST_DATA_READY : 2, EVENT_GRID_DATA_READY : 3};

?

?

定義一個(gè)名稱空間uikit,并聲明一個(gè)靜態(tài)的常量:EventTypes,此變量定義了目前系統(tǒng)所支持的事件類型。

?

?

?

Js代碼

  • uikit.event.JSEvent?=?Base.extend({??
  • ????constructor?:?function(obj){??
  • ???????this.type?=?obj.type?||?uikit.event.EventTypes.EVENT_NONE;??
  • ???????this.object?=?obj.data?||?{};??
  • ????},??
  • ?????
  • ????getType?:?function(){??
  • ???????return?this.type;??
  • ????},??
  • ?????
  • ????getObject?:?function(){??
  • ???????return?this.object;??
  • ????}??
  • });??
  • uikit.event.JSEvent = Base.extend({ constructor : function(obj){ this.type = obj.type || uikit.event.EventTypes.EVENT_NONE; this.object = obj.data || {}; }, getType : function(){ return this.type; }, getObject : function(){ return this.object; }});

    ?

    ?

    ?

    定義事件類,事件包括類型和事件中包含的數(shù)據(jù),通常為事件發(fā)生的點(diǎn)上的一些信息,比如點(diǎn)擊一個(gè)表格的某個(gè)單元格,可能需要將該單元格所在的行號(hào)和列號(hào)包裝進(jìn)事件的數(shù)據(jù)。

    ?

    ?

    ?

    Js代碼

  • uikit.event.JSEventListener?=?Base.extend({??
  • ????constructor?:?function(listener){??
  • ???????this.sense?=?listener.sense;??
  • ???????this.handle?=?listener.handle?||?function(event){};??
  • ????},??
  • ?????
  • ????getSense?:?function(){??
  • ???????return?this.sense;??
  • ????}??
  • });??
  • uikit.event.JSEventListener = Base.extend({ constructor : function(listener){ this.sense = listener.sense; this.handle = listener.handle || function(event){}; }, getSense : function(){ return this.sense; }});

    ?

    ?

    ?

    定義事件監(jiān)聽器類,事件監(jiān)聽器包含兩個(gè)屬性,及監(jiān)聽器所關(guān)心的事件類型sense和當(dāng)該類型的事件發(fā)生后要做的動(dòng)作handle。

    ?

    ?

    ?

    Js代碼

  • uikit.event.JSEventDispatcher?=?function(){??
  • ????if(uikit.event.JSEventDispatcher.singlton){??
  • ???????return?uikit.event.JSEventDispatcher.singlton;??
  • ????}??
  • ???
  • ????this.listeners?=?{};??
  • ???
  • ????uikit.event.JSEventDispatcher.singlton?=?this;??
  • ???
  • ????this.post?=?function(event){??
  • ???????var?handlers?=?this.listeners[event.getType()];??
  • ???????for(var?index?in?handlers){??
  • ???????????if(handlers[index].handle?&&?typeof?handlers[index].handle?==?"function")??
  • ???????????handlers[index].handle(event);??
  • ???????}??
  • ????};??
  • ???
  • ????this.addEventListener?=?function(listener){??
  • ???????var?item?=?listener.getSense();??
  • ???????var?listeners?=?this.listeners[item];??
  • ???????if(listeners){??
  • ???????????this.listeners[item].push(listener);??
  • ???????}else{??
  • ???????????var?hList?=?new?Array();??
  • ???????????hList.push(listener);??
  • ???????????this.listeners[item]?=?hList;????
  • ???????}??
  • ????};??
  • }??
  • ???
  • uikit.event.JSEventDispatcher.getInstance?=?function(){??
  • ????return?new?uikit.event.JSEventDispatcher();????
  • };??
  • uikit.event.JSEventDispatcher = function(){ if(uikit.event.JSEventDispatcher.singlton){ return uikit.event.JSEventDispatcher.singlton; } this.listeners = {}; uikit.event.JSEventDispatcher.singlton = this; this.post = function(event){ var handlers = this.listeners[event.getType()]; for(var index in handlers){ if(handlers[index].handle && typeof handlers[index].handle == "function") handlers[index].handle(event); } }; this.addEventListener = function(listener){ var item = listener.getSense(); var listeners = this.listeners[item]; if(listeners){ this.listeners[item].push(listener); }else{ var hList = new Array(); hList.push(listener); this.listeners[item] = hList; } };} uikit.event.JSEventDispatcher.getInstance = function(){ return new uikit.event.JSEventDispatcher(); };

    ?

    ?

    ?

    這里定義了一個(gè)單例的事件分發(fā)器,同一個(gè)系統(tǒng)中的任何組件都可以向此實(shí)例注冊(cè)自己,或者發(fā)送事件到此實(shí)例。事件分發(fā)器事實(shí)上需要為何這樣一個(gè)數(shù)據(jù)結(jié)構(gòu):

    ?

    ?

    ?

    Js代碼

    var?listeners?=?{?? ????eventType.foo?:?[?? ???????{sense?:?"eventType.foo",?handle?:?function(){doSomething();}}?? ???????{sense?:?"eventType.foo",?handle?:?function(){doSomething();}}?? ???????{sense?:?"eventType.foo",?handle?:?function(){doSomething();}}?? ????],?? ????eventType.bar?:?[?? ???????{sense?:?"eventType.bar",?handle?:?function(){doSomething();}}?? ???????{sense?:?"eventType.bar",?handle?:?function(){doSomething();}}?? ???????{sense?:?"eventType.bar",?handle?:?function(){doSomething();}}?? ????],..?? };?? var listeners = { eventType.foo : [ {sense : "eventType.foo", handle : function(){doSomething();}} {sense : "eventType.foo", handle : function(){doSomething();}} {sense : "eventType.foo", handle : function(){doSomething();}} ], eventType.bar : [ {sense : "eventType.bar", handle : function(){doSomething();}} {sense : "eventType.bar", handle : function(){doSomething();}} {sense : "eventType.bar", handle : function(){doSomething();}} ],..};

    ?

    ?

    當(dāng)事件發(fā)生之后,分發(fā)器會(huì)找到該事件處理器的數(shù)組,然后依次調(diào)用監(jiān)聽器的handle方法進(jìn)行相應(yīng)。好了,到此為止,我們已經(jīng)有了事件分發(fā)器的基本框架了,下來,我們開始實(shí)現(xiàn)我們的組件(Component)。

    ???????? 組件要通信,則需要加入事件支持,因此可以抽取出一個(gè)類:

    ?

    ?

    Js代碼

  • uikit.component?=?uikit.component?||?{};??
  • ???
  • uikit.component.EventSupport?=?Base.extend({??
  • ??constructor?:?function(){??
  • ?????
  • ??},??
  • ???
  • ??raiseEvent?:?function(eventdef){??
  • ???????var?e?=?new?uikit.event.JSEvent(eventdef);??
  • ???????uikit.event.JSEventDispatcher.getInstance().post(e);??????
  • ??},??
  • ???
  • ??addActionListener?:?function(listenerdef){??
  • ???????var?l?=?new?uikit.event.JSEventListener(listenerdef);??
  • ???????uikit.event.JSEventDispatcher.getInstance().addEventListener(l);??
  • ??}??
  • });??
  • uikit.component = uikit.component || {}; uikit.component.EventSupport = Base.extend({ constructor : function(){ }, raiseEvent : function(eventdef){ var e = new uikit.event.JSEvent(eventdef); uikit.event.JSEventDispatcher.getInstance().post(e); }, addActionListener : function(listenerdef){ var l = new uikit.event.JSEventListener(listenerdef); uikit.event.JSEventDispatcher.getInstance().addEventListener(l); }});

    ?

    ?

    ?

    繼承了這個(gè)類的類具有事件支持的能力,可以raise事件,也可以注冊(cè)監(jiān)聽器,這個(gè)EventSupport僅僅做了一個(gè)代理,將實(shí)際的工作代理到事件分發(fā)器上。

    ?

    ?

    ?

    Js代碼

  • uikit.component.ComponentBase?=?uikit.component.EventSupport.extend({??
  • ??constructor:?function(canvas)?{??
  • ???????this.canvas?=?canvas;??
  • ??},??
  • ???
  • ??render?:?function(datamodel){}??
  • });??
  • uikit.component.ComponentBase = uikit.component.EventSupport.extend({ constructor: function(canvas) { this.canvas = canvas; }, render : function(datamodel){}});

    ?

    ?

    ?

    定義所有的組件的基類,一般而言,組件需要有一個(gè)畫布(canvas)的屬性,而且組件需要有展現(xiàn)自己的能力,因此需要實(shí)現(xiàn)render方法來畫出自己來。

    ?

    我們來看一個(gè)繼承了ComponentBase的類JSList:

    ?

    ?

    ?

    Js代碼

  • uikit.component.JSList?=?uikit.component.ComponentBase.extend({??
  • ????constructor?:?function(canvas,?datamodel){??
  • ???????this.base(canvas);??
  • ???????this.render(datamodel);??
  • ????},??
  • ?????
  • ????render?:?function(datamodel){??
  • ???????var?jqo?=?$(this.canvas);??
  • ???????var?text?=?"";??
  • ???????for(var?p?in?datamodel.items){??
  • ???????????text?+=?datamodel.items[p]?+?";";??
  • ???????}??
  • ???????var?item?=?$("<div></div>").addClass("component");??
  • ???????item.text(text);??
  • ???????item.click(function(){??
  • ???????????jqo.find("div.selected").removeClass("selected");??
  • ???????????$(this).addClass("selected");??
  • ????????????
  • ???????????var?idx?=?jqo.find("div").index($(".selected")[0]);??
  • ???????????var?c?=?new?uikit.component.ComponentBase(null);??
  • ???????????c.raiseEvent({??
  • ??????????????type?:?uikit.event.EventTypes.EVENT_INDEX_CHANGE,??
  • ??????????????data?:?{index?:?idx}??
  • ???????????});??
  • ???????});??
  • ????????
  • ???????jqo.append(item);??
  • ????},??
  • ?????
  • ????update?:?function(event){??
  • ???????var?jqo?=?$(this.canvas);??
  • ???????jqo.empty();??
  • ???????var?dm?=?event.getObject().items;??
  • ???
  • ???????for(var?i?=?0;?i?<?dm.length();i++){??
  • ???????????var?entity?=?dm.get(i).item;??
  • ???????????jqo.append(this.createItem({items?:?entity}));??
  • ???????}??
  • ????},??
  • ?????
  • ????createItem?:?function(datamodel){??
  • ???????var?jqo?=?$(this.canvas);??
  • ???????var?text?=?datamodel.items;??
  • ???
  • ???????var?item?=?$("<div></div>").addClass("component");??
  • ???????item.text(text);??
  • ???????item.click(function(){??
  • ???????????jqo.find("div.selected").removeClass("selected");??
  • ???????????$(this).addClass("selected");??
  • ????????????
  • ???????????var?idx?=?jqo.find("div").index($(".selected")[0]);??
  • ???????????var?c?=?new?uikit.component.ComponentBase(null);??
  • ???????????c.raiseEvent({??
  • ??????????????type?:?uikit.event.EventTypes.EVENT_INDEX_CHANGE,??
  • ??????????????data?:?{index?:?idx}??
  • ???????????});??
  • ???????});??
  • ????????
  • ???????return?item;??
  • ????},??
  • ?????
  • ????getSelectedItemIndex?:?function(){??
  • ???????var?jqo?=?$(this.canvas);??
  • ???????var?index?=?jqo.find("div").index($(".selected")[0]);??
  • ???????return?index;??
  • ????}??
  • });??
  • uikit.component.JSList = uikit.component.ComponentBase.extend({ constructor : function(canvas, datamodel){ this.base(canvas); this.render(datamodel); }, render : function(datamodel){ var jqo = $(this.canvas); var text = ""; for(var p in datamodel.items){ text += datamodel.items[p] + ";"; } var item = $("<div></div>").addClass("component"); item.text(text); item.click(function(){ jqo.find("div.selected").removeClass("selected"); $(this).addClass("selected"); var idx = jqo.find("div").index($(".selected")[0]); var c = new uikit.component.ComponentBase(null); c.raiseEvent({ type : uikit.event.EventTypes.EVENT_INDEX_CHANGE, data : {index : idx} }); }); jqo.append(item); }, update : function(event){ var jqo = $(this.canvas); jqo.empty(); var dm = event.getObject().items; for(var i = 0; i < dm.length();i++){ var entity = dm.get(i).item; jqo.append(this.createItem({items : entity})); } }, createItem : function(datamodel){ var jqo = $(this.canvas); var text = datamodel.items; var item = $("<div></div>").addClass("component"); item.text(text); item.click(function(){ jqo.find("div.selected").removeClass("selected"); $(this).addClass("selected"); var idx = jqo.find("div").index($(".selected")[0]); var c = new uikit.component.ComponentBase(null); c.raiseEvent({ type : uikit.event.EventTypes.EVENT_INDEX_CHANGE, data : {index : idx} }); }); return item; }, getSelectedItemIndex : function(){ var jqo = $(this.canvas); var index = jqo.find("div").index($(".selected")[0]); return index; }});

    ?

    ?

    ?

    首先,我們的畫布其實(shí)是一個(gè)共jQuery選擇的選擇器,選擇到這個(gè)畫布之后,通過jQuery則可以比較容易的在畫布上繪制組件。

    ?

    在我們的實(shí)現(xiàn)中,數(shù)據(jù)與視圖是分離的,我們通過定義這樣的數(shù)據(jù)結(jié)構(gòu):

    ?

    ?

    ?

    Js代碼

  • {items?:?["China",?"Canada",?"U.S.A",?"U.K",?"Uruguay"]};??
  • {items : ["China", "Canada", "U.S.A", "U.K", "Uruguay"]};

    ?

    ?

    ?

    則可以render出如下圖所示的List:

    ?

    ?

    ?

    好,既然組件模型已經(jīng)有了,事件分發(fā)器的框架也有了,相信你已經(jīng)迫不及待的想要看看這些代碼可以干點(diǎn)什么了吧,再耐心一下,我們還要寫一點(diǎn)代碼:

    ?

    ?

    ?

    Js代碼

  • $(document).ready(function(){??
  • ????var?ldmap?=?new?uikit.component.ArrayLike(dataModel);??
  • ?????
  • ????ldmap.addActionListener({??
  • ???????sense?:?uikit.event.EventTypes.EVENT_INDEX_CHANGE,??
  • ???????handle?:?function(event){??
  • ???????????var?idx?=?event.getObject().index;??
  • ???????????uikit.component.EventGenerator.raiseEvent({??
  • ??????????????type?:?uikit.event.EventTypes.EVENT_GRID_DATA_READY,??
  • ??????????????data?:?{rows?:?ldmap.get(idx).grid}??
  • ???????????});??
  • ???????}??
  • ????});??
  • ?????
  • ????var?list?=?new?uikit.component.JSList("div#componentList",?[]);??
  • ????var?grid?=?new?uikit.component.JSGrid("div#conditionsTable?table?tbody");??
  • ?????
  • ????list.addActionListener({??
  • ????????sense?:??uikit.event.EventTypes.EVENT_LIST_DATA_READY,??
  • ????????handle?:?function(event){??
  • ????????????list.update(event);??
  • ????????}??
  • ????});??
  • ???
  • ????grid.addActionListener({??
  • ???????sense?:?uikit.event.EventTypes.EVENT_GRID_DATA_READY,??
  • ???????handle?:?function(event){??
  • ???????????grid.update(event);??
  • ???????}??
  • ????});??
  • ???
  • ????uikit.component.EventGenerator.raiseEvent({??
  • ???????type?:?uikit.event.EventTypes.EVENT_LIST_DATA_READY,??
  • ???????data?:?{items?:?ldmap}??
  • ????});??
  • ???
  • ????var?colorPanel?=?new?uikit.component.Panel("div#colorPanel");??
  • ????colorPanel.addActionListener({??
  • ???????sense?:?uikit.event.EventTypes.EVENT_INDEX_CHANGE,??
  • ???????handle?:?function(event){??
  • ???????????var?idx?=?parseInt(10*Math.random())??
  • ???????????colorPanel.update(idx);??
  • ???????}??
  • ????});??
  • });??
  • $(document).ready(function(){ var ldmap = new uikit.component.ArrayLike(dataModel); ldmap.addActionListener({ sense : uikit.event.EventTypes.EVENT_INDEX_CHANGE, handle : function(event){ var idx = event.getObject().index; uikit.component.EventGenerator.raiseEvent({ type : uikit.event.EventTypes.EVENT_GRID_DATA_READY, data : {rows : ldmap.get(idx).grid} }); } }); var list = new uikit.component.JSList("div#componentList", []); var grid = new uikit.component.JSGrid("div#conditionsTable table tbody"); list.addActionListener({ sense : uikit.event.EventTypes.EVENT_LIST_DATA_READY, handle : function(event){ list.update(event); } }); grid.addActionListener({ sense : uikit.event.EventTypes.EVENT_GRID_DATA_READY, handle : function(event){ grid.update(event); } }); uikit.component.EventGenerator.raiseEvent({ type : uikit.event.EventTypes.EVENT_LIST_DATA_READY, data : {items : ldmap} }); var colorPanel = new uikit.component.Panel("div#colorPanel"); colorPanel.addActionListener({ sense : uikit.event.EventTypes.EVENT_INDEX_CHANGE, handle : function(event){ var idx = parseInt(10*Math.random()) colorPanel.update(idx); } });}); ?

    ?

    ?

    使用jQuery,我們?cè)谖臋n加載完畢之后,新建了兩個(gè)對(duì)象List和Grid,通過點(diǎn)擊List上的條目,如果這些條目在List的模型上索引發(fā)生變化,則會(huì)發(fā)出EVENT_INDEX_CHAGE事件,接收到這個(gè)事件的組件或者DataModel會(huì)做出相應(yīng)的響應(yīng)。在本例中,ldmap在接收到EVENT_INDEX_CHANGE事件后,會(huì)組織數(shù)據(jù),并發(fā)出EVENT_GRID_DATA_READY事件,而Grid接收到這個(gè)事件后,根據(jù)事件對(duì)象上綁定的數(shù)據(jù)模型來更新自己的UI。

    上例中的類繼承關(guān)系如下圖:

    ?

    圖 事件分發(fā)器類層次

    ?

    ???????? 應(yīng)該注意的是,在綁定完監(jiān)聽器之后,我們手動(dòng)的觸發(fā)了EVENT_LIST_DATA_READY事件,來通知List可以繪制自身了:

    ?

    ?

    ?

    Js代碼

  • uikit.component.EventGenerator.raiseEvent({??
  • ???type?:?uikit.event.EventTypes.EVENT_LIST_DATA_READY,??
  • ???data?:?{items?:?ldmap}??
  • });??
  • uikit.component.EventGenerator.raiseEvent({ type : uikit.event.EventTypes.EVENT_LIST_DATA_READY, data : {items : ldmap} });

    ?

    ?

    ?

    在實(shí)際的應(yīng)用中,這個(gè)事件可能是用戶在頁面上點(diǎn)擊一個(gè)按鈕,或者一個(gè)Ajax請(qǐng)求的返回,等等,一旦事件監(jiān)聽器注冊(cè)完畢,程序就已經(jīng)就緒,等待異步事件并響應(yīng)。

    ?

    點(diǎn)擊List中的元素China,Grid中的數(shù)據(jù)發(fā)生變化

    ?

    點(diǎn)擊Canada,Grid中的數(shù)據(jù)同樣發(fā)生相應(yīng)的變化:

    ?

    ?

    由于List和Grid的數(shù)據(jù)是關(guān)聯(lián)在一起的,他們的數(shù)據(jù)結(jié)構(gòu)具有下列的結(jié)構(gòu):

    ?

    ?

    ?

    Js代碼

    var?dataModel?=?[{?? ????item:?"China",?? ????grid:?[?? ????????[{?? ????????????dname:?"Beijing",?? ????????????type:?"string"?? ????????},?? ????????{?? ????????????dname:?"ProductA",?? ????????????type:?"string"?? ????????},?? ????????{?? ????????????dname:?1000,?? ????????????type:?"number"?? ????????}],?? ????????[{?? ????????????dname:?"ShangHai",?? ????????????type:?"string"?? ????????},?? ????????{?? ????????????dname:?"ProductB",?? ????????????type:?"string"?? ????????},?? ????????{?? ????????????dname:?23451,?? ????????????type:?"number"?? ????????}],?? ????????[{?? ????????????dname:?"GuangZhou",?? ????????????type:?"string"?? ????????},?? ????????{?? ????????????dname:?"ProductB",?? ????????????type:?"string"?? ????????},?? ????????{?? ????????????dname:?87652,?? ????????????type:?"number"?? ????????}]?? ????]?? },...?? ];?? var dataModel = [{ item: "China", grid: [ [{ dname: "Beijing", type: "string" }, { dname: "ProductA", type: "string" }, { dname: 1000, type: "number" }], [{ dname: "ShangHai", type: "string" }, { dname: "ProductB", type: "string" }, { dname: 23451, type: "number" }], [{ dname: "GuangZhou", type: "string" }, { dname: "ProductB", type: "string" }, { dname: 87652, type: "number" }] ]},...];

    ?

    ?

    一個(gè)組件可以發(fā)出多種事件,同時(shí)也可以監(jiān)聽多種事件,所以我們可以為L(zhǎng)ist的下標(biāo)改變事件注冊(cè)另一個(gè)監(jiān)聽器,監(jiān)聽器為一個(gè)簡(jiǎn)單組件Panel,當(dāng)接收到這個(gè)事件后,該P(yáng)anel會(huì)根據(jù)一個(gè)隨機(jī)的顏色來重置自身的背景色(注意在List和Grid下面的灰色Panel):

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/TDYToBaby/archive/2010/06/12/1757326.html

    總結(jié)

    以上是生活随笔為你收集整理的JavaScript内核系列 第8章 面向对象的JavaScript(下)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。