最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Web標(biāo)準(zhǔn)的UI組件 — 樹狀菜單(2)

 更新時(shí)間:2006年09月18日 00:00:00   作者:  
從這篇開始,你需要擁有一些Javascript和DOM相關(guān)的知識(shí)才能順利地學(xué)習(xí)下去。由于Javascript和DOM都不是三言兩語(yǔ)可以說(shuō)完的東西,如果你對(duì)它們還不熟悉,請(qǐng)先到這里學(xué)習(xí)一下再繼續(xù):Javascript在線教程(英文)、DOM在線教程(英文)。

getElementsByClassName()

  為了從一大堆HTML代碼中找出我們的樹狀菜單(也許有多個(gè)),我們先來(lái)實(shí)現(xiàn)一個(gè)通過(guò)className找DOM節(jié)點(diǎn)的方法:getElementsByClassName。這是對(duì)瀏覽器自有DOM方法的一個(gè)簡(jiǎn)單但實(shí)用的擴(kuò)充。

  此方法有兩個(gè)參數(shù):ele指出以哪個(gè)DOM節(jié)點(diǎn)為根節(jié)點(diǎn)尋找(也就是說(shuō)只找ele的子節(jié)點(diǎn)),className指出符合條件的節(jié)點(diǎn)的class屬性中必須包含怎樣的className。它的返回值是一個(gè)數(shù)組,存放了所有符合條件的節(jié)點(diǎn)。

function getElementsByClassName(ele,className) {
 //獲取所有子節(jié)點(diǎn)
 if(document.all){
  var children = ele.all;
 }else{
  var children = ele.getElementsByTagName('*');
 }
 //遍歷子節(jié)點(diǎn)并檢查className屬性
 var elements = new Array();
 for (var i = 0; i < children.length; i++) {
  var child = children[i];
  var classNames = child.className.split(' ');
  for (var j = 0; j < classNames.length; j++) {
   if (classNames[j] == className) {
    elements[elements.length] = child;
    break;
   }
  }
 }
 return elements;
}

  最前面的一個(gè)if-else語(yǔ)是為了兼容IE5(IE5不能運(yùn)行document.getElementsByTagName('*'))。需要注意的是千萬(wàn)不要用瀏覽器檢測(cè)的方法來(lái)寫腳本,而應(yīng)該直接使用將要用到的語(yǔ)句來(lái)測(cè)試是否可以執(zhí)行,如果返回值為nullundefined,那再換一種方法。這樣的腳本可以有更好的兼容性,也更健壯。

  elements[elements.length] = child;,這句同樣是為了兼容IE5才沒(méi)有使用數(shù)組的push方法。如果你一定要使用push方法,那么可以在執(zhí)行getElementsByClassName()之前先重載一遍push方法。代碼如下:

Array.prototype.push = function(value){
 this[this.length] = value;
}

  注:原本我希望getElementsByClassName也能像push方法一樣寫,比如HTMLElement.prototype.getElementsByClassName = ...。不過(guò)實(shí)際操作的時(shí)候發(fā)現(xiàn)在運(yùn)行時(shí)HTMLElement這個(gè)對(duì)象并不是固定的,每種tag似乎都不一樣,只能作罷。如果你有解決方案請(qǐng)告訴我,謝謝。

  現(xiàn)在我們就可以方便地找出頁(yè)面上所有的樹狀菜單了:

var trees	= getElementsByClassName(document,'TreeView');
for(var i=0;i<trees.length;i++){
 alert('我是第' + i + '個(gè)樹狀菜單');
 //在這里可以更細(xì)致地處理每一個(gè)樹狀菜單
}

  最后把上面這幾句加到window.onload事件中運(yùn)行,以便文檔一加載完就對(duì)樹狀菜單進(jìn)行初始化。完整的代碼請(qǐng)查看下面例子的源代碼。

  查看效果(例1)

區(qū)分樹枝與樹葉

  在上一篇中我們說(shuō)到樹枝和樹葉的區(qū)別就是這個(gè)節(jié)點(diǎn)有沒(méi)有子節(jié)點(diǎn),所以判斷樹枝和樹葉的方法也可以從這個(gè)角度來(lái)考慮。一個(gè)比較直觀的方法就是遍歷整個(gè)樹狀菜單的DOM樹(注意這里兩個(gè)“樹”的區(qū)別),看看每個(gè)節(jié)點(diǎn)是不是擁有子節(jié)點(diǎn),如果有的話我們就給這個(gè)節(jié)點(diǎn)一個(gè)專門的class以示區(qū)分。我們這里用一種比較取巧的方法,就是判斷各個(gè)節(jié)點(diǎn)的innerHTML中有沒(méi)有出現(xiàn)字符串'<ul>'。如果有的話,那么很顯然它擁有一個(gè)或多個(gè)子節(jié)點(diǎn)。

