文章目錄
- 使用方法
- 工作原理
- 樣本:菜單效果
- 檔案下載及更新說明:
這很酷,因為這使你可以僅通過 css來對錶格行(<tr>)應用滑鼠滑過事件(mouseover)時的特殊效果。然而,萬惡的IE,對 :hover偽類頂多隻提供了有限的支援,具體支援的程度要取決於你的IE瀏覽器的具體版本。
Whatever:hover 是一個小小的指令碼,它可以迅速、自動地為IE6,IE7,IE8添加標準的 :hover、:active 和:focus 偽類支援。第三版引入了 ajax 支援,意味著通過 javascript動態添加到文檔中的任意html元素也同樣可以在IE中響應 :hover、:active 和 :focus 樣式。
如果你已經對使用 whatever:hover 很熟練,現在只是想下載它,你可以直接跳轉到擷取最新版本。而對於其它想深入瞭解它的人,請繼續閱讀。
使用方法
你只需要將 whatever:hover 連結到 body 元素就可以了。注意這裡的 behavior 屬性中的 URL 是相對於 html 檔案的,而不是像背景圖片地址一樣是相對於 css 檔案的路徑。
body { behavior: url("csshover3.htc"); }
工作原理
所有的瀏覽器都提供了一些方法,讓你用 javascript 查詢樣式表中定義好的規則或者動態地插入新規則。正常情況下,IE對所有它不支援的規則返回 “unknown”。例如:一條關於 “div p:first-child” 的規則將會被改成 "divp:unknown”, 而一條關於 "p a[href]” 的規則將整體地作為 "unknown" 返回。幸運的是 IE 把 :hover偽類認為是它支援的樣式規則,並且會將它保持原樣。
IE 還支援所謂的行為(behaviors),不僅包括預定義的功能比如動態載入內容或者持續資料存放區,也包括你可以在一個尾碼為 .htc 或者 .hta 為的檔案中建立的自訂行為。這些行為通過 css 實現與 html 節點關聯,並“增強”這些被指定行為中的樣式選取器選中的節點。
綜上所述,建立一個行為來尋找樣式表中 IE 不支援的元素,並以一些其它手段“欺騙”影響的到元素讓它們應用樣式表中關聯的樣式。這個複雜的操作中包含的步驟大致可以描述為:
- 在所有的樣式表中搜尋 IE 不支援的 :hover 偽類規則;
- 插入一條 IE 支援的,例如帶 class 名稱的新規則;
- 最後,設定指令碼事件來切換目標元素的 class 名稱。
通過這種方式,:hover、:active 和 :focus 就可以得到(IE 的)支援了。而作為開發人員,你除了包含這個行為以外不需要做任何事。所有的工作都將自動完成。
與第1版和第2版比較,第3版對動態加入的 html (ajax) 也同樣支援。另外還有一個改動是原來第1版和第2版採用的是在頁面載入事件中主動搜尋影響到的元素,而在第3版中改為藉助運算式(expressions)讓節點自己回調。關於這部分你可以閱讀帶注釋的版本擷取更多細節。
樣本:菜單效果
:hover 一個很常見的用途就是用列表建立菜單系統。用這個行為來建立一個兩級的菜單系統是再容易不過的事情了。例如,如果你從 suckerfish dropdown (一個帶有下拉式功能表的網頁,關於這個頁面和效果的描述,參見 A List Apart article)上把 javascript 刪除掉了,它仍然能正常工作。
但是多級的菜單需要做不同的處理。這是由於 IE 不支援子選擇符 ‘>',子選擇符可以完美地顯示下級子功能表,而不是連更深層的菜單一起顯示出來。
li:hover > ul { /* 在 IE 下無效 */ }
有一種可供選擇的方法可以只使用簡單的子孫選擇符來類比這種行為(主要是針對 IE)。還有種不太成熟的方法是應用多個類定義,但是更簡單的方法是利用 CSS 選擇符的不同優先順序(specificity).每一條 css 規則都有特定的重要等級,這個等級可以簡單地根據一條規則中的不同元素來計算。以元素名稱為基準值 “1″,類、偽類和屬性選擇符重要性(權重)為 “10″,然後元素 id 為 “100″。比如下面的例子。
ul ul { display:none; }
li:hover ul { display:block; }
這樣做能夠生效的原因,就是選擇符的優先順序不同。第一條規則只包含兩個元素名稱,這樣它的權重值(優先順序)就是2。第二條規則也包含兩個元素名稱,但是 :hover 偽類的權重值(優先順序)是10,所以加起來的值就是12。由於第二條規則比第一條規則優先,因此被滑鼠滑過的 li 元素內部的ul 將被顯示。
那麼這個對於解決 >子選擇符的問題有什麼協助呢?是這樣,如果一條權重值(優先順序)為12的規則定義所有的子功能表都要顯示,我們只需要建立一條權重值(優先順序)大於12的規則來把下一級的菜單隱藏起來。然後,那個菜單又需要另一條優先順序更高的規則來顯示,一直迴圈下去。對於3級的導航來說,需要的 css代碼短得讓人意外:
/* 2 和 13 */
ul ul, li:hover ul ul { display:none; }
/* 12 和 23*/
li:hover ul, li:hover li:hover ul { display:block; }
這種方式可以無需附加任何類樣式實現無限級嵌套菜單(4級或更多級需要需要繼續添加更多規則)。
指令碼事件的效能最佳化
現在還剩下一件事需要考慮。.htc 檔案在所有樣式表檔案中搜尋 :hover 規則,並且按照 css 檔案的定義對所有它認為需要用指令碼處理停留效果的元素附加滑鼠滑過和移出事件。為了找出這些(被影響的)元素,所有去掉 :hover 偽類選擇到的元素以及被 :hover 偽類修飾的元素本身,都會被選擇並且進行處理。一條類似這樣的規則
#menu li:hover ul { ... }
…將會被調整成下面這樣來尋找所有可能需要響應滑鼠滑過事件的元素:
#menu li { ... }
很顯然這會選中整個菜單中的每一個 <li>元素,並對其中一大堆不需要滑鼠事件(在當前情況下)的元素附加事件。這個問題可以很輕鬆地得到解決,我們可以對包含子功能表的列表元素添加一個類樣式,比如 "folder"。這樣一來,調整(去除:hover)之後的樣式規則變成了
#menu li.folder { ... }
…可以高效地直接選中那些真正需要事件的元素。缺點是為了改善指令碼的效能,你需要添加一個類樣式(這個類樣式的添加純粹是為了視覺效果,而且放棄了li:hover 方式實現菜單的通用性)。但是,從另一個角度考慮的話,也許你反正也要用一個類來把這些列表元素與普通元素區別開來,那就無所謂了。
為了直觀地說明上述問題,請查看綜合樣本。希望你喜歡。
檔案下載及更新說明:
檔案下載:
Version 3.11 (:hover, :active and :focus)
(:hover, :active 和 :focus)
Minified, 2.8K (right click & save) | commented, 9.7K | both, zipped
Version 1.42.060206 (:hover and :active) download | view
Version 2.02.060206 (1.42 and :focus) download | view
說明:
說明1:如果在使用 whatever:hover 的過程中遇到問題,請 讓我知道! 由於第3版比較新,可能會存在一些無法預知的問題。
說明2:確保你的web伺服器把 htc 檔案按照 text/x-component 的 mime類型發送。關於這方面的更多資訊,可以參閱 Aldo的個人部落格。如果你的主機支援 .htaccess 檔案,可以添加下面這行代碼:
AddType text/x-component .htc
說明3:第三版支援在 IE6 以上版本中使用 :hover 和 :active,對 IE7 和 IE8 還支援:focus。由於運算式(expression)在 IE8 標準模式下不支援,所以 whatever:hover 只在 IE8 的怪異模式(Quirks Mode) 下運行。實際上在 IE8 標準模式中也根本不需要這個指令碼了。
說明4:如果使用這個指令碼之後網頁變慢,請嘗試對更加具體的選擇符運用 :hover偽類,比如添加元素名稱、使用元素id,或者類名稱。例如:"div#someId li.group:hover”, 而不要只用".group:hover”。這樣能夠很大程度上減少搜尋和解析時間,並能減少需要應用的事件。請閱讀 效能最佳化 獲得更多資訊。
說明5:第2版也支援 :focus 偽類,僅限於 A、INPUT、和 TEXTAREA元素。但是,由於類似"input:focus" 這樣的選擇符被 IE 的樣式表對象返回為 "input:unknown",指令碼將基於這些 "unkonwn"規則來附加獲得焦點和失去焦時間點事件,這個問題同樣存在於其它瀏覽器無法識別的偽類。因此,使用2.0版本的時候,你無法在 IE 中對A、INPUT和 TEXTAREA元素應用瀏覽器無法識別的偽類,因為他們統統都會被處理成獲得焦點樣式。如果你確實需要這個功能,請使用1.4版或者3.0版。
在 Naar Voren (一個關於web開發的德語網站)上,有我用德語寫的一篇關於用純css 在菜單系統中使用 :hover 的更詳細的文章(德語版)。對於不懂德語的網友,可以查看該文章的英文翻譯版。
非常感謝 Arnoud Berendsen 和 Martin Reurings 提供的創意和支援,感謝 Robert Jan Verkade 和 Naar Voren 上的朋友們發表我的文章,還要感謝 Eric Meyer 對這個指令碼給予支援和在他的書裡提到我的這個網頁(指 《Eric Meyer談CSS(卷2)》 第六章》——譯者注)。
作者:peter ned 原文:whatever:hover
譯者:小李刀刀 首發:Whatever:hover – 無需javascript讓IE支援豐富偽類
轉載請註明出處。
上面的檔案,指令碼之家打包