使用YUI 3,建立雅虎體育TOURNEY Pick'em遊戲
2010年3月19日,6:46上午由馬克川| 發展歷程 | 關
作者簡介:馬克·川上( @ skippykawakami Twitter的 )是一個前端工程師雅虎 在 雅虎 體育隊
每年三月,在世界各地的用戶湧向雅虎幻想體育發揮我們的NCAA錦標賽支架遊戲,“ TOURNEY Pick'Em 。“這是我們最流行 的遊戲之一。
在許多方面,它也是我們最簡單的一個。 只需填寫您的選擇您所期望的球隊將贏得支架。 聽起來很容易,對不對? 以及有一個問題-有9,223,372,036,854,780,000不同的可能的方式,你可以填寫您的支架。
這種荒謬的大量介紹,以及對我們的挑戰。 你怎麼9三次方可能的組合東西,所以易於使用,用戶可以填寫他們在短短幾分鐘的括號? 答案涉及到相當數量的JavaScript引擎蓋下方,我們稱之為我們的“發動機支架”。
支架的發動機,我們已經從2004年起使用的服務很好,但後6個NCAA比賽開始顯示出它的年齡。 YUI庫根本不存在,當它被第一次寫入(對於這個問題,也沒有JSON或Firebug)。 因此,今年的比賽,我們決定,而不是我們通常做的逐步改善,我們會從頭開始。 從地面改造,給我們的機會,完全現代化的支架發動機,所以這是理所當然的,我們去了現代,因為我們可以通過使用YUI 3。 這將是雅虎幻想體育已建立使用YUI 3的首批項目之一,但我們知道,在這一點上,庫的優勢是太偉大了,通過了。 令人高興的是,新的支架引擎橫空出世,甚至比我們所希望的。
YUI的3橫空出世將非常適合建設的複雜的相互作用,我們想為支架引擎。 我們從一個完全基於點擊界面拖放接口,和YUI的3拖和能力是如此易於使用,它是實際上的第一件事,我們就工作。 我們交換接口完全由JavaScript建立一個支架的繪製與HTML和CSS,然後用JavaScript增強。 這意味著到DOM一些漂亮的深海潛水,但3 YUI的CSS選擇器的使用幾乎無處不在,這些短期的工作。
進入這個項目,我知道,拖式和3 YUI的CSS選擇器的功能將被證明是非常寶貴的,但我一直在3 YUI的許多有用的其他組件如何將驚訝。 對於這個職位,我想探討一個不得到盡可能多的關注: Y.Base 。 ( 相應的是YUI的組件基礎設施的一部分,銳的工程師Satyen德賽有一個很好的介紹,銳劇院的工具集 。)
Y.Base Pumpin“
在支架上的發動機的工作,我發現, Y.Base是非常有用的。 有兩個有價值的東西,你有自由得到Y.Base :針對屬性和事件。 均顯著比我預想的更為有用。 銳3不要求你創建自己的類時使用Y.Base ,但我的任何類建立,甚至稍不平凡的,我要去使用Y.Base作為我的出發點。
屬性
屬性使您能夠輕鬆地配置對象,當你實例化它。 如果你已經使用YUI的許多部件或公用事業,這將是熟悉的:
VAR CONFIG = { 節點:節點, '時間':0.25 “緩和”:Y.Easing.easeOut }; 阿尼姆=新Y.Anim(CONFIG);
例如在上面的config變量是在行動中的屬性的一個例子。 但你得到的不僅僅是簡化了複雜對象的實例化過程。 您可以定義的getter,setter方法,默認值等,但對我來說,真正的力量來改變屬性值。 之前和之後立即改變屬性的值,事件被解僱,讓你的代碼,以響應對象的變化。
例如,在我們的支架發動機上的對決小圖標,彈出打開一個顯示有關如何兩隊互相堆疊的信息,當用戶點擊。
表示在JavaScript彈出一類我們稱之為MatchupPanel 。 MatchupPanel已命名的屬性存儲參考所顯示的對決對象的matchup 。 在事件監聽到任何時候採取行動MatchupPanel波動matchup屬性更改。 因此,要改變我們在彈出的顯示什麼對決,我們只需要改變的matchup屬性。
MatchupPanel =功能(){ MatchupPanel.superclass.constructor.apply(這一點,參數); } MatchupPanel.NAME =“matchuppanel”; MatchupPanel.ATTRS = { “teamA”:{值:null}, “teamB”:{值:null}, “集裝箱”:{值:null}, “對決”:{值:null}, ... }; y.extend(MatchupPanel,Y.Base,{ 初始化函數(){ ... this.after(“matchupChange”,this.afterMatchupChange); }, ... afterMatchupChange:功能(E){ VAR米= this.get(“對決”); (M){ game1 = m.get(“game_1”); game2 = m.get(“game_2”); VAR team_1 game1.getValue(); VAR team_2 game2.getValue(); (team_1的&& team_2){ this.setupDisplay(team_1,team_2); this.show(); } 其他{ this.hide(); } } 其他{ this.hide(); } }, ... }
活動
Y.Base還採用銳3的自定義事件和自定義事件冒泡 。 這意味著,不僅是它方便地創建和觸發自定義事件,它很容易為其他對象的響應,他們包括停止傳播事件冒泡您所指定的目標鏈,就像泡了DOM瀏覽器事件層次。
對於括號內,我們在一些地方使用。 例如,用戶墊款隊通過幾輪,形成新的對決組合。 在第一輪比賽的第一和第二場比賽的獲勝者,在第二輪的第一場比賽中面對對方,我們有顯示對決彈出的圖標。
Matchup對象是負責顯示或隱藏圖標,而每一個遊戲內的對決是由代表TeamGame對象。 當一支球隊成為一個先進的TeamGame對象,該對象觸發一個事件。 申報的Matchup對象為目標TeamGame的事件, Matchup知道它的遊戲變化之一,可以隱藏或顯示必要的圖標。
這裡有一個(非常)簡化這個例子在行動Matchup對象:
對決=函數(){ Matchup.superclass.constructor.apply(這一點,參數); } Matchup.NAME =“對決”; Matchup.ATTRS = { “集裝箱”:{值:null}, “game_1”:{值:null}, “game_2”:{值:null}, “身份證”:{值:null}, “infotrigger”:{值:NULL} ... } y.extend(對決,Y.Base,{ 初始化函數(CFG){ VAR李= this.get(“容器”); VAR遊戲= li.all(的“li.ysf TPE遊戲”); ... / /創建這個對決TeamGame對象的 (VAR x = 0,X <games.size(); X +){ gameNode = games.item(X); VAR gameobj =新TeamGame({ “對決”:這一點, “集裝箱”:gameNode }); (this.get(“game_1”)== NULL){ this.set(“game_1”,gameobj); } 否則,如果(this.get(“game_2”)== NULL){ this.set(“game_2”,gameobj); } / /這個對決允許的TeamGame的事件泡沫 gameobj.initTarget(本); } ... }, initHandlers:函數(){ this.on(“teamgame:改變”,this.onMatchupChange); this.onMatchupChange(); }, onMatchupChange:功能(E){ / /每當這個對決的遊戲之一變化 / /這將檢查,看看是否需要的信息圖標 / /隱藏或顯示。 ... }, ... }
......為TeamGame對象:
TeamGame =(){ TeamGame.superclass.constructor.apply(這一點,參數); this.publish(“改變”,{前綴“teamgame”}); } TeamGame.NANE =“teamgame”; TeamGame.ATTRS = { “集裝箱”:{值:null}, “對決”:{值:null}, “選擇”:{值:null}, “gameid”:{值:null} ... } y.extend(TeamGame,Y.Base,{ 初始化函數(CFG){ CONT = this.get(“容器”); (續) VAR SEL = cont.one(“選擇”); this.set(“選擇”,SEL); VAR SID = cont.getAttribute(“ID”); VAR gameid,= TeamGame.getGameId(SID); this.set(“gameid”,gameid); } }, initTarget:功能(對決){ / /允許對決是本場比賽的事件的目標。 TARG =對決| | this.get(“對決”); this.addTarget(TARG); }, setValue方法:功能(VAL){ / /設置給定值的選擇菜單。 / /這是什麼時幕後發生 / /用戶,使他們的選秀權。 VAR oldValue = this.getValue(); VAR SEL = Y.Node.getDOMNode(this.get(“選擇”)); VAR OPTS = sel.options; VAR selIdx = NULL; (VAR X = 0,X <opts.length; X + +){ (OPTS [X]。價值== VAL){ selIdx = X; } } (selIdx!== NULL){ sel.selectedIndex = selIdx; VAR newValue = this.getValue(); gameid = this.get(“gameid”); this.fire(“teamgame:改變”,{ “遊戲”:gameid “老字號”:oldValue “新”:newValue }); 返回selIdx; } 返回false; }, 的getValue:函數(){ 選擇this.get(“選擇”); 返回parseInt(select.get(“值”)); }, ... }
通過組合成一個易於擴展的類的事件和屬性, Y.Base需要照顧了很多管道需要一個複雜的網絡應用程序。 對我來說,這最大的好處是,我可以勾畫出一個快速的圖框和箭頭,我多麼希望我的應用程序工作,並迅速把它轉換成工作的JavaScript。
如果你想看到所有(及以上)在行動,還是有時間為我們的其他NCAA比賽,“簽署了第二機會TOURNEY Pick'Em “。 而這一次是更容易一些,還有只有32,768方式填寫的支架。
共享和擴展: 書籤del.icio.us Digg它! | reddit!
還沒有評論
很抱歉,評論已被封閉,在這個時候。


