顯示廣告
隱藏 ✕
※ 本文為 Knuckles 轉寄自 ptt.cc 更新時間: 2012-02-14 10:09:38
看板 Web_Design
作者 TonyQ (沉默是金)
標題 [心得] js 到 jQuery 之二:無所遁形之 selector
時間 Fri Aug  8 02:52:24 2008



        上一篇不含開頭簡介就爆了一百多字, 這篇得更精簡用詞才行.


        會想學 js的有兩種人 , 一種是希望看完之後自己會寫會改的 ,
        另一種則是希望來找些語法copy and paste的 ,

        基本上體驗部份是為後者設計的 , 而文章內文主要是寫給前者看的,
        我寫的很口語 , 希望你們以「跟程式語言聊天」的心情來看這些文字.


        jquery呢? 我會說它是對兩者都適合的,
        他可以簡單到一行就能完成 , 也能讓人很方便的去寫去改.

        希望你們看完這幾萹文章不會被誤導 , 不是所有事情都能一行被完成 ,
        但是它能讓你在思考上保持「簡單」.

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

      @前情摘要

        我們正說到 js 大部分的時間都用來異動網頁上成員的屬性 ,
        比方說換個背景顏色 , 換成消失或顯示 , 甚至移動位置 ,

        嗯 , 這聽起來不錯 , 當你正坐下來開始想思考這到底是怎麼做的 ,

        你或許會想到 , 我什麼時候要作這件事情?


      @行為的起點 ─ 事件

        這是個好問題 , 在這裡我們不妨先假設一個簡單的情境 ,
        當你按下名為芝麻開門的按鈕(button)時 , 你希望某個圖片就突然消失.

        雖然事件不是我們本章的主角 , 不過在這裡姑且當隻誤闖
        叢林的小白兔 ,  先來看這個簡單的例子吧.:)

        http://tonyq.org/jqtalk/jq2_dooropen.html


        對於 onclick 事件 , 相信你們不會全然陌生 ,
        我特地選擇使用純js撰寫 , 以保持你們可能較為熟悉的面貌 .


        在這個事件裡面 , 我們很清楚到人事物是事件最重要的三元素,
        由使用者去點擊按鈕, 而發動事件 , 接著對img做屬性的異動.

        以這個例子 , 我們是針對 #imgDoor 作
                { display:none; }跟 {display:;} 的切換


      @目標是那個元素?

        不管是這次的例子中的imgDoor或者是之前體驗的table跟各span ,
        這些都是我們事件要異動的對象, 通常我們最簡單也最常見的方法就是

        將目標物件加上一個id , 然後採用document.getElementById ,

        這字串長度共23個字 , 有大寫有小寫 ,
        還很容易跟document.getElementsByName弄錯 ,

        而且對html來說 , id要唯一的 , 設定id會造成思考上得負擔,
        雖然純js也有提供 document.gtElementsByTagName 的方法,
        但是總是需要花時間去學習 , 而且一樣有程式碼太長的問題.


      @為元素披上外衣的CSS

        讓我們先把鏡頭拉遠 , 講到這個要做出漂亮html就不能忘記的網頁夥伴,
        我們會很驚訝地發現 , 他也一樣有不曉得要針對那個網頁元件上色的問題 .


        我們可能會採用  <div style="background:red"></div>,
        我們稱之為 inline style(行內樣式) 的方式寫 ,

        為各元素上色 , 但是這跟之前 id 問題一樣 ,
        逐一設定過於繁瑣 ,  讓它失去彈性.


        於是 css 就改採用 <style type="text/css"></style> 的標籤樣式 ,
        甚至是連結到外部的 <link rel="stylesheet" href="xxx.css" /> .

        而它之所以能獨立 , 仰賴的就是 selector .


      @認識css三種充滿威力的selector

        1. id selector ,
           我們用 「#」這個字元開頭 ,緊接著它的id , 稱之為id selector .
           透過這個selector 所設定的樣式會影響到該id的元素
           (這個selector 指向應該是獨一無二的, 因為同一頁面不該有同樣id元素.)

           /*將<div id="hello"></div> 的背景改為紅色的寫法*/

           #hello{
              background:red;
           }

        2.tag selector
          你是否常常想要改變所有超連結<a>的顏色 ? 選他就對了
          當你不打任何符號,直接打上網頁標籤(tag)的名稱,
          就是採用tag selector方案.

          /*將網頁上所有div的文字顏色變成綠色*/

          div{
                color:green;
          }

        3.class selector
          這個是最常見也最具擴充性的一個selector ,
          要使用這個你必須要在元素上先加上 class="xxx" ,
          再透過 「.」開頭的字串「.xxx」指定這個元素 ,
          他跟id selector最大的差異是它的class可以有一個以上,
          且class不限定只能用在一個元素上 .

          <div class="wordtitle">wordtitle1</div>
          <div class="wordbody">word1</div>

          <div class="wordtitle">wordtitle2</div>
          <div class="wordbody">word2</div>

          /*將wordtitle的文字加上底線 , wordbody的字設為綠色*/

          .wordtitle{
                text-decoration:underline;
          }
          .wordbody{
                color:green;
          }


      @等等,我們不是在講 javascript嗎?

        沒錯 , 但這裡的selector的確跟我們主題的selector有關,
        更之前的文章中提到 , 傳統id取得元素的方案程式碼過長,

        且需要花費時間學習 , 相信各位網頁設計師可能會跟我以前一樣 ,


        會用下列這樣的工具來加速開發

        function e(strId){return document.getElementById(strId)};
        function eS(strId,show){ e(strId).style.display=show};

        之後只要呼叫 e("nodename") 就可以取得dom物件 ,
        這大概是只有id selector 的需求下最簡單直接的方案.


        但是我們除了id selector以外其實還有很多隱性需求 ,
        比方說我終於受夠充斥整個頁面幾百個該死的表格了 ,

        我現在想把整個頁面的討厭表格給移除 , 我想要tag selector !!


        jQuery就很貼心的提供了這樣的方案:


        你看 , 就像這樣
                $("table").remove();    

        /*這不是開玩笑 , 所有的表格就這樣從頁面中移除了.*/


        好吧 , 我知道一定有人會質疑 , 所以還是程式碼會說話.
        http://tonyq.org/jqtalk/jq2_tableremove.html


      @劫後餘生記

        嗯 , 我們終於成功的討伐 table 大魔王了 ,

        但是table在頁面上少說也有5~6個 , 也不完全是巢狀關係 ,
        為什麼一行就清掉了呢?


        理由是 jquery 預設取回來的資料是以陣列處理的jQuery context ,
        而你透過 jQuery context所作的任何事件(像是他提供給你的remove) ,
        都會影響到 jQuery context中所有成員 .


     @remove實在太酷了 , 但總不能一直移除東西吧 , 那他提供哪些方法呢?

        請見 jquery Document (我們之後會再針對常用的方法做介紹)
        雖然我個人是覺得這這介面很有改善空間 , 但是對基本的查詢來說夠用了.

        網址: http://docs.jquery.com/Core

        他把它的方法分成了幾大類
        jQuery Core  ,  Selectors  ,  Attributes , Traversing  ,Manipulation
        CSS  ,  Events , Effects , Ajax  , Utilities  , jQuery UI


        原則上主要特效都集中在 jQuery UI ,而其他的幾乎都是基本操作方法 .

        core是基本的迴圈取資料 , 以及提供plug-in擴充介面 ,
        plug-in 這比較進階 , 如果有餘力會寫一篇如何做自己的jquery plug-in.


        我們剛剛用的remove 則是 Manipulation 區的,
        這區主要都在講怎麼新增元素移除元素 , 甚至拿一個元素包在自己外面 ,
        或者把自己拿去加在別人裡面諸如此類 .

        基本上attributes css events selectors core manipulation 都非常常用 .

        比方說$("table").hide() 跟 style.display='none'的效果是一樣的.
              $("table").show() 則就是對應的顯示.

        remove跟hide的差異是 , 前者是show不回來的 .(從dom被移除了.)



      @等等 , 既然 selector 取的是網頁元素 , 那他是dom元素嗎?

        你或許會想知道 $("table").style.display='none' 的結果.

        答案會是 style is undefined , 因為$("table")是個 jquery Context ,
        他只能處理他提供給你的方法 , 那你如果比較習慣 js 的作法 ,

        不想查jquery 文件 ,有沒有搞頭?

        有!

        你可以透過 $("table")[0] 取得「第一個表格」的html dom物件 ,
        也就是 $("table")[0].style.display='none'會是可行的 .

        如果你想對所有裡面的元素做存取, 你也可以這麼做 .

        var jqTable=$("table");
        for(var i =0; i <jqTable.length ;++i){
                jqTable[i].style.display='none';
        }

        就純粹把它當個陣列來看.


      @超級賽亞 dom

        基本上我常戲稱 jquery context是超級賽亞 dom ,
        dom能做的事情他都能做 , 更能做它做不到的事情.

        而且他還可以幫你考慮跨平台的狀況 , 以後會介紹 .
        (糟 好像挖了不少洞給自己跳...)


      @雖然我只介紹了 tag selector , 我相信聰明如讀者您 ,
        一定也能猜到 id selector 跟 class selector 的寫法 .

        (如果有正妹的可以留電話我們私下教學 >////< (被女友拖去打))



        就跟css selector一樣 , 其實他還有支援一些css 3 selector才有的東西,
        比方說 "table:first" 可以取得第一個表格之類的 ,
        以及我目前還沒有提到的attr selector ,

        (以「[xxxx]」搜尋, 回傳網頁元件中含有xxxx屬性者 ,
          可看小弟之前寫的jquery Tooltip範例. http://0rz.tw/804x5 )


        主要是因為這些東西要逐一介紹都可以寫上五千字了,
        我的目的只是做入門介紹 , 就不這麼「複雜」了.(淺笑)


      @selector 只有這樣嗎? 好像沒什麼差?

        當然以目前講的這些東西 , 要取得目標物好像還差些什麼 ,
        我們總是常常會有這樣的狀況 , 比方說在特定table的 td 的裡面的div,

        (這樣由父結構到子結構的關係 , 有個 xml的 專有名詞xpath 可描述)


        我們也是可以混著用 , 如 $("#tableid td div") ,

        就表示搜尋 id叫 tableid 的元素裡面的 td tag裡面的 div tag.

        當然 除了父,子關係外 , 還有 「或」 的關係.

        比方說 $("#testid1,#testid2") 中間用逗號隔開表示都可以,
        也就是這樣會取得 id=testid1 跟 id=testid2的物件.


      @寫到這裡 , 這章應該是上看兩千字 , 主題不小 , 可能有點失焦 ,
        如果讀者有看不懂的 , 請儘管推文或回文 , 小弟將盡心解釋 ,
        看反應決定是不是要加一點介紹 ,


        selector 是我當初對jQuery最驚豔的一點,
        他把我從思考如何去寫更多不重複id的泥沼中給挖出來了 ,

        以及讓我在思考問題時能更加純粹 , 更能專注於我所該解決的問題.


        當然jQuery並不是唯一鑽研此道的 js lib ,
        諸如prototype.js , yui等 , 也都各有其優點 ,

        各位可選擇自己較為熟悉的 js lib 去運用 , 小弟只是獨鐘 jQuery的簡單.


      @體驗時間
        各位觀眾 , 今天我們要介紹的是 drag and drop .

        你還認為元素可以讓你在網頁上拖來拖去很炫嗎? (draggable)
        這早就已經過時了 , 現在更流行的是拖過來還要放到別的地方去.(droppable)


        至於更有趣的 sortable , 就讓我賣個關子 ,
        留著當以後想不到要寫什麼範例的壓箱寶.

        http://tonyq.org/jqtalk/jq2_dragFrog.html


--
就這樣 , have a nice time ~
下一章要介紹的是  認識可怕的事件叢林

--
        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
shingoliang:Cool!首推~~寫得很不錯:)1F 08/08 03:15
flamerecca:有心推一個2F 08/08 07:29
ybite:"透過這個selector 所設定的樣式會影響到同id的元素"3F 08/08 11:50
ybite:這樣寫不好,因為規定上兩個元素不能同id...
ckw:推,蠻容易看懂5F 08/08 12:05
TonyQ:意思是#xxxx 會影響到 id xxxx 的元素, 我修一下用詞,6F 08/08 12:05
※ 編輯: TonyQ           來自: 220.128.219.202      (08/08 12:06)
uold:好文推~~7F 08/08 13:22
shadowken:比較好奇大大是用什麼工具來寫jQuery8F 08/08 13:38
TonyQ:notepad++ , eclipse , 我是做J2EE的環境再開發...9F 08/08 13:39
TonyQ:不過基本上這些都能提供有限的幫助 , 一年前碰過aptana ,
TonyQ:他對js的支援還不錯 , 有興趣可以去玩玩 .
shadowken:自己目前是使用eclipse+Aptana來寫,不知道有沒有更好的12F 08/08 13:39
TonyQ:我自己開發JS 是已經習慣用背跟查的 , 需要用的功能也不多,13F 08/08 13:48
TonyQ:所以這邊也是沒什麼特別的工具 ... ;P
ckmarkhsu:好文推一下:)15F 08/08 16:39
MrOrz:推好文 也推超級賽亞德姆(誤)16F 08/08 17:07
chrisQQ:推好文!!17F 08/08 17:51
shyangs:要不要發佈到blog、html、或維基教科書;18F 08/08 21:27
shyangs:bbs的特性會讓好文埋沒(搜尋引擎找不到)
TonyQ:我是特地發佈在這裡的 ,但有興趣者可具名轉載 . :)20F 08/08 22:37
dreamerXYZ:幫你推  雖然我還沒能力理解!21F 08/08 22:45
ot32em:真是JQuery界的孔子啊 讓我懂好多之前看英文DOC不懂的地方!22F 08/09 04:49
Kenqr:推!23F 08/09 13:57
tellies:辛苦了,在下也剛在學,謝謝您的說明24F 09/04 21:24
Arton0306:推!25F 09/09 14:50
※ 編輯: TonyQ           來自: 61.224.239.208       (12/15 23:46)
TonyQ:更新失效連結26F 12/15 23:46

--
※ 看板: JavaScript 文章推薦值: 0 目前人氣: 0 累積人氣: 1431 
作者 TonyQ 的最新發文:
點此顯示更多發文記錄
分享網址: 複製 已複製
guest
x)推文 r)回覆 e)編輯 d)刪除 M)收藏 ^x)轉錄 同主題: =)首篇 [)上篇 ])下篇