顯示廣告
隱藏 ✕
※ 本文為 Knuckles 轉寄自 ptt.cc 更新時間: 2012-02-14 10:12:35
看板 Web_Design
作者 TonyQ (沉默是金)
標題 從 js 到 jQuery 之五:巡覽‧跳過來跳過去
時間 Sun Aug 10 23:44:25 2008



        十篇的目標看來越來接近了 , 行百里半九十 , 繼續努力. :)
        由於前面我們介紹了不少基礎知識 , 接下來的篇幅應該可簡單一點.

        ────────────────────────────────

      @瀏覽? 我以為selector就是一切了呢?

        selector是以一個根元素(通常為 document)為基礎,去尋找裡面的成員 ,
        但是這裡我們要談的是 , 從元素去找與他有關系的元素 .


        先談標準的 traversing , 也就是元素之間的跳轉關係,
        再來我們再針對jQuery談談前面談selector時,所沒有提到的一些方法.


        元素瀏覽 , 最基本的分法分為水平瀏覽跟垂直瀏覽.


      @我怎麼好像從來不知道這東西?

        前面這裡主要是介紹一些不常用的東西 , 以及為什麼他們不常用 ,
        不過並不是必備知識 , 只要知道瀏覽不僅只於selector ,還有底下提的兩種.

        但是為了後面要介紹的 jQuery幾個非常有用的方法 , 這裡還是得先帶一點基
        本知識.



      @垂直瀏覽

        我們先從比較容易了解的垂直瀏覽開始 , 基本上垂直瀏覽的本質非常接近
        selector的方案 , 我們在操作selector時多少會運用父子關係來做操作.

        也就是 父元件 <-> 子元件的瀏覽方式.


        傳統 js 的dom物件有提供 parentNode / childNodes(陣列元素)可調用,
        相信對習慣用dom 的 appendChild 新增元件的 js開發者應該不陌生.
        (當然如果你是innerHTML派的 , 也不用擔心 , 這不會有任何影響!)


      @什麼父子??那媽媽是誰??
        這...你得去問結束標籤啊(羞)>////<

        好啦 , 輕鬆一下 , 雖然相信讀者不至於對父子關係感到抽象 ,
        不過簡單的實例對理解會有所幫助的 .

        <div>
                <span> first </span>
                <span> second </span>
                <span> three </span>
        </div>

        在這個例子來說,「理論上」 (也是我們預期,此處後面會續討論.)

            childNodes

        div -------> sapn , span ,span
            <-------
            parentNode


        這其實就可以做一些應用 , 來個很熟悉的情境吧,
        比方說我可以點選一個按鈕 , 就把按鈕的父元素直接移除掉.

        你問我哪裡熟悉?我可以用一個例子馬上讓你想起來你曾經在哪看過.

        http://tonyq.org/test/testTableGird.html


      @水平瀏覽呢?
        指的是同一層級的前後瀏覽.

        讓我們在拿這個例子來看.

        <div>
                <span> first </span>
                <span> second </span>
                <span> three </span>
        </div>
        ----------------------------

        <span>first</span>下一個元素 理論上會是 <span> second </span>
        也就是同樣在div下一層的子node之間的瀏覽 , 就稱為水平瀏覽.

        在傳統js上你可以透過
                nextSibling           (貼心翻譯時間 sibling -> 兄弟姊妹)
                previousSibling

        來取得下一個跟前一個dom物件 (如果不存在 , 就會回傳null)


      @為什麼是「理論上」?

        這是個好問題 , 答案還是在於瀏覽器的相容性問題 ,
        這系列文章快變瀏覽器相容性問題大全了.

        Firefox體系下 , 預設會把純粹換行跟空白字元也當成一個 dom來解讀 ,
        而這對水平瀏覽或垂直瀏覽都會造成問題 ,  至少在2.0.0.16行為如此,
        新版有沒有異動就有賴眾朋友測試.


        有興趣的朋友可以分別用ie跟fx觀察底下的範例.
        http://tonyq.org/test/testtravsering.html
        (ie底下會是3 , 就是對應的三個span)
        (fx底下會是7 , 多了四個由換行跟空白產生的node.)


        另外在存取的時候 , 還要另外注意 table的子元素 ,  會先接到tbody,
        tbody的子元素才會接到tr td, 雖然這是標準有定義的 ,但是常被人遺忘.


      @那我們還要介紹什麼呢?

        首先我們要介紹的是 jQuery下的水平瀏覽跟垂直瀏覽 ,
        讓我用簡單數行帶過即可.


        ※垂直瀏覽部份
          $("#selectNode").parent()     /*取得最接近的父元素物件*/
          $("#selectNode").children()   /*取得下一層的子元素物件集合*/

          $("#selectNode").parents( )   /*取得全部的父元素物件*/
          $("#selectNode").contents( )   /*取得全部的子元素*/
          /*註:如果selectNode是iframe, 則contents會取得其document物件*/

        ※水平瀏覽部分

          這兩個看字義就知道是下一個跟前一個.
          $("#selectNode").next()
          $("#selectNode").prev()

          $("#selectNode").nextAll( )  /*從下一個一直到最後一個*/
          $("#selectNode").prevAll( )  /*從前一個 一直到最前面一個*/

       @那firefox下的空白跟換行字元怎麼辦?

         在這裡jQuery 預設狀況是不把空白跟換行字元算入node的 , 所以不會有
          先前所提firefox下的元素判定問題 .


          另外 , 以上所有方法全部都支援 selector 參數 .

          也就說如果是以下的狀況

          <div>
                <p id="pnode">test p1</p>
                <span>test s1</span>
                <h1>hi , i am big  </h1>
                <p>test p2</p>
                <span>test s2</span>
                <h1>hi , i am not small </h1>
          <div>

          $("#pnode").nextAll("h1").css("background","red");


          則上面兩個h1都會背景變紅色 , 但是在這裡也有一個常常會混淆的狀況 ,
          他是先執行他所應該要執行的任務 , 再針對給定的條件去做過濾(filter),

          所以 $("#pnode").next("h1").css("background","red");

          並不是會回傳下一個h1 , 而是先找到下一個後 , 過濾不是h1的元素 ,
          下一個其實是 span , 但是由於指定要h1所以被濾掉了 ,  所以實際上傳
          回的是空 context .


          這是筆者早期剛碰時曾經碰過的釘子 , 不過事實上要用filter ,
          我個人會較建議用後面所提的方式 , 所以我們接下來要介紹的是filter .


        @什麼filter ? 過濾器 ?  為什麼前面介紹 js的時候沒介紹到?

          很簡單 , 因為我還沒看過傳統 js 有能夠替代filter的方案 ,

          但是在瀏覽元素的時候 , 這甚至比本章之前所提得那些都還重要 ,


          能夠精準的挑出我們所想要的資料 的處理.



          當然筆者沒看過不代表沒有 , 如果有人有的話很歡迎來分享一下,
          筆者能想到的最多是用typeof或nodetype過濾. 但是運用起來很麻煩.


          filter 其實應該跟find一起講 , 不過我們還是先講filter.

          filter就很單純是現在的context中找出所有符合的子元素 ,

          所以比方說 $("div").filter("p") 一定會是空的 , 因為兩者沒有交集.


          另外還有一個類似的 , 就是 not , 就是不符合的條件,
          比方說 $("div,p").not("p")  取出來的結果還是只會剩div的資料.

          這裡的字串都是套用selector的規則 , 請各位看官自行發揮.


        @finder

          有沒有曾經有過這樣的想法 ?

          我手邊有一個div 物件觸發onmouseover事件 ,
          但是我想讓觸發事件元素中所有圖片加上框線.


          你可能會想到selector , 但是我有這個事件的物件有好幾個啊,
          我很難特定指定哪一個物件來處理.

          這時候你就會想要 find , 他可以幫助你在特定的 context中尋找
          子元素的資料.

          比方說  $("table").find("td")
          或者是 $("#selectNode").find("img")


          甚至於 jQuery還為他寫了簡式 ,  以前面的寫法來看 , 可以改寫成
          $("td","table")

          第一個元素是selector , 第二個元素是指定區間, 而除了直接給selector外,
          $("td", $("table"))     給定一個jQuery context也是可以接受的.
          $("td", $("table")[0])  給定一個html dom物件也是可以接受的 .


      @沒想到要取得元件有這麼大學問!

        相信看到這裡 , 不管元素躲到天涯海角 ,他都難不倒你了,

        當然還是那句老話 , 礙於篇幅有限 , 我們只挑部份出來講 ,
        剩下的請看文件 http://docs.jquery.com/Traversing/

        我想應該還要介紹給你的function 還剩下一個 ,
        $("p").add("div") 究竟會得到什麼呢?

       (答案:等同於$("p,div"))  <---欲知答案 請按 \ 關燈


      @體驗時間:
        我們今天要介紹的是blockUI ,  基本上他跟大部分的燈箱都蠻像的 ,
        不過它比燈箱更純粹了一點 ,純粹就是阻斷所有背景的事件 ,

        讓你做到鎖定的效果 , 當然重點是他也非常的簡單易用 .


        官方網站
        http://malsup.com/jquery/block/#overview


        簡易版sample
        http://tonyq.org/jqtalk/jq5_blockUI.html

