jQuery进阶入门:从基础到高效开发的核心突破

在掌握jQuery基础选择器、DOM操作和简单事件后,进阶的关键是理解“为什么这么用”和“如何更高效地用”。本文围绕jQuery进阶开发的四大核心能力——链式调用原理、事件委托深化、Ajax全场景实战、插件开发入门,通过“原理拆解+实战案例+性能优化”的结构,帮你突破基础瓶颈,用jQuery解决更复杂的前端需求,同时理解背后的设计逻辑。

一、进阶核心1:吃透链式调用——从“会用”到“理解原理”

基础开发中,我们常用$('#box').css('color','red').text('内容')这类链式调用,但很少思考“为什么能链式调用”。理解其原理,能帮你避免链式调用中的常见错误,甚至自定义支持链式调用的方法。

1. 链式调用的核心原理

jQuery的链式调用本质是“方法执行后返回当前jQuery对象(this)”,而非返回undefined或其他值。例如:

// jQuery内部方法简化逻辑

jQuery.fn.css = function(prop, value) {

  // 执行设置样式的逻辑...

  return this; // 关键:返回当前jQuery对象

};

jQuery.fn.text = function(text) {

  // 执行设置文本的逻辑...

  return this; // 继续返回当前jQuery对象

};

// 因此可链式调用:方法返回的对象继续调用下一个方法

$('#box').css('color','red').text('内容');

注意:并非所有方法都支持链式调用

部分方法因需要返回“具体结果”(而非jQuery对象),不支持链式调用,例如:

val():获取输入框值时,返回字符串(如$('#input').val()),无法链式调用;

text():获取文本时,返回字符串(如$('#box').text()),无法链式调用;

find():返回新的jQuery对象(匹配子元素),支持链式调用,但操作的是新对象。

示例:链式调用的正确与错误用法

// 正确:设置值的方法支持链式调用(返回jQuery对象)

$('#input')

  .val('进阶学习') // 设置值,返回jQuery对象

  .css('color','#2563eb') // 继续操作当前对象

  .attr('placeholder','请输入内容'); // 继续操作

// 错误:获取值的方法不支持链式调用(返回字符串)

$('#input')

  .val() // 获取值,返回字符串

  .css('color','red'); // 报错:字符串没有css()方法

2. 链式调用的进阶技巧:end()与add()

当链式调用中使用find()、filter()等方法切换了操作对象后,可通过end()返回上一级对象,add()添加新的操作对象,避免重复选择元素。

方法作用示例代码

end()返回上一级jQuery对象$('#box').find('p').css('color','red').end().css('border','1px solid #ddd')

add()给当前jQuery对象添加新元素$('p').add('div').css('margin','10px')

实战案例:用end()简化多元素操作

<div id="box">

  <p class="item">子元素1</p>

  <p class="item">子元素2</p>

</div>

<script>

  $(function() {

    // 需求:给#box添加边框,同时给内部p标签设置红色文本

    // 方法1:重复选择元素(低效)

    $('#box').css('border', '1px solid #ddd');

    $('#box').find('p').css('color', 'red');

    // 方法2:用end()链式调用(高效,仅选择一次#box)

    $('#box')

      .css('border', '1px solid #ddd') // 操作#box

      .find('p') // 切换到p标签

      .css('color', 'red') // 操作p标签

      .end(); // 返回上一级#box(若后续需继续操作#box)

  });

</script>

二、进阶核心2:事件委托深化——解决动态元素与性能问题

基础开发中,我们常用click()直接绑定事件,但面对“动态生成的元素”或“大量元素”时,这种方式会失效或导致性能问题。进阶的关键是掌握on()方法的事件委托机制。

1. 为什么需要事件委托?

直接绑定事件(如$('.item').click())的两大问题:

动态元素无效:事件绑定在初始元素上,后续动态添加的元素不会继承事件;

性能开销大:若有1000个.item元素,会绑定1000个事件处理函数,占用大量内存。

事件委托的原理是“将事件绑定在静态父元素上,通过事件冒泡触发”,只需绑定1个事件,即可处理所有子元素的事件,包括动态添加的子元素。

2. 事件委托的正确语法:on()的三参数用法

基础绑定语法:$('selector').on('event', handler)(直接绑定)

事件委托语法:$('parentSelector').on('event', 'childSelector', handler)(委托绑定)

参数位置作用说明

第一个参数事件名(如'click'、'input')支持多个事件,用空格分隔(如'click mouseenter')

第二个参数子元素选择器(委托目标)必须是父元素的子元素,动态添加的子元素也会生效

第三个参数事件处理函数函数中的this指向子元素(委托目标)

实战案例1:处理动态元素事件

<ul id="list">

  <!-- 初始元素 -->

  <li class="item">初始项1</li>

  <li class="item">初始项2</li>

