CSS 选择器和 jQuery 选择器是现代网页开发中不可或缺的两个核心技术。CSS 选择器负责样式的精准定位,而 jQuery 选择器则在 CSS 选择器的基础上扩展,提供了强大的 DOM 操作和动态交互能力。两者协同工作,共同构建了丰富、动态的网页体验。

博主博客

第一部分:CSS 选择器详解

1.1 基本选择器

元素选择器

根据 HTML 标签名选择元素。

CSS 示例:

/* 选择所有段落 */
p {
  color: #333;
  line-height: 1.6;
}

/* 选择所有一级标题 */
h1 {
  font-size: 2rem;
  margin-bottom: 1rem;
}

jQuery 应用示例:

// 选择并操作所有段落
$("p").css("color", "blue");

// 绑定点击事件到所有段落
$("p").click(function() {
  $(this).slideToggle();  // 点击时展开/收起段落
});

// 批量操作标题元素
$("h1, h2, h3").addClass("heading");

类选择器

选择具有特定 class 属性的元素。

CSS 示例:

/* 选择所有具有 "button" 类的元素 */
.button {
  padding: 10px 20px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
}

/* 元素特定类选择器 */
p.highlight {
  background-color: yellow;
}

jQuery 应用示例:

// 为所有按钮添加点击事件
$(".btn").click(function() {
  alert("按钮被点击!");
});

// 动态切换类
$(".toggle-btn").click(function() {
  $(".content").toggleClass("active");
});

// 过滤选择器
$(".item:first").addClass("first-item");
$(".item:last").addClass("last-item");

ID 选择器

选择具有特定 id 属性的元素。

CSS 示例:

/* 选择 id 为 "header" 的元素 */
#header {
  background-color: #f8f9fa;
  padding: 20px;
  border-bottom: 1px solid #dee2e6;
}

jQuery 应用示例:

// 选择并操作特定元素
$("#header").fadeIn(1000);

// 修改特定元素内容
$("#username").val("新用户名");

// 滚动到特定元素
$("#scroll-to-top").click(function() {
  $("html, body").animate({
    scrollTop: $("#top").offset().top
  }, 1000);
});

通用选择器

选择所有元素。

CSS 示例:

/* 重置所有元素的边距和盒模型 */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

jQuery 应用示例:

// 选择页面所有元素
$("*").css("transition", "all 0.3s ease");

// 在通用选择器上使用事件委托
$(document).on("click", "*", function(e) {
  console.log("点击了:", e.target.tagName);
});

1.2 组合选择器

后代选择器

选择某个元素内的所有特定后代元素。

CSS 示例:

/* 选择 article 元素内的所有 p 元素 */
article p {
  font-size: 1.1rem;
  margin-bottom: 1rem;
}

jQuery 应用示例:

// 选择特定容器内的所有链接
$("#sidebar a").addClass("sidebar-link");

// 操作表格内的所有单元格
$("table td").hover(
  function() {
    $(this).addClass("hover");  // 鼠标移入
  },
  function() {
    $(this).removeClass("hover");  // 鼠标移出
  }
);

// 深层嵌套选择
$("#main .article .content p").css("line-height", "1.8");

子元素选择器

选择某个元素的直接子元素。

CSS 示例:

/* 选择 nav 元素的直接子 li 元素 */
nav > li {
  display: inline-block;
  margin-right: 15px;
}

jQuery 应用示例:

// 仅选择导航的直接子菜单项
$("#nav > li").addClass("top-level-item");

// 操作表单的直接子输入框
$("form > input[type='text']").addClass("form-control");

// 避免选择深层嵌套元素
$(".menu > .item").click(function() {
  // 不会触发嵌套.item的点击事件
});

相邻兄弟选择器

选择紧接在另一个元素后的元素。

CSS 示例:

/* 选择紧接在 h2 后的第一个 p 元素 */
h2 + p {
  margin-top: 0;
  font-weight: bold;
}

jQuery 应用示例:

// 在标题后插入装饰元素
$("h2 + p").before('<hr class="section-divider">');

// 操作紧邻的下一个元素
$(".active + li").addClass("next-active");

// 显示/隐藏相邻元素
$(".toggle").click(function() {
  $(this).next(".content").slideToggle();
});

通用兄弟选择器

选择某个元素之后的所有兄弟元素。

CSS 示例:

/* 选择 h3 元素之后的所有同级 p 元素 */
h3 ~ p {
  color: #666;
}

