jQuery CSS 樣式

jQuery 提供了方便的方法來操作元素的 CSS 樣式,包括取得和設定樣式值、操作 CSS 類別,以及取得元素的尺寸和位置資訊。

css() - 取得與設定樣式

取得樣式值

// 取得單一樣式值
var color = $('#box').css('color');
var bgColor = $('#box').css('background-color');
var width = $('#box').css('width'); // 返回如 "100px"

// 取得多個樣式值(返回物件)
var styles = $('#box').css(['color', 'background-color', 'font-size']);
// {color: "rgb(0, 0, 0)", background-color: "rgb(255, 255, 255)", font-size: "16px"}
css() 取得的值是計算後的樣式值(computed style),可能與原始 CSS 設定的值不同。例如顏色會轉為 RGB 格式。

設定樣式值

// 設定單一樣式
$('#box').css('color', 'red');
$('#box').css('font-size', '20px');
$('#box').css('opacity', 0.5);

// 設定多個樣式
$('#box').css({
  color: 'white',
  'background-color': '#333',
  padding: '10px',
  'border-radius': '5px',
});

// 也可以使用 camelCase
$('#box').css({
  color: 'white',
  backgroundColor: '#333',
  padding: '10px',
  borderRadius: '5px',
});

使用函式設定

// 根據舊值設定新值
$('.item').css('width', function (index, oldValue) {
  return parseFloat(oldValue) * 2 + 'px';
});

// 根據索引設定不同值
$('.item').css('opacity', function (index) {
  return 1 - index * 0.1;
});

相對值

使用 +=-= 來進行相對調整:

$('#box').css('width', '+=50px'); // 增加 50px
$('#box').css('height', '-=20px'); // 減少 20px

移除樣式

將樣式值設為空字串可以移除行內樣式:

$('#box').css('color', ''); // 移除行內 color 樣式

CSS 類別操作

操作 CSS 類別通常比直接操作 style 更好,因為樣式可以集中管理在 CSS 檔案中。

addClass() - 新增類別

// 新增單一類別
$('#box').addClass('active');

// 新增多個類別(空格分隔)
$('#box').addClass('active highlight');

// 使用函式新增
$('.item').addClass(function (index, currentClass) {
  return 'item-' + index;
});

removeClass() - 移除類別

// 移除單一類別
$('#box').removeClass('active');

// 移除多個類別
$('#box').removeClass('active highlight');

// 移除所有類別
$('#box').removeClass();

// 使用函式移除
$('.item').removeClass(function (index, currentClass) {
  return 'item-' + index;
});

toggleClass() - 切換類別

// 切換單一類別(有則移除,無則新增)
$('#box').toggleClass('active');

// 切換多個類別
$('#box').toggleClass('active highlight');

// 根據條件切換
$('#box').toggleClass('active', isActive); // isActive 為 true 則新增,false 則移除

// 使用函式切換
$('.item').toggleClass(function (index, currentClass, isToggled) {
  if (currentClass.includes('disabled')) {
    return 'locked';
  }
  return 'active';
});

hasClass() - 檢查類別

// 檢查是否具有某類別
if ($('#box').hasClass('active')) {
  console.log('元素有 active 類別');
}

// 在條件判斷中使用
$('.item').each(function () {
  if ($(this).hasClass('featured')) {
    $(this).css('border', '2px solid gold');
  }
});

類別操作範例

// 點擊切換選單
$('.menu-toggle').on('click', function () {
  $('.menu').toggleClass('open');
  $(this).toggleClass('active');
});

// 表單驗證
$('input').on('blur', function () {
  var isValid = $(this).val().length > 0;
  $(this).toggleClass('valid', isValid).toggleClass('invalid', !isValid);
});

尺寸方法

jQuery 提供多種方法來取得和設定元素的尺寸。

width() 和 height()

取得或設定元素的內容尺寸(不含 padding、border、margin):

// 取得尺寸
var width = $('#box').width(); // 數值,如 100
var height = $('#box').height();

// 設定尺寸
$('#box').width(200);
$('#box').height('150px');
$('#box').width('50%');

// 使用函式設定
$('#box').width(function (index, oldWidth) {
  return oldWidth * 1.5;
});

innerWidth() 和 innerHeight()

取得或設定元素的尺寸,包含 padding(不含 border、margin):

var innerWidth = $('#box').innerWidth();
var innerHeight = $('#box').innerHeight();

