jQuery

技术栈
前端框架
javascriptdomajaxlegacyutility

概览

jQuery 技术栈概览

jQuery 是 John Resig 于 2006 年创建的经典 JavaScript 工具库,曾统治前端开发十余年。它简化了 DOM 操作、事件处理、Ajax 请求和动画效果,至今仍有大量网站和毕设项目在使用。

jQuery 是什么?

  • 轻量级 JavaScript DOM 操作库
  • 链式调用语法 $('.box').addClass('active').fadeIn()
  • 浏览器兼容性极佳(IE6+)
  • 丰富的插件生态

解决什么问题?

  • 原生 DOM API 繁琐(querySelector vs $)
  • Ajax 跨浏览器兼容
  • 快速给老项目/简单项目添加交互
  • 毕设后台管理页面快速开发

关键特性:

  • $() 选择器引擎
  • 链式调用
  • .ajax() / $.get() / $.post()
  • 动画:fadeIn、slideUp、animate
  • 插件:jQuery UI、DataTables、Chosen

安装

环境准备

  • 操作系统:任何支持现代浏览器的系统
  • 浏览器:Chrome / Firefox / Safari / Edge(jQuery 3.x 支持 IE9+)
  • 编辑器:任何代码编辑器均可
  • 无需 Node.js:jQuery 可直接通过 CDN 使用,也可通过 npm 在构建工具中使用

安装命令

方式一:CDN(最常用)

<!-- 最新 3.x(推荐) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.0/dist/jquery.min.js"></script>

<!-- jQuery 2.x(支持到 IE9) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@2.2.4/dist/jquery.min.js"></script>

<!-- jQuery 1.x(最兼容,旧项目) -->
<script src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>

方式二:npm

npm install jquery
// ES Module
import $ from "jquery";

// CommonJS
const $ = require("jquery");

方式三:本地文件

# 下载到项目
curl -o jquery.min.js https://code.jquery.com/jquery-3.7.0.min.js
<script src="./jquery.min.js"></script>

常见安装问题

1. $ is not defined

  • 原因:jQuery 未加载或加载顺序错误
  • 解决:确保 <script src="jquery.min.js"> 在使用 $ 的脚本之前;CDN 链接是否正确

2. 与其他库冲突(如 Prototype.js)

  • 解决
    jQuery.noConflict(); // 释放 $,仅使用 jQuery
    // 或
    (function($) {
      // 在这个闭包中安全使用 $
    })(jQuery);
    

3. CDN 加载失败时的回退

<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.0/dist/jquery.min.js"></script>
<script>
  window.jQuery || document.write('<script src="./jquery.min.js"><\/script>');
</script>

4. $(document).ready 中代码不执行

  • 原因:在 DOM 已就绪后才绑定
  • 解决:使用 $(function() { ... }) 简写,确保在 <head> 中或 <body> 底部引入脚本

示例

jQuery 动态 Todo 列表

目标

用 jQuery 实现经典 Todo 列表:添加/删除/标记完成,展示 jQuery 的 DOM 操作和事件处理能力。