jQuery 应用示例:

// 影响特定元素后的所有同级元素
$(".error ~ input").addClass("error-neighbor");

// 批量操作同级元素
$("#current-item ~ .item").css("opacity", "0.5");

1.3 伪类选择器

状态伪类

基于元素状态进行选择。

CSS 示例:

/* 链接状态 */
a:link { color: blue; }      /* 未访问链接 */
a:visited { color: purple; } /* 已访问链接 */
a:hover { 
  color: red;                /* 鼠标悬停 */
  text-decoration: underline;
}
a:active { color: orange; }  /* 激活状态 */
a:focus {                    /* 获得焦点 */
  outline: 2px solid blue;
}

/* 表单元素状态 */
input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
input:checked {
  accent-color: green;
}

jQuery 应用示例:

// 链接状态模拟
$("a").hover(
  function() { $(this).addClass("hover"); },
  function() { $(this).removeClass("hover"); }
);

// 表单状态处理
$("input:focus").addClass("focused");
$("input:blur").removeClass("focused");

// 禁用状态处理
$(":disabled").addClass("disabled-state");

// 检查复选框状态
$("input[type='checkbox']:checked").each(function() {
  console.log("已选中:", $(this).val());
});

结构伪类

基于文档结构进行选择。

CSS 示例:

/* 选择第一个子元素 */
li:first-child {
  font-weight: bold;
}

/* 选择最后一个子元素 */
li:last-child {
  border-bottom: none;
}

/* 选择第 n 个子元素 */
li:nth-child(3) {
  color: red;
}

/* 选择奇数行 */
tr:nth-child(odd) {
  background-color: #f2f2f2;
}

/* 选择偶数行 */
tr:nth-child(even) {
  background-color: #fff;
}

/* 排除特定元素 */
p:not(.exclude) {
  margin-bottom: 15px;
}

jQuery 应用示例:

// 操作特定位置的元素
$("tr:first").addClass("table-header");
$("tr:last").addClass("table-footer");

// 奇偶行处理
$("tr:even").addClass("even-row");
$("tr:odd").addClass("odd-row");

// 特定位置元素
$("li:nth-child(3)").addClass("third-item");

// 排除特定元素
$("p:not(.exclude)").addClass("normal-text");

// 选择空元素并添加内容
$("div:empty").text("这里还没有内容");

1.4 伪元素选择器

CSS 示例:

/* 在元素内容前插入内容 */
p::before {
  content: "📝 ";
  color: #666;
}

/* 在元素内容后插入内容 */
p::after {
  content: " [结束]";
  font-size: 0.8em;
  color: #999;
}

/* 选择第一行文本 */
p::first-line {
  font-weight: bold;
  font-size: 1.2em;
}

/* 选择第一个字母 */
p::first-letter {
  font-size: 2em;
  float: left;
  margin-right: 5px;
  color: #900;
}

/* 用户选中文本的样式 */
::selection {
  background-color: yellow;
  color: black;
}

jQuery 应用说明:

注意:jQuery 不能直接选择伪元素(如 ::before, ::after),因为它们不是 DOM 的一部分。但我们可以通过操作 CSS 类来间接控制伪元素。

// 通过添加/移除类来改变伪元素样式
$("p").addClass("has-icon");

// 对应的CSS
.has-icon::before {
  content: "✓ ";
  color: green;
}

// 模拟 ::first-line 效果
$(".first-line-bold").each(function() {
  var text = $(this).text();
  var firstLine = text.split('\n')[0];
  $(this).html('<span class="first-line">' + firstLine + '</span>' + text.substring(firstLine.length));
});

1.5 属性选择器

CSS 示例:

/* 选择具有 title 属性的元素 */
[title] {
  border-bottom: 1px dotted #ccc;
}

/* 选择 href 等于指定值的链接 */
a[href="https://example.com"] {
  color: green;
}

/* 选择 href 包含 "example" 的链接 */
a[href*="example"] {
  font-weight: bold;
}

/* 选择 href 以 "https" 开头的链接 */
a[href^="https"] {
  border-left: 3px solid green;
  padding-left: 5px;
}

/* 选择 href 以 ".pdf" 结尾的链接 */
a[href$=".pdf"]::after {
  content: " (PDF)";
  font-size: 0.8em;
  color: #d00;
}