// 設定尺寸(jQuery 3.0+)
$('#box').innerWidth(200);
$('#box').innerHeight(150);

outerWidth() 和 outerHeight()

取得元素的尺寸,包含 padding 和 border

// 包含 padding 和 border
var outerWidth = $('#box').outerWidth();
var outerHeight = $('#box').outerHeight();

// 包含 padding、border 和 margin
var totalWidth = $('#box').outerWidth(true);
var totalHeight = $('#box').outerHeight(true);

// 設定尺寸(jQuery 3.0+)
$('#box').outerWidth(200);
$('#box').outerHeight(150);

尺寸方法比較

假設一個元素的 CSS 如下:

#box {
  width: 100px;
  height: 100px;
  padding: 10px;
  border: 5px solid black;
  margin: 20px;
}
方法計算內容結果
width()content100
innerWidth()content + padding120
outerWidth()content + padding + border130
outerWidth(true)content + padding + border + margin170

視窗和文件尺寸

// 瀏覽器視窗尺寸
$(window).width();
$(window).height();

// 文件尺寸
$(document).width();
$(document).height();

位置方法

offset() - 相對於文件的位置

取得或設定元素相對於文件(document)的位置:

// 取得位置
var position = $('#box').offset();
console.log(position.top, position.left);

// 設定位置
$('#box').offset({
  top: 100,
  left: 200,
});

// 使用函式設定
$('#box').offset(function (index, oldOffset) {
  return {
    top: oldOffset.top + 10,
    left: oldOffset.left + 10,
  };
});

position() - 相對於定位父元素的位置

取得元素相對於其最近的定位祖先元素(position 不為 static)的位置:

// 取得位置(唯讀)
var pos = $('#box').position();
console.log(pos.top, pos.left);
offset() 返回相對於文件的絕對位置,position() 返回相對於定位父元素的位置。position() 是唯讀的,無法設定。

scrollTop() 和 scrollLeft()

取得或設定元素的捲動位置:

// 取得頁面捲動位置
var scrollTop = $(window).scrollTop();
var scrollLeft = $(window).scrollLeft();

// 設定捲動位置
$(window).scrollTop(0); // 捲動到頂部

// 取得/設定特定元素的捲動位置
var containerScroll = $('#container').scrollTop();
$('#container').scrollTop(100);

平滑捲動到頂部

$('#scrollTop').on('click', function () {
  $('html, body').animate(
    {
      scrollTop: 0,
    },
    500
  );
});

捲動到特定元素

function scrollToElement(selector) {
  var $target = $(selector);
  if ($target.length) {
    $('html, body').animate(
      {
        scrollTop: $target.offset().top - 50, // 留 50px 空間
      },
      500
    );
  }
}

// 使用
$('a[href^="#"]').on('click', function (e) {
  e.preventDefault();
  var targetId = $(this).attr('href');
  scrollToElement(targetId);
});

實用範例

固定導覽列

var $nav = $('#navbar');
var navTop = $nav.offset().top;

$(window).on('scroll', function () {
  if ($(window).scrollTop() > navTop) {
    $nav.addClass('fixed');
    $('body').css('padding-top', $nav.outerHeight());
  } else {
    $nav.removeClass('fixed');
    $('body').css('padding-top', 0);
  }
});

回到頂部按鈕

var $backToTop = $('#backToTop');

// 顯示/隱藏按鈕
$(window).on('scroll', function () {
  if ($(this).scrollTop() > 300) {
    $backToTop.fadeIn();
  } else {
    $backToTop.fadeOut();
  }
});

// 點擊回到頂部
$backToTop.on('click', function () {
  $('html, body').animate({ scrollTop: 0 }, 500);
});

等高欄位

function equalizeHeight(selector) {
  var $elements = $(selector);
  var maxHeight = 0;

  // 重設高度後找出最高的
  $elements.css('height', 'auto').each(function () {
    maxHeight = Math.max(maxHeight, $(this).outerHeight());
  });

  // 設定所有元素為最大高度
  $elements.css('height', maxHeight);
}

// 使用
equalizeHeight('.card');

// 視窗調整時重新計算
$(window).on('resize', function () {
  equalizeHeight('.card');
});

元素位置追蹤

$('#draggable').on('mousemove', function (e) {
  var offset = $(this).offset();
  var x = e.pageX - offset.left;
  var y = e.pageY - offset.top;

  $('#coordinates').text('X: ' + x + ', Y: ' + y);
});