完整代码

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <title>jQuery Todo</title>
  <style>
    body { font-family: system-ui; max-width: 500px; margin: 50px auto; background: #f0f4f8; }
    h1 { text-align: center; }
    .todo-form { display: flex; gap: 8px; margin-bottom: 20px; }
    .todo-form input { flex: 1; padding: 10px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; }
    .todo-form button { padding: 10px 20px; background: #3b82f6; color: white; border: none; border-radius: 6px; cursor: pointer; }
    .todo-list { list-style: none; padding: 0; }
    .todo-item { display: flex; align-items: center; gap: 10px; padding: 12px; background: white; border-radius: 8px; margin-bottom: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
    .todo-item.completed .todo-text { text-decoration: line-through; color: #999; }
    .todo-text { flex: 1; cursor: pointer; }
    .todo-delete { background: #ef4444; color: white; border: none; padding: 4px 10px; border-radius: 4px; cursor: pointer; }
    .stats { text-align: center; color: #666; margin-top: 10px; }
  </style>
</head>
<body>
  <h1>✅ jQuery Todo</h1>
  <div class="todo-form">
    <input type="text" id="todoInput" placeholder="输入待办事项...">
    <button id="addBtn">添加</button>
  </div>
  <ul class="todo-list" id="todoList"></ul>
  <div class="stats">
    共 <span id="totalCount">0</span> 项,
    已完成 <span id="doneCount">0</span> 项
  </div>

  <script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
  <script>
    $(function() {
      let todos = [
        { id: 1, text: '完成毕设开题报告', done: false },
        { id: 2, text: '阅读参考文献', done: true },
      ];
      let nextId = 3;

      function render() {
        const $list = $('#todoList').empty();
        todos.forEach(t => {
          const $item = $(`
            <li class="todo-item ${t.done ? 'completed' : ''}" data-id="${t.id}">
              <span class="todo-text">${t.text}</span>
              <button class="todo-delete">删除</button>
            </li>
          `);
          $list.append($item);
        });

        $('#totalCount').text(todos.length);
        $('#doneCount').text(todos.filter(t => t.done).length);
      }

      // 添加
      $('#addBtn').on('click', function() {
        const text = $('#todoInput').val().trim();
        if (!text) return alert('请输入内容');
        todos.push({ id: nextId++, text, done: false });
        $('#todoInput').val('');
        render();
      });

      // 回车添加
      $('#todoInput').on('keypress', function(e) {
        if (e.which === 13) $('#addBtn').click();
      });

      // 切换完成状态(事件委托)
      $('#todoList').on('click', '.todo-text', function() {
        const id = $(this).closest('.todo-item').data('id');
        const todo = todos.find(t => t.id === id);
        if (todo) { todo.done = !todo.done; render(); }
      });

      // 删除(事件委托)
      $('#todoList').on('click', '.todo-delete', function() {
        const id = $(this).closest('.todo-item').data('id');
        todos = todos.filter(t => t.id !== id);
        render();
      });

      // 初始渲染
      render();
    });
  </script>
</body>
</html>

运行步骤

  1. 复制代码保存为 index.html
  2. 直接在浏览器中打开(无需服务器)
  3. 或用 npx serve . 启动本地服务器

预期输出

  • 显示 2 条预置 Todo
  • 输入文字 → 点击添加或回车 → 新 Todo 出现
  • 点击 Todo 文字 → 切换完成/未完成(划线效果)
  • 点击删除 → 移除该项
  • 底部统计自动更新

jQuery Hello World — DOM 操作与 AJAX

目标

展示 jQuery 最经典的特性:选择器、DOM 操作、事件绑定、AJAX 请求和动画效果。

完整代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8" />
  <title>jQuery Demo</title>
  <script src="https://cdn.jsdelivr.net/npm/jquery@3.7.0/dist/jquery.min.js"></script>
  <style>
    body {
      font-family: -apple-system, 'Microsoft YaHei', sans-serif;
      max-width: 560px; margin: 40px auto;
      padding: 0 16px; background: #f8fafc;
    }
    .card {
      background: white; border-radius: 12px;
      padding: 24px; box-shadow: 0 2px 16px rgba(0,0,0,0.06);
      margin-bottom: 16px;
    }
    button {
      padding: 10px 20px; border: none; border-radius: 8px;
      font-size: 0.95rem; cursor: pointer; margin: 4px;
      transition: 0.2s;
    }
    button:hover { opacity: 0.85; }
    .btn-primary { background: #3b82f6; color: white; }
    .btn-danger { background: #ef4444; color: white; }
    .btn-success { background: #10b981; color: white; }
    input[type="text"] {
      width: 100%; padding: 10px; border: 2px solid #e2e8f0;
      border-radius: 8px; font-size: 1rem; box-sizing: border-box;
    }
    .todo-item {
      display: flex; justify-content: space-between; align-items: center;
      padding: 10px 0; border-bottom: 1px solid #f1f5f9;
    }
    .done { text-decoration: line-through; color: #94a3b8; }
    .loading { text-align: center; color: #888; padding: 20px; }
    .result { background: #f0fdf4; padding: 12px; border-radius: 8px; margin-top: 12px; }
  </style>
</head>
<body>

<div class="card">
  <h1>📜 jQuery Demo</h1>
  <p style="color:#64748b;">经典 DOM 操作 & AJAX 示例</p>

  <!-- 待办列表 -->
  <h3>📋 待办事项</h3>
  <div style="display:flex;gap:8px;margin-bottom:12px;">
    <input type="text" id="todo-input" placeholder="添加新任务..." />
    <button class="btn-primary" id="add-todo">添加</button>
  </div>
  <div id="todo-list"></div>
</div>

<div class="card">
  <h3>🌐 AJAX 请求</h3>
  <button class="btn-success" id="fetch-posts">加载文章</button>
  <div id="posts-container"></div>
</div>

<div class="card">
  <h3>✨ jQuery 动画</h3>
  <button class="btn-primary" id="btn-animate">显示/隐藏说明</button>
  <p id="animate-text" style="display:none;">
    jQuery 让动画变得极其简单:<code>.fadeIn()</code>、
    <code>.slideDown()</code>、<code>.animate()</code>。
  </p>
</div>

<script>
  // ===== 入口:DOM 就绪后执行 =====
  $(function () {
    // ========== 1. 待办事项:DOM 操作 ==========
    const $input = $("#todo-input");
    const $list = $("#todo-list");

    function addTodo(text) {
      const $item = $(`
        <div class="todo-item">
          <span>${escapeHtml(text)}</span>
          <div>
            <button class="btn-success done-btn">✓</button>
            <button class="btn-danger del-btn">✕</button>
          </div>
        </div>
      `);

      // 标记完成(事件委托不需要,这是直接绑定)
      $item.find(".done-btn").on("click", function () {
        $item.find("span").toggleClass("done");
      });

      // 删除
      $item.find(".del-btn").on("click", function () {
        $item.fadeOut(300, function () { $(this).remove(); });
      });

      $list.append($item);
    }

    $("#add-todo").on("click", function () {
      const text = $input.val().trim();
      if (text) { addTodo(text); $input.val("").focus(); }
    });

    $input.on("keydown", function (e) {
      if (e.key === "Enter") { $("#add-todo").trigger("click"); }
    });

    // 初始数据
    addTodo("学 jQuery");
    addTodo("写代码");

    // ========== 2. AJAX 请求 ==========
    $("#fetch-posts").on("click", function () {
      const $btn = $(this);
      const $container = $("#posts-container");

      $btn.prop("disabled", true).text("加载中...");
      $container.html('<div class="loading">⏳ 加载中...</div>');

      // jQuery AJAX(支持 Promise)
      $.ajax({
        url: "https://jsonplaceholder.typicode.com/posts",
        method: "GET",
        data: { _limit: 5 },
        dataType: "json",
        timeout: 5000,
      })
        .done(function (posts) {
          const html = posts
            .map(
              (p) => `
            <div class="todo-item">
              <strong>${escapeHtml(p.title)}</strong>
              <small style="color:#94a3b8">#${p.id}</small>
            </div>`
            )
            .join("");
          $container.html(`<div class="result">${html}</div>`);
        })
        .fail(function (jqXHR, textStatus) {
          $container.html(
            `<div style="color:red;">请求失败:${textStatus}</div>`
          );
        })
        .always(function () {
          $btn.prop("disabled", false).text("加载文章");
        });
    });

    // ========== 3. 动画 ==========
    $("#btn-animate").on("click", function () {
      const $text = $("#animate-text");
      if ($text.is(":visible")) {
        $text.slideUp(400);
        $(this).text("显示说明");
      } else {
        $text.slideDown(400);
        $(this).text("隐藏说明");
      }
    });
  });

  // XSS 防护小工具
  function escapeHtml(str) {
    return $("<span>").text(str).html();
  }
</script>

</body>
</html>

运行步骤

  1. 保存为 index.html
  2. 浏览器直接打开

预期输出

  • 待办列表支持添加/完成/删除(带动画)
  • 点击"加载文章"从 JSONPlaceholder API 拉取 5 篇文章
  • 显示/隐藏说明面板有 slide 动画

教程

jQuery 入门教程:现代开发者的 jQuery 指南

一、jQuery 的定位

jQuery 统治了前端开发十余年(2006-2016),它解决的核心痛点是:

  • 浏览器兼容:统一的 API 抹平 IE6/7/8/9 与 Chrome/Firefox 的差异
  • 简洁的 DOM 操作$(".class")document.querySelectorAll 短且强大
  • AJAX 简化$.ajax() 比原生 XMLHttpRequest 友好得多
  • 动画:内置 fadeslideanimate

现在(2024年),原生 JavaScript 已足够好用,但 jQuery 仍然有价值:维护遗留项目、WordPress/Shopify 主题、快速原型、Bootstrap 5 之前版本的依赖。

二、核心选择器

// 基本选择器
$("#id")        // ID
$(".class")     // 类
$("div")        // 标签
$("div, span")  // 多选

// 层级选择器
$("div p")      // 后代
$("div > p")    // 直接子元素
$("div + p")    // 相邻兄弟

// 过滤选择器
$("li:first")           // 第一个
$("li:last")            // 最后一个
$("li:eq(2)")           // 索引 2
$("li:contains('文字')") // 包含文字
$("input:checked")      // 选中状态

// 属性选择器
$("[data-id]")          // 有 data-id 属性
$("[data-id='42']")     // 精确匹配
$("[href^='https']")    // 以 https 开头

三、DOM 操作

// 读取/修改
$("#title").text("新标题");           // textContent
$("#content").html("<b>加粗</b>");    // innerHTML
$("input").val("默认值");              // value
$("img").attr("src", "new.jpg");      // 属性
$("div").css("color", "red");         // 单一样式
$("div").css({ color: "red", fontSize: "20px" }); // 多样式

// 类操作
$("div").addClass("active");
$("div").removeClass("old");
$("div").toggleClass("hidden");

// 插入
$("#list").append("<li>新项</li>");  // 末尾
$("#list").prepend("<li>首项</li>"); // 开头
$("<p>").text("Hello").appendTo("#container");

// 删除
$(".obsolete").remove();   // 彻底删除
$(".temp").empty();        // 保留元素,清空内容

四、事件处理

// 绑定事件
$("#btn").on("click", function (e) {
  e.preventDefault();
  console.log(this);     // DOM 元素(不是 jQuery 对象)
  console.log($(this));  // jQuery 对象
});

// 事件委托(动态元素也能响应)
$("#list").on("click", ".item", function () {
  $(this).toggleClass("selected");
});

// 一次性事件
$("#btn").one("click", function () {
  console.log("只触发一次");
});

// 触发事件
$("#btn").trigger("click");

// 快捷方法
$("#btn").click(fn);
$("input").keydown(fn);
$("form").submit(fn);
$("#el").hover(fnEnter, fnLeave);

五、AJAX

// 完整版
$.ajax({
  url: "/api/users",
  method: "POST",
  contentType: "application/json",
  data: JSON.stringify({ name: "张三" }),
  headers: { Authorization: "Bearer token" },
  success: function (data) { /* ... */ },
  error: function (jqXHR, status, error) { /* ... */ },
});

// 快捷方法
$.get("/api/users", { page: 1 }, function (data) {});
$.post("/api/users", { name: "张三" }, function (data) {});
$.getJSON("/api/config.json", function (config) {});

// Promise 风格(jQuery 3+)
$.ajax({ url: "/api/data" })
  .done((data) => console.log(data))
  .fail((jqXHR) => console.error(jqXHR.status))
  .always(() => console.log("完成"));

六、动画

// 预设动画
$("#box").fadeIn(400);
$("#box").fadeOut(400);
$("#box").slideDown(300);
$("#box").slideUp(300);

// 自定义动画
$("#box").animate({
  width: "300px",
  opacity: 0.5,
}, 500, function () {
  console.log("动画完成!");
});

// 链式调用
$("#box")
  .slideUp(300)
  .delay(500)
  .slideDown(300);

七、实用技巧

防抖搜索

let searchTimer;
$("#search").on("input", function () {
  clearTimeout(searchTimer);
  searchTimer = setTimeout(() => {
    $.get("/api/search", { q: $(this).val() }, renderResults);
  }, 300);
});

jQuery 插件模式

// 创建插件
$.fn.highlight = function (color) {
  return this.css("background-color", color || "#ff0");
};

// 使用
$("p").highlight("#ff6");

八、现代替代方案

jQuery 功能 原生替代
$(".class") document.querySelectorAll(".class")
$.ajax() fetch() / axios
.fadeIn() CSS transition / Element.animate()
.on("click") addEventListener
.addClass() classList.add()

九、思考题

  1. jQuery 的链式调用是如何实现的?
  2. 为什么事件委托 $(parent).on("click", ".child", fn) 对动态元素有效?
  3. 在一个已有 Vue/React 的页面中引入 jQuery 可能引发什么问题?

jQuery 毕设快速开发入门

背景

很多同学觉得 jQuery "过时了",跳过它直接学 React/Vue。但实际毕设中,大量场景只需要简单的 DOM 操作和 Ajax 请求,jQuery 恰恰是最快出活的选择。学习成本低、复制粘贴就能跑、兼容性好——特别适合时间紧迫的毕设冲刺。


核心概念

jQuery 的三句话心法

  1. 选择元素,然后操作它$('.box').addClass('active')
  2. 事件驱动$('#btn').on('click', function() { ... })
  3. Ajax 很简单$.get('/api/data', function(res) { ... })

选择器大全

$('#id')         // ID 选择
$('.class')      // 类选择
$('div')         // 标签选择
$('[name="x"]')   // 属性选择
$('.parent .child')  // 层级
$('li:first')    // 伪类

常用 DOM 操作

// 内容
$('#el').text('hello')          // 文本
$('#el').html('<b>bold</b>')    // HTML
$('#el').val()                   // 表单值

// 样式
$('#el').addClass('active')
$('#el').css('color', 'red')
$('#el').toggle()

// 创建/插入
$('<div>新元素</div>').appendTo('body')
$('#list').append('<li>item</li>')

分步操作

第一步:引入 jQuery

最简单方式——CDN:

<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>

第二步:等待 DOM 就绪

$(function() {
  // 所有 DOM 操作写在这里
  console.log('页面加载完毕');
});

第三步:Ajax 请求

// GET
$.get('/api/students', function(data) {
  data.forEach(s => {
    $('#list').append(`<li>${s.name}</li>`);
  });
});

// POST
$.post('/api/students', { name: '张三', major: 'CS' }, function(res) {
  alert('添加成功');
});

第四步:事件绑定

// 直接绑定(对已有元素)
$('#saveBtn').on('click', function() {
  const name = $('#nameInput').val();
  $.post('/api/students', { name: name });
});

// 事件委托(对动态创建的元素)
$('#list').on('click', '.delete-btn', function() {
  $(this).closest('li').remove();
});

毕设实战模式

模式一:纯静态 + jQuery 交互

适合纯前端页面、作品展示站。

HTML + CSS + jQuery CDN,零构建工具。

模式二:jQuery + Bootstrap 管理后台

Bootstrap 提供 UI,jQuery 处理表单和表格。

引入 Bootstrap CSS + jQuery + Bootstrap JS。
用 DataTables 插件做表格分页搜索。

模式三:jQuery + 后端 API

前端 jQuery 调后端接口。

$.get('/api/data') → 渲染表格
$.post('/api/form') → 提交表单

思考题

  1. 事件委托 $(parent).on('click', 'child', fn) 相比直接绑定有什么优势?
  2. 为什么 Ajax 请求要在 $(function(){}) 内部执行?
  3. jQuery 的链式调用 $el.addClass().fadeIn().text() 是怎么实现的?

小结

jQuery 虽老,但实用。当你只需要一个简单的管理后台、一个表单提交页面、一个数据展示面板时,它是最快的方式。学习它只需半天,出活只需一小时。