/* 选择 class 包含 "btn" 的元素 */
[class~="btn"] {
  display: inline-block;
  padding: 8px 16px;
}

jQuery 应用示例:

// 选择具有特定属性的元素
$("[data-toggle]").click(function() {
  var target = $(this).data("toggle");
  $(target).toggle();
});

// 选择特定值的元素
$('input[type="email"]').addClass("email-field");

// 选择属性包含特定值的元素
$('a[href*="download"]').addClass("download-link");

// 选择属性以特定值开头的元素
$('a[href^="https"]').addClass("secure-link");

// 选择属性以特定值结尾的元素
$('a[href$=".pdf"]').append(' <i class="pdf-icon"></i>');

// 组合属性选择器
$('input[type="text"][required]').addClass("required-field");

第二部分:jQuery 专属选择器扩展

jQuery 在 CSS 选择器的基础上,扩展了许多实用的选择器:

2.1 表单选择器

// 表单元素选择器
$(":text").addClass("text-input");        // 文本框
$(":password").addClass("password-input"); // 密码框
$(":radio").addClass("radio-input");      // 单选按钮
$(":checkbox").addClass("checkbox-input"); // 复选框
$(":submit").addClass("submit-btn");      // 提交按钮
$(":reset").addClass("reset-btn");        // 重置按钮

// 表单状态选择器
$(":checked").addClass("selected");       // 选中状态
$(":selected").addClass("option-selected"); // 下拉选项选中
$(":enabled").addClass("enabled");        // 启用状态
$(":disabled").addClass("disabled");      // 禁用状态
$(":focus").addClass("focused");          // 焦点状态

2.2 内容选择器

// 包含特定文本的元素
$("p:contains('重要')").addClass("important");

// 空元素
$("div:empty").css("border", "1px dashed #ccc");

// 包含特定元素的元素
$("div:has(img)").addClass("has-image");

// 父元素选择
$("span:parent").addClass("has-children");

2.3 可见性选择器

// 可见元素
$("div:visible").fadeOut();

// 隐藏元素
$("div:hidden").fadeIn();

// 切换可见性
$(".toggle-btn").click(function() {
  $(".content").toggle();  // 或使用 fadeToggle/slideToggle
});

2.4 索引选择器

// 基于索引的选择
$("li:first").addClass("first-item");
$("li:last").addClass("last-item");
$("li:eq(2)").addClass("third-item");     // 索引从0开始
$("li:gt(2)").addClass("after-third");    // 索引大于2
$("li:lt(2)").addClass("before-third");   // 索引小于2

// 动画序列示例
$(".item").each(function(index) {
  $(this).delay(index * 200).fadeIn();
});

第三部分:选择器优先级与性能优化

3.1 CSS 选择器优先级

CSS 选择器的优先级遵循以下规则(从高到低):

优先级 选择器类型 示例 说明
最高 !important color: red !important; 避免过度使用
内联样式 style="color: blue;" HTML 元素上的 style 属性
中高 ID 选择器 #header 特异性值为 100
类/属性/伪类 .button, [type="text"], :hover 特异性值为 10
元素/伪元素 div, p::before 特异性值为 1
最低 通用选择器 * 特异性值为 0

3.2 jQuery 选择器性能优化

缓存选择器

// 不好的做法:重复查询DOM
$(".item").addClass("active");
$(".item").removeClass("inactive");
$(".item").fadeIn();

// 好的做法:缓存选择器
var $items = $(".item");
$items.addClass("active");
$items.removeClass("inactive");
$items.fadeIn();

使用 ID 选择器提高性能

// ID选择器最快
$("#main-content").find("p").addClass("content-paragraph");

// 避免过度使用的选择器
$("body div ul li a span");  // 性能差
$(".nav span");              // 性能好

事件委托

// 直接绑定(对动态添加的元素无效)
$(".item").click(function() {
  console.log("点击");
});

// 事件委托(对动态元素有效)
$("#container").on("click", ".item", function() {
  console.log("点击(支持动态元素)");
});

第四部分:综合应用示例

4.1 响应式导航菜单

CSS 样式:

.nav {
  display: flex;
  gap: 20px;
}

.nav-item {
  position: relative;
}

.nav-link {
  color: #333;
  text-decoration: none;
  padding: 10px;
  transition: color 0.3s;
}

.nav-link:hover {
  color: #007bff;
}

.nav-link::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 0;
  height: 2px;
  background-color: #007bff;
  transition: all 0.3s;
  transform: translateX(-50%);
}