< href="zhiq.zhaopin.com/moment/82695346  ">

< href="zhiq.zhaopin.com/moment/82695381  ">

< href="zhiq.zhaopin.com/moment/82695400  ">

< href="zhiq.zhaopin.com/moment/82695413  ">

< href="zhiq.zhaopin.com/moment/82695426  ">

< href="zhiq.zhaopin.com/moment/82695442  ">

< href="zhiq.zhaopin.com/moment/82695450  ">

< href="zhiq.zhaopin.com/moment/82695452  ">

< href="zhiq.zhaopin.com/moment/82695457  ">

< href="zhiq.zhaopin.com/moment/82695461  ">

</ul>

<button id="addItem">添加新项</button>

<script>

  $(function() {

    // 1. 错误:直接绑定事件,动态添加的项无效

    // $('.item').click(function() {

    //  alert($(this).text());

    // });

    // 2. 正确:事件委托,绑定在静态父元素#list上

    $('#list').on('click', '.item', function() {

      alert($(this).text()); // this指向被点击的.item(包括动态添加的)

    });

    // 动态添加项

    $('#addItem').click(function() {

      const newItem = $(`<li class="item">动态项${$('#list .item').length + 1}</li>`);

      $('#list').append(newItem);

    });

  });

</script>

实战案例2:优化大量元素事件性能

<!-- 假设有100个列表项 -->

<ul id="bigList">

  <!-- 100个<li class="item">...</li> -->

</ul>

<script>

  $(function() {

    // 1. 低效:直接绑定,创建100个事件处理函数

    // $('#bigList .item').click(function() {

    //  $(this).toggleClass('active');

    // });

    // 2. 高效:事件委托,仅创建1个事件处理函数

    $('#bigList').on('click', '.item', function() {

      $(this).toggleClass('active');

    });

  });

</script>

3. 事件委托的进阶技巧:事件数据与阻止冒泡

(1)传递事件数据

通过on()的第二个参数(或第三个参数,取决于是否委托)传递数据,在事件处理函数中通过event.data获取,避免使用全局变量。

// 传递数据:给事件处理函数传递用户ID

$('#userList').on('click', '.user-item', { role: 'admin' }, function(event) {

  const userId = $(this).data('user-id');

  const userRole = event.data.role; // 获取传递的数据

  console.log(`用户ID:${userId},角色:${userRole}`);

});

(2)阻止事件冒泡与默认行为

在事件委托中,若需要阻止事件冒泡(避免父元素事件触发)或阻止默认行为(如链接跳转),需在事件处理函数中使用event.stopPropagation()和event.preventDefault()。

<div id="outer">

  <a href="https://jquery.com" class="link">jQuery官网</a>

</div>

<script>

  $(function() {

    // 父元素事件

    $('#outer').on('click', function() {

      alert('点击了外层div');

    });

    // 子元素事件委托,阻止冒泡和默认行为

    $('#outer').on('click', '.link', function(event) {

      event.stopPropagation(); // 阻止事件冒泡,外层div事件不触发

      event.preventDefault(); // 阻止默认行为,链接不跳转

      alert('点击了链接,但不跳转');

    });

  });

</script>

三、进阶核心3:Ajax全场景实战——从基础请求到复杂交互

jQuery的Ajax模块是其核心优势之一,基础开发中可能用过$.get()或$.post(),但进阶开发需要掌握更灵活的$.ajax()方法,处理“请求参数、响应解析、错误处理、加载状态”等全场景需求。

1. jQuery Ajax的核心方法对比

jQuery提供了多个Ajax相关方法,不同方法适用于不同场景:

方法作用适用场景语法示例

$.get(url, data, success)发送GET请求(获取数据)简单数据获取(如列表数据)$.get('/api/list', { page: 1 }, function(res) { ... })

$.post(url, data, success)发送POST请求(提交数据)简单数据提交(如表单提交)$.post('/api/login', { username: 'admin' }, function(res) { ... })

$.ajax(options)通用Ajax方法(支持所有配置)复杂需求(如文件上传、超时设置)$.ajax({ url: '/api/data', type: 'GET', ... })

2.$.ajax()全配置实战:处理复杂请求

$.ajax()通过配置对象支持“请求类型、参数、响应类型、超时、错误处理”等所有Ajax需求,是进阶开发的首选方法。

核心配置项说明

配置项类型作用示例值

urlString请求地址/api/user

typeString请求类型(GET/POST/PUT/DELETE)'POST'

dataObject/String请求参数{ id: 1, name: 'admin' }

dataTypeString预期响应数据类型(json/text/html)'json'(自动解析JSON)

contentTypeString请求头Content-Type'application/json'(JSON格式提交)

timeoutNumber请求超时时间(毫秒)5000(5秒超时)

beforeSendFunction请求发送前执行(如设置loading)function(xhr) { $('#loading').show(); }