var trees	= getElementsByClassName(document,'TreeView');
for(var i=0;i<trees.length;i++){
 //先把所有的節(jié)點(diǎn)找出來(lái)
 var nodes = trees[i].getElementsByTagName('LI');
 //判斷各個(gè)節(jié)點(diǎn)是否有子節(jié)點(diǎn)
 for(var j=0;j<nodes.length;j++){
  if(nodes[j].innerHTML.toLowerCase().indexOf('<ul>') > -1)
   nodes[j].className += 'Open';
 }
}

  這里給每個(gè)樹枝加了一個(gè)className:Open,因?yàn)槲覀儸F(xiàn)在還不能打開關(guān)閉樹枝,所以只要是樹枝那就是open的。當(dāng)然后面我們會(huì)用到Close的:)。相應(yīng)的修改一下CSS,給樹枝一個(gè)帶減號(hào)的圖標(biāo),表示它是打開的:

.TreeView li.Open{
 background:transparent url(opened.gif) 12px 2px no-repeat;
}

  查看效果(例2)

高亮選中項(xiàng)

  接下來(lái)實(shí)現(xiàn)把當(dāng)前選中的樹枝(或樹葉)高亮的功能。有兩個(gè)時(shí)候需要高亮:菜單初始化的時(shí)候和點(diǎn)擊某個(gè)菜單項(xiàng)的時(shí)候。

  初始化的時(shí)候比較容易處理,直接給需要高亮的節(jié)點(diǎn)一個(gè)特殊的Class即可,比如“Selected”:

.TreeView li.Selected a:link,
.TreeView li.Selected a:visited,
.TreeView li.Selected a:hover,
.TreeView li.Selected a:active{
 background-color:#05F;
 color:#FFF;
 text-decoration:none;/*去除下劃線*/
 cursor:default;/*讓光標(biāo)變?yōu)槠胀^,假裝是不能點(diǎn)的^_^*/
 padding:0 2px;/*為了美觀考慮,也可以不要這句*/
}

  查看效果(例3)

  這里有幾點(diǎn)可能還需要補(bǔ)充說(shuō)明一下:

  1. 選擇器(Selector)的前面為什么要加上.TreeView,這不是冗余代碼嗎?
    在這個(gè)例子中確實(shí)是冗余代碼,但在實(shí)際項(xiàng)目中,一個(gè)頁(yè)面上可能會(huì)有各種不同的組件,比如還有一個(gè)菜單,被選中的菜單項(xiàng)也用.Selected來(lái)表示。這時(shí)就需要在選擇符的前面先指出是什么組件的選中項(xiàng)以防沖突。當(dāng)然還有其他的解決辦法,比如這里的類不取名為Selectd,改為TreeSelected或者其他什么的,但是這樣做人為的把命名方案復(fù)雜化了,我個(gè)人不推薦這樣做。
  2. 選擇器為什么分作四行來(lái)寫?
    因?yàn)槲覀冎耙呀?jīng)設(shè)置過(guò)a的樣式,為了提高優(yōu)先級(jí)重載舊的樣式,所以需要指定a的四種偽狀態(tài)(還有其他提高優(yōu)先級(jí)的辦法,關(guān)于優(yōu)先級(jí)算法,在《網(wǎng)站重構(gòu)》一書中有詳細(xì)說(shuō)明)。
  3. Selected為什么要用在li上,而不直接用在a上?
    這又是一個(gè)不太容易說(shuō)明白的地方,因?yàn)楹艽蟪潭壬纤且环N個(gè)人習(xí)慣,只是我個(gè)人覺得這樣做更合適一些。事實(shí)上,寫在li上或a上都是可以的,至少看上去(表現(xiàn)層的視角)不會(huì)有太大的區(qū)別,但是如果你從“表現(xiàn)層”中跳出來(lái),站在“結(jié)構(gòu)層”的視角來(lái)看,無(wú)論這個(gè)菜單的樹結(jié)構(gòu)還是DOM結(jié)構(gòu),一個(gè)節(jié)點(diǎn)都是由一個(gè)li來(lái)表達(dá)的,a只不過(guò)是這個(gè)節(jié)點(diǎn)內(nèi)的更細(xì)節(jié)的部分。雖然我最終是希望給a指定一個(gè)特殊的樣式(為什么不指定給li?你可以自己試一下),但從XHTML結(jié)構(gòu)來(lái)說(shuō),這個(gè)class="Selected"還是寫在li上更合適。(上帝保佑我說(shuō)清楚了……)

下一篇講什么?

  這篇文章是我第一次加入Javascript內(nèi)容,不是很清楚是說(shuō)淺了還是說(shuō)深了,請(qǐng)大家在右邊留言告訴我你的想法。從下一篇開始,我們開始進(jìn)入部署鼠標(biāo)事件和響應(yīng)鼠標(biāo)事件方面的內(nèi)容。也許從下下篇開始再加入一些Javascript面向?qū)ο缶幊痰膬?nèi)容,待定待定……h(huán)ehe^_^

