從“jquery”這個名字就能看出,用css/xml選擇器查詢頁面元素,是這個javascript庫賴以起家的絕活,最早可以追溯到dean edwards的cssquery,和simon willison的getelementsbyselector,但是在那個上古時代(史料記載中無正式名稱,我們可以稱之為“age of the first bubble”,或者“dhtml era”,雖然也有學者認為希臘神話中描述的黑鐵時代(iron age)就是指那段時間……dojo創始人alex russell,以及prototype創始人sam stephenson,都是來自那個時代地淫~),面對惡劣的瀏覽器環境和粗糙的web應用,這些選擇器的實現只能被當作geek的實驗,沒有應用市場。而到了05年,世界已經進入web2.0和ajax的新紀元,84年出生的天才少年john resig(555跟我同年~>_<~)在先行者的啟發下(必須承認d edwards老爺“啟發”了很多人……自己的作品卻沒機會進入主流)開始探索選擇器技術,一年后的1月15日(沒錯今天是jquery三周年生日)就在紐約的barcamp上正式發布了第一版的jquery,迅速紅遍全球,流行程度堪比搖滾巨星(我就很喜歡jquery去年發布1.2.6時搞得那個搖滾主題的主頁啞!)
在jquery的影響下,選擇器逐漸變成了javascript開發的主流需求,其他的庫不進則死,都匆匆引入選擇器,比如dojo.query,yahoo.util.selector.query,$$……甚至各大瀏覽器廠商也開始實現w3c最新的selectors api標準(包括safari3.1、firefox3.1、ie8 beta,居然連ie也實現了耶!可見這個現象的反常程度……)
但是當選擇器的實現變得無處不在五花八門的時候(我以前做的jquery迷你版里也有一個自己實現的選擇器-___-b),開發者們又有了新煩惱,他們需要統一的,能平穩遷移/升級的接口,需要最高效的實現,隨著w3c selectors api的實現,統一標準也變得更加重要和緊迫,于是john resig就像武林盟主一樣站出來開發了一個純粹而高效的選擇器引擎——sizzle,并主動貢獻給prototype, dojo, mochkit等各大門派,jquery1.3是第一個采用sizzle的正式產品,可以看到速度有顯著的提升,今后的發展非常令人期待。
sizzle反映了一種新趨勢,隨著javascript庫的逐漸成熟,一些功能開始被分離出來設計成獨立維護的引擎/核心。實際上現在的主流庫里,有很多代碼都互相借鑒,并采納blogsphere里討論出的最新最好的實現方法,比如jquery的dom ready方法就可以明顯看到這種演進,而那些涉及跨瀏覽器的實現和bug fix,尤其容易趨向于統一。有機會產生通用引擎的領域,除了css選擇器,可以預見的還有2d/3d繪圖引擎(封裝canvas,vml或svg),模板引擎,對象映射,文本解析,動畫,運動和定位相關的計算,還有一些基礎代碼,比如迭代器。
不過關于選擇器,還有一點必須指出的是,無論選擇器發展的多么高效,即使有一天能完全當作native實現來對待,也不能過度的依賴它來完成任務,滿足于寫一些腳本式的代碼,而忽視javascript語言本身的算法,數據結構和模式。這個道理其實就類似php和mysql的關系,php作為服務器端專業的web開發語言,有大量開發工作是圍繞著數據來進行,而強大的mysql已經實現很多針對數據查詢的算法和邏輯,加上php本身與其說是一門語言,不如說是工具包,導致很多初心的php程序員簡單的依賴于mysql,編程能力普遍不高,進而損害到了php程序員的平均工資……
從這個角度上來講,javascript跟php非常相像,雖然javascript本身是一門強悍而集大成的語言(記得上次去帝都參加sd2c時,天際網的cto郭應壽說“喜歡技術的人不可能不喜歡javascript”),但是多數時候都被限制在瀏覽器的sandbox里,曾經一度淪為真正的“腳本語言”,多虧瀏覽器后來施舍了dom和xhr,才讓javascript有了用武之地,所以js在很大程度上也是圍繞著dom在編程,dom是前端最重要的數據結構,有了強大的選擇器工具,很多需求只要反復調用選擇器,寫幾串腳本式的代碼就能實現,如果滿足于這種開發方式,不站在更高的角度去設計和構建應用,對于自己和自己的工作都可以說是非常危險的。
另外,設計良好的html,重要性相當于后端的數據庫設計,可以讓選擇器的使用變得更高效,并直接影響js的設計模式。我在一些項目中非常喜歡這樣的理念:在保證語義和簡潔的前提下,讓html成為一種配置文件,當需求有變化,或是在一些可復用的場合,只需要簡單的編寫html,就能自動實現相應的程序邏輯。對于選擇器的使用,還存在另一種截然相反的設計方式:在有些情況下,需要讓javascript和html盡可能的解耦合,讓同樣的代碼可以適應靈活變化的html結構,并盡可能減少dom操作,具體的例子會在下篇文章中給出。
其實本來今天最想寫的是jquery1.3中新增的live events,因為土豆網全局js里正好有一個自己實現的方法$.fn.eventproxy,兩者基于同樣的設計模式,明天有空的時候再寫算了,這篇就當作向三歲的jquery致敬。
新聞熱點
疑難解答
圖片精選