successFunction请求成功执行function(res) { console.log(res); }

errorFunction请求失败执行(如网络错误、超时)function(xhr, status) { alert('请求失败'); }

completeFunction请求完成后执行(无论成功失败)function() { $('#loading').hide(); }

实战案例1:JSON格式提交与响应解析

<!-- 表单 -->

<form id="userForm">

  <input type="text" name="username" placeholder="用户名">

  <input type="password" name="password" placeholder="密码">

< href="zhiq.zhaopin.com/moment/82695464  ">

< href="zhiq.zhaopin.com/moment/82695468  ">

< href="zhiq.zhaopin.com/moment/82695473  ">

< href="zhiq.zhaopin.com/moment/82695476  ">

< href="zhiq.zhaopin.com/moment/82695479  ">

< href="zhiq.zhaopin.com/moment/82695481  ">

< href="zhiq.zhaopin.com/moment/82695485  ">

< href="zhiq.zhaopin.com/moment/82695521  ">

< href="zhiq.zhaopin.com/moment/82695529  ">

< href="zhiq.zhaopin.com/moment/82695541  ">

  <button type="submit">提交</button>

</form>

<div id="loading" style="display: none;">加载中...</div>

<script>

  $(function() {

    $('#userForm').on('submit', function(e) {

      e.preventDefault();

      // 1. 获取表单数据

      const formData = {

        username: $('[name="username"]').val().trim(),

        password: $('[name="password"]').val().trim()

      };

      // 2. 发送Ajax请求

      $.ajax({

        url: '/api/login', // 实际项目中替换为真实接口地址

        type: 'POST',

        dataType: 'json', // 预期响应是JSON格式

        contentType: 'application/json', // 请求体是JSON格式

        data: JSON.stringify(formData), // 将对象转为JSON字符串

        timeout: 5000, // 5秒超时

        beforeSend: function() {

          // 请求前显示loading

          $('#loading').show();

        },

        success: function(res) {

          // 请求成功:根据响应处理

          if (res.code === 200) {

            alert('登录成功!');

            window.location.href = '/home'; // 跳转到首页

          } else {

            alert('登录失败:' + res.msg);

          }

        },

        error: function(xhr, status) {

          // 请求失败:处理网络错误、超时等

          if (status === 'timeout') {

            alert('请求超时,请稍后重试');

          } else {

            alert('网络错误,请求失败');

          }

        },

        complete: function() {

          // 请求完成:隐藏loading(无论成功失败)

          $('#loading').hide();

        }

      });

    });

  });

</script>

实战案例2:文件上传(FormData格式)

文件上传需用FormData格式提交,$.ajax()需配置contentType: false和processData: false,避免jQuery自动处理请求体。

<!-- 文件上传表单 -->

<input type="file" id="fileInput" accept="image/*">

<button id="uploadBtn">上传图片</button>

<div id="progress" style="width: 300px; height: 10px; border: 1px solid #ddd; margin-top: 10px; display: none;">

  <div id="progressBar" style="width: 0; height: 100%; background: #4096ff;"></div>

</div>

<script>

  $(function() {

    $('#uploadBtn').click(function() {

      const file = $('#fileInput')[0].files[0]; // 获取选择的文件

      if (!file) {

        alert('请选择图片文件');

        return;

      }

      // 1. 创建FormData对象,添加文件和其他参数

      const formData = new FormData();

      formData.append('file', file); // 添加文件

      formData.append('type', 'image'); // 添加其他参数

      // 2. 发送文件上传请求

      $.ajax({

        url: '/api/upload', // 实际项目中替换为真实接口地址

        type: 'POST',

        data: formData,

        contentType: false, // 关键:不设置Content-Type,由浏览器自动处理

        processData: false, // 关键:不处理请求数据(避免将FormData转为字符串)

        xhr: function() {

          // 自定义XHR对象,监听上传进度

          const xhr = $.ajaxSettings.xhr();

          if (xhr.upload) {

            xhr.upload.addEventListener('progress', function(e) {

              if (e.lengthComputable) {

                const percent = Math.round((e.loaded / e.total) * 100); // 计算上传进度

                $('#progress').show();

                $('#progressBar').css('width', percent + '%');

              }

            });

          }

          return xhr;

        },

        success: function(res) {

          if (res.code === 200) {

            alert('上传成功!图片地址:' + res.data.url);

            $('#progressBar').css('width', '100%');

          } else {

            alert('上传失败:' + res.msg);

          }

        },

        error: function() {

          alert('上传失败,请稍后重试');

        }

      });

    });

  });

</script>

3. Ajax进阶技巧:全局事件与请求拦截

(1)全局Ajax事件

jQuery提供全局Ajax事件,可在所有Ajax请求中统一</doubaocanvas>

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容