相關(guān)文章

  • JS實(shí)現(xiàn)簡(jiǎn)單易用的手機(jī)端浮動(dòng)窗口顯示效果

    JS實(shí)現(xiàn)簡(jiǎn)單易用的手機(jī)端浮動(dòng)窗口顯示效果

    這篇文章主要介紹了JS實(shí)現(xiàn)簡(jiǎn)單易用的手機(jī)端浮動(dòng)窗口顯示效果,涉及javascript針對(duì)頁(yè)面元素的動(dòng)態(tài)操作相關(guān)技巧,適用于做廣告展示,需要的朋友可以參考下
    2016-09-09
  • uniapp中uni.request(OBJECT)接口請(qǐng)求封裝實(shí)例代碼

    uniapp中uni.request(OBJECT)接口請(qǐng)求封裝實(shí)例代碼

    在開發(fā)的時(shí)候經(jīng)常會(huì)用到前端請(qǐng)求后端接口,每次的請(qǐng)求都會(huì)出現(xiàn)地址不一樣,參數(shù)不一樣,方式不一樣等等情況,下面這篇文章主要給大家介紹了關(guān)于uniapp中uni.request(OBJECT)接口請(qǐng)求封裝的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • Bootstrap 3瀏覽器兼容性問(wèn)題及解決方案

    Bootstrap 3瀏覽器兼容性問(wèn)題及解決方案

    這篇文章主要為大家詳細(xì)介紹了 Bootstrap 3 瀏覽器兼容性問(wèn)題及其對(duì)應(yīng)的解決方案,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • 探討JavaScript語(yǔ)句的執(zhí)行過(guò)程

    探討JavaScript語(yǔ)句的執(zhí)行過(guò)程

    本文給大家介紹JavaScript語(yǔ)句的執(zhí)行過(guò)程的相關(guān)知識(shí),對(duì)js語(yǔ)句執(zhí)行過(guò)程的相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2016-01-01
  • 前端實(shí)現(xiàn)圖片或視頻預(yù)覽的三種方法總結(jié)

    前端實(shí)現(xiàn)圖片或視頻預(yù)覽的三種方法總結(jié)

    在JavaScript中實(shí)現(xiàn)前端圖片上傳即時(shí)預(yù)覽功能是一項(xiàng)常見的需求,特別是在網(wǎng)頁(yè)交互設(shè)計(jì)中,這篇文章主要給大家介紹了關(guān)于前端實(shí)現(xiàn)圖片或視頻預(yù)覽的三種方法,需要的朋友可以參考下
    2024-06-06
  • 前端圖片加載錯(cuò)誤的多種原因分析

    前端圖片加載錯(cuò)誤的多種原因分析

    在瀏覽網(wǎng)頁(yè)或使用應(yīng)用程序時(shí),圖片加載失敗是一個(gè)常見的問(wèn)題,下面這篇文章主要介紹了前端圖片加載錯(cuò)誤的多種原因分析的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-03-03
  • layui使用及簡(jiǎn)單的三級(jí)聯(lián)動(dòng)實(shí)現(xiàn)教程

    layui使用及簡(jiǎn)單的三級(jí)聯(lián)動(dòng)實(shí)現(xiàn)教程

    這篇文章主要給大家介紹了關(guān)于layui使用及簡(jiǎn)單的三級(jí)聯(lián)動(dòng)的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • nodejs實(shí)用示例 縮址還原

    nodejs實(shí)用示例 縮址還原

    nodejs最近好紅火,我也趁寒冷天氣在nodejs的火爐邊取暖一下。縮址還原實(shí)現(xiàn)代碼。
    2010-12-12
  • JavaScript實(shí)現(xiàn)點(diǎn)擊文字切換登錄窗口的方法

    JavaScript實(shí)現(xiàn)點(diǎn)擊文字切換登錄窗口的方法

    這篇文章主要介紹了JavaScript實(shí)現(xiàn)點(diǎn)擊文字切換登錄窗口的方法,涉及javascript操作div層及相關(guān)樣式的技巧,需要的朋友可以參考下
    2015-05-05
  • JS實(shí)現(xiàn)簡(jiǎn)單的二維矩陣乘積運(yùn)算

    JS實(shí)現(xiàn)簡(jiǎn)單的二維矩陣乘積運(yùn)算

    這篇文章主要介紹了JS實(shí)現(xiàn)簡(jiǎn)單的二維矩陣乘積運(yùn)算方法,涉及JavaScript基于數(shù)組操作實(shí)現(xiàn)矩陣運(yùn)算的功能,需要的朋友可以參考下
    2016-01-01

最新評(píng)論

新昌县| 千阳县| 黄浦区| 新巴尔虎左旗| 布拖县| 柳州市| 东乌珠穆沁旗| 枣阳市| 安塞县| 观塘区| 中西区| 麦盖提县| 普陀区| 伊宁市| 大兴区| 阿勒泰市| 嫩江县| 涞水县| 阜新| 图木舒克市| 乌拉特后旗| 行唐县| 阳原县| 延安市| 新泰市| 顺昌县| 临城县| 巴青县| 夏邑县| 星座| 喜德县| 天津市| 麻城市| 台安县| 中宁县| 安丘市| 库尔勒市| 湖北省| 丹东市| 龙南县| 富民县|