--
        What do you want to have ?  / What do you have?            
        從書本中,你可以發現我的各種興趣。
        從CD中,你可以瞭解我所喜歡的偶像明星。

        或許從文字你很難以瞭解一個人,但從物品可以。
        My PPolis , My past. http://ppolis.tw/user/Tony           

--
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.132.59.247
bibo9901:原po好威 XD1F 08/10 23:54
TonyQ:希望這些介紹幫的上版友們 , 且不要嫌我洗版就好了^^a2F 08/10 23:59
legnaleurc:web design的大魔王之一就是瀏覽器相容性啊XD3F 08/11 00:00
TonyQ:想了一下 應該要說 純js本來就比較沒有dom 集合得概念 ,4F 08/11 00:03
TonyQ:所以自然就沒有filter 機制 , 只有type check .
maonenine:太強大了,應該K了不少專書6F 08/11 01:46
TonyQ:預告一下 , 下一篇我們要談 Effects. 針對一些特效的原理7F 08/11 07:49
TonyQ:做最基本的討論與剖析.
chrisQQ:友情推!9F 08/11 09:32
gpmm:推推~10F 08/11 09:45
ot32em:pushpush11F 08/11 18:08
kkc:推推推~12F 08/12 01:11
appleboy46:大推13F 08/12 14:43
Kenqr:推!14F 08/14 21:35
PHP6:push15F 08/15 10:52
ghostleader:不會覺得是洗版阿  看很多書都覺得光是一個物件取得16F 08/18 13:23
ghostleader:也沒幾本書寫的向大大一樣清楚
※ 編輯: TonyQ           來自: 61.224.239.208       (12/15 23:50)
TonyQ:更新連結18F 12/15 23:50

--
※ 看板: JavaScript 文章推薦值: 0 目前人氣: 0 累積人氣: 820 
分享網址: 複製 已複製
guest
x)推文 r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