Contents

[jQuery] :first 和:first-child 不一樣

在寫 jQuery 或 CSS 時,:first:first-child 看起來很相似,但行為完全不同。這篇文章整理各種「第一個」選擇器的差異,讓你不再踩坑。

實際情境

假設有以下 HTML 結構:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<table>
    <thead>
        <tr><th>標題列</th></tr>
    </thead>
    <tbody>
        <tr><td>第一列</td></tr>
        <tr><td>第二列</td></tr>
        <tr><td>第三列</td></tr>
    </tbody>
</table>

對所有 tr 加入點擊跳頁,但第一列(標題列)不需要跳頁:

1
2
3
4
5
6
$('table tr').click(function () {
    location.href = 'https://example.com';
});

// 移除第一列的點擊事件
$('table tr:first-child').off('click');

jQuery :first vs :first-child

:first

:firstjQuery 專屬選擇器(非標準 CSS),從所有符合條件的元素中,只選出第一個

1
2
$('table tr:first')       // 只選 table 中的第一個 tr(標題列)
$('p:first')              // 只選頁面上第一個 p 元素

重要:first 是 jQuery 擴充的非標準選擇器,CSS 中沒有對應的寫法

:first-child

:first-child標準 CSS 選擇器,選出每個父元素的第一個子元素

1
$('table tr:first-child')   // 選出 thead 的第一個 tr,也選出 tbody 的第一個 tr

等同於 :nth-child(1)

差異對照

選擇器 選到的元素 是否為標準 CSS
tr:first 整個頁面第一個 tr ❌ jQuery 專屬
tr:first-child 每個父元素的第一個 tr ✅ CSS 標準

以上面的 table 為例:

1
2
$('table tr:first').length        // 1(只有 thead 的 tr)
$('table tr:first-child').length  // 2(thead 的 tr + tbody 的第一個 tr)

:first-child vs :first-of-type

這兩個也很容易混淆:

1
2
3
4
5
<div>
    <p>第一段</p>
    <span>span 元素</span>
    <p>第二段</p>
</div>
1
2
3
4
5
/* :first-child:父元素的第一個子元素,且必須符合選擇器 */
p:first-child    /* 選到「第一段」(它既是 p,也是第一個子元素) */

/* :first-of-type:父元素中,同類型元素的第一個 */
p:first-of-type  /* 選到「第一段」(第一個 p 元素) */

差異在於:如果第一個子元素不是 p

1
2
3
4
5
<div>
    <span>span 元素</span>
    <p>第一段</p>
    <p>第二段</p>
</div>
1
2
p:first-child    /* 選不到任何元素(第一個子元素是 span,不是 p) */
p:first-of-type  /* 選到「第一段」(第一個 p,不論位置) */

其他相關選擇器

選擇器 說明
:last-child 父元素的最後一個子元素
:nth-child(n) 父元素的第 n 個子元素(從 1 開始)
:nth-child(odd) / :nth-child(even) 奇數 / 偶數子元素(常用於表格斑馬紋)
:nth-last-child(n) 從後往前數第 n 個子元素
:only-child 只有一個子元素時選中
:first-of-type 同類型元素中的第一個
:last-of-type 同類型元素中的最後一個
:nth-of-type(n) 同類型元素中的第 n 個

實用範例:表格斑馬紋

1
2
3
/* 奇數列白色,偶數列淺灰 */
tr:nth-child(odd) { background-color: #ffffff; }
tr:nth-child(even) { background-color: #f5f5f5; }

結論

  • 如果你想選整個查詢結果的第一個:用 jQuery 的 :first
  • 如果你想選每個父元素的第一個子元素:用 :first-child(CSS 標準)
  • 如果你只想選同類型的第一個(不論位置):用 :first-of-type
  • 要寫 CSS 時,避免用 :first,因為 CSS 中沒有對應語法