.nav-link:hover::after {
  width: 100%;
}

jQuery 交互:

// 导航菜单交互
$(document).ready(function() {
  // 移动端菜单切换
  $(".menu-toggle").click(function() {
    $(".nav").toggleClass("mobile-active");
  });
  
  // 下拉菜单
  $(".has-dropdown").hover(
    function() {
      $(this).find(".dropdown").stop(true, true).slideDown(200);
    },
    function() {
      $(this).find(".dropdown").stop(true, true).slideUp(200);
    }
  );
  
  // 当前页面高亮
  var currentPage = window.location.pathname.split("/").pop();
  $('.nav-link[href="' + currentPage + '"]').addClass("active");
});

4.2 动态表单验证系统

CSS 样式:

.form-group {
  margin-bottom: 20px;
}

.form-label {
  display: block;
  margin-bottom: 5px;
  font-weight: bold;
}

.form-input {
  width: 100%;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  transition: border-color 0.3s;
}

.form-input:focus {
  outline: none;
  border-color: #007bff;
  box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.1);
}

.form-input.error {
  border-color: #dc3545;
}

.form-input.valid {
  border-color: #28a745;
}

.error-message {
  color: #dc3545;
  font-size: 0.875em;
  margin-top: 5px;
  display: none;
}

.error-message.show {
  display: block;
}

jQuery 验证逻辑:

// 表单验证
$(document).ready(function() {
  // 实时验证
  $("input, textarea, select").on("input change", function() {
    validateField($(this));
  });
  
  // 提交验证
  $("form").submit(function(e) {
    e.preventDefault();
    
    var isValid = true;
    var $form = $(this);
    
    // 验证所有字段
    $form.find("input, textarea, select").each(function() {
      if (!validateField($(this))) {
        isValid = false;
      }
    });
    
    if (isValid) {
      // 提交表单
      console.log("表单验证通过,正在提交...");
      // $form[0].submit(); // 实际提交
    } else {
      // 显示错误总结
      showFormErrors($form);
    }
  });
  
  // 字段验证函数
  function validateField($field) {
    var value = $field.val().trim();
    var $errorMsg = $field.next(".error-message");
    
    // 清除之前的错误状态
    $field.removeClass("error valid");
    $errorMsg.removeClass("show").text("");
    
    // 检查必填字段
    if ($field.attr("required") && value === "") {
      $field.addClass("error");
      $errorMsg.text("此字段为必填项").addClass("show");
      return false;
    }
    
    // 邮箱验证
    if ($field.attr("type") === "email" && value !== "") {
      var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailRegex.test(value)) {
        $field.addClass("error");
        $errorMsg.text("请输入有效的邮箱地址").addClass("show");
        return false;
      }
    }
    
    // 密码强度验证
    if ($field.attr("type") === "password" && value !== "") {
      if (value.length < 8) {
        $field.addClass("error");
        $errorMsg.text("密码长度至少为8位").addClass("show");
        return false;
      }
    }
    
    // 验证通过
    if (value !== "") {
      $field.addClass("valid");
    }
    
    return true;
  }
  
  // 显示表单错误总结
  function showFormErrors($form) {
    var errorCount = $form.find(".error").length;
    alert("表单包含 " + errorCount + " 个错误,请检查后重新提交。");
  }
});

4.3 图片懒加载与灯箱效果

CSS 样式:

.lazy-image {
  opacity: 0;
  transition: opacity 0.5s ease;
}

.lazy-image.loaded {
  opacity: 1;
}

.lightbox-overlay {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.9);
  z-index: 1000;
  justify-content: center;
  align-items: center;
}

.lightbox-image {
  max-width: 90%;
  max-height: 90%;
}

.close-lightbox {
  position: absolute;
  top: 20px;
  right: 20px;
  color: white;
  font-size: 30px;
  cursor: pointer;
}

jQuery 实现:

// 图片懒加载与灯箱效果
$(document).ready(function() {
  // 懒加载实现
  function lazyLoadImages() {
    $(".lazy-image").each(function() {
      if (isElementInViewport(this) && !$(this).hasClass("loaded")) {
        var src = $(this).data("src");
        if (src) {
          $(this).attr("src", src).addClass("loaded");
        }
      }
    });
  }
  
  // 检查元素是否在视口中
  function isElementInViewport(el) {
    var rect = el.getBoundingClientRect();
    return (
      rect.top >= 0 &&
      rect.left >= 0 &&
      rect.bottom <= $(window).height() &&
      rect.right <= $(window).width()
    );
  }
  
  // 初始加载和滚动时加载
  lazyLoadImages();
  $(window).scroll(lazyLoadImages);
  
  // 灯箱效果
  $(".lightbox-trigger").click(function() {
    var imageSrc = $(this).attr("src") || $(this).data("src");
    var $lightbox = $(".lightbox-overlay");
    var $lightboxImage = $lightbox.find(".lightbox-image");
    
    $lightboxImage.attr("src", imageSrc);
    $lightbox.fadeIn(300);
    
    // 阻止背景滚动
    $("body").css("overflow", "hidden");
  });
  
  // 关闭灯箱
  $(".close-lightbox, .lightbox-overlay").click(function(e) {
    if (e.target === this || $(e.target).hasClass("close-lightbox")) {
      $(".lightbox-overlay").fadeOut(300);
      $("body").css("overflow", "auto");
    }
  });
  
  // 键盘控制
  $(document).keydown(function(e) {
    if ($(".lightbox-overlay").is(":visible")) {
      if (e.keyCode === 27) { // ESC键
        $(".lightbox-overlay").fadeOut(300);
        $("body").css("overflow", "auto");
      }
    }
  });
});

第五部分:选择器最佳实践

5.1 保持选择器简洁高效

// 避免过度具体的选择器
$(".header .nav .menu .item a.link");  // 性能差

// 使用更简洁的选择器
$(".menu-link");  // 性能好

// 使用ID作为起点提高性能
$("#container").find(".item");  // 优于 $(".item", "#container")

5.2 链式操作提高可读性

// 链式调用
$("#element")
  .addClass("active")
  .fadeIn(300)
  .delay(1000)
  .animate({ opacity: 0.5 }, 500)
  .find("span")
  .text("已更新");

5.3 合理使用事件委托

// 对动态添加的元素使用事件委托
$("#static-container").on("click", ".dynamic-item", function() {
  // 处理点击事件
});

// 对多个事件使用同一处理函数
$("#form").on("focus blur", "input", function(e) {
  $(this).toggleClass("focused", e.type === "focus");
});

5.4 选择器性能对比

选择器类型 性能等级 示例 建议
ID选择器 优秀 $("#id") 尽可能使用ID选择器
类选择器 良好 $(".class") 大多数情况下使用
元素选择器 一般 $("div") 结合上下文使用
属性选择器 较差 $("[type='text']") 避免过度使用
伪类选择器 较差 $(":hidden") 谨慎使用
后代选择器 $("div p span") 尽量简化

第六部分:现代化替代方案

虽然 jQuery 仍然广泛使用,但现代 JavaScript 也提供了类似功能:

// 原生JavaScript选择器
document.querySelector(".class");     // 相当于 $(".class")
document.querySelectorAll("p");       // 相当于 $("p")

// 类操作
element.classList.add("active");      // 相当于 $(el).addClass("active")
element.classList.remove("active");   // 相当于 $(el).removeClass("active")
element.classList.toggle("active");   // 相当于 $(el).toggleClass("active")

// 事件监听
element.addEventListener("click", handler);  // 相当于 $(el).click(handler)

// AJAX请求
fetch("/api/data")                    // 相当于 $.ajax()
  .then(response => response.json())
  .then(data => console.log(data));

总结

CSS 选择器和 jQuery 选择器共同构成了现代网页开发的强大工具组合:

  1. CSS 选择器负责静态样式的精准定位,通过选择器优先级规则确保样式正确应用
  2. jQuery 选择器在 CSS 选择器基础上扩展,提供强大的 DOM 操作和动态交互能力
  3. 两者协同:CSS 定义外观,jQuery 控制行为,共同创建丰富的用户体验
  4. 性能优化:合理使用选择器、缓存DOM查询、使用事件委托等技巧可显著提升性能
  5. 现代化发展:虽然原生 JavaScript 提供了类似功能,但 jQuery 仍然是处理兼容性和简化开发的优秀选择

掌握 CSS 选择器和 jQuery 选择器的使用,理解它们的特性和适用场景,能够帮助开发者创建更加高效、可维护的网页应用。在实际开发中,应根据项目需求和技术栈选择合适的工具,既可以利用 jQuery 的便利性,也可以拥抱现代 JavaScript 的新特性。