【水平:编写简单的JQuery】用一篇文章精通JQuery

在这里插入图片描述

jQuery选择器讲解

让我用生活中的例子来帮你理解jQuery选择器,就像我们整理衣柜一样。

基础选择器 - 就像分类整理衣物

  1. ID选择器 ($("#id"))
    • 就像衣柜里每件大衣都有一个专属挂钩,每个挂钩都有唯一编号
    • 示例:$("#coat-hook1") 找到编号为"coat-hook1"的挂钩
  2. 类选择器 ($(".class"))
    • 就像把所有冬季外套放在一起,它们都有"winter-coat"标签
    • 示例:$(".winter-coat") 找到所有冬季外套
  3. 元素选择器 ($("element"))
    • 就像把所有的衬衫都归类到一起
    • 示例:$("shirt") 找到所有衬衫
  4. 全选选择器 ($("*"))
    • 就像整理衣柜时把所有衣物都拿出来
    • 示例:$("*") 选择页面所有元素
  5. 并集选择器 ($("sel1, sel2"))
    • 就像同时整理衬衫和裤子
    • 示例:$("shirt, pants") 选择所有衬衫和裤子

层级选择器 - 就像衣柜的分层结构

  1. 后代选择器 ($("ancestor descendant"))
    • 就像在衣柜的抽屉里找袜子
    • 示例:$("drawer socks") 选择抽屉里的所有袜子
  2. 子元素选择器 ($("parent > child"))
    • 就像只找直接挂在衣架上的衣服,不包括衣架内口袋里的物品
    • 示例:$("hanger > clothes") 选择直接挂在衣架上的衣服
  3. 相邻兄弟选择器 ($("prev + next"))
    • 就像找到某件衣服后面紧挨着的另一件衣服
    • 示例:$("red-shirt + blue-shirt") 选择红色衬衫后面紧挨着的蓝色衬衫
  4. 一般兄弟选择器 ($("prev ~ siblings"))
    • 就像找到某件衣服后面的所有同类型衣服
    • 示例:$("red-shirt ~ shirt") 选择红色衬衫后面的所有衬衫

实际应用小故事

记得有一次我需要为一个服装电商网站添加交互功能。用户点击某件衣服时,需要高亮显示同类型的其他衣服。

我用类选择器解决了这个问题:

$(".dress").click(function() {
    $(".dress").addClass("highlight");
});

后来又需要只高亮同一品牌下的衣服,这时用了层级选择器:

$(".brand-section .dress").click(function() {
    $(this).siblings(".dress").addClass("highlight");
});

通过这样的层级关系,可以精确地定位到需要的元素,就像在整理得井井有条的衣柜里快速找到想要的衣物一样。

JQuery DOM操作之元素内容操作

让我用一个餐厅点餐系统的例子来讲解这几个JQuery方法。

1. html() - 获取或设置元素的HTML内容

想象餐厅的菜单板:

// 获取菜单板的完整HTML内容 
let menuContent = $('#menu-board').html();
 
// 设置菜单板的内容(会解析HTML标签)
$('#menu-board').html('<h3>今日特价</h3><p>红烧牛肉 ¥38</p>');

就像餐厅经理可以查看或完全更换菜单板上的所有内容(包括标题、图片等)。

2. text() - 获取或设置元素的纯文本内容

// 获取菜单项的纯文本(不包含HTML标签)
let dishName = $('.special-dish').text();
 
// 设置纯文本内容(不会解析HTML标签)
$('.special-dish').text('今日特价:红烧牛肉 ¥38');

这就像服务员只读取菜单上的文字给顾客听,不会解释其中的格式。

3. val() - 获取或设置表单元素的值

// 获取顾客输入的数量
let quantity = $('#quantity-input').val();
 
// 设置默认数量 
$('#quantity-input').val('1');

这相当于记录顾客在点餐单上填写的数量信息。

4. append() - 在元素内部末尾追加内容

// 在订单列表末尾添加新菜品 
$('#order-list').append('<li>红烧牛肉 x 1</li>');

就像服务员把新点的菜加到订单的最后一行。

5. prepend() - 在元素内部开头插入内容

// 在订单列表开头插入紧急订单
$('#order-list').prepend('<li class="urgent">VIP加急订单</li>');

这相当于把VIP订单插到订单列表的最前面优先处理。

实际应用场景

假设我们正在开发餐厅的点餐系统:

// 初始化菜单 
$('#menu').html('<ul><li>加载中...</li></ul>');
 
// 从服务器获取菜单数据后 
$.get('/api/menu', function(data) {
  let menuItems = '';
  data.forEach(item => {
    menuItems += `<li>${item.name} ¥${item.price}</li>`;
  });
  $('#menu ul').html(menuItems);
});
 
// 顾客点餐时 
$('.order-btn').click(function() {
  const dishName = $(this).data('dish');
  const quantity = $('#quantity').val() || 1;
  
  // 添加到订单列表
  $('#order-list').append(`<li>${dishName} x ${quantity}</li>`);
  
  // 清空数量输入框
  $('#quantity').val('');
});
 
// 添加特别提示
$('#order-container').prepend('<div class="notice">今日所有订单9折</div>');

注意事项

  1. html()
    

    text()
    

    的区别:

    • html()会解析HTML标签,text()会把内容当作纯文本
    • 使用text()可以防止XSS攻击
  2. 性能考虑:

    • 批量操作时,先构建好字符串再一次性插入比多次调用append/prepend更高效
  3. 链式调用:

    $('#content')
      .html('')
      .append('<h1>新菜单</h1>')
      .append('<ul><li>...</li></ul>');
    

就像餐厅经理管理菜单和订单一样,这些JQuery方法让我们可以灵活地操作网页内容。

jQuery DOM操作之CSS类操作

作为一名全栈工程师,我来给你讲个有趣的故事,帮助你理解jQuery中的CSS类操作。

衣柜的故事:理解CSS类操作

想象你有一个智能衣柜(DOM元素),里面挂着各种衣服(CSS类)。jQuery提供了几个方法来管理这些"衣服":

1. addClass() - 添加新衣服

$('#myWardrobe').addClass('winter-coat');

就像冬天来了,你给衣柜添加了一件"winter-coat"大衣。这个方法不会替换掉原有的衣服,只是添加新的。

实际应用场景:当用户点击按钮时,给某个元素添加高亮样式

$('#highlightBtn').click(function() {
    $('#importantText').addClass('highlight');
});

2. removeClass() - 清理不需要的衣服

$('#myWardrobe').removeClass('summer-shirt');

夏天过去了,你把"summer-shirt"夏装从衣柜里移除。如果衣柜里没有这件衣服,也不会报错。

实际应用场景:关闭弹窗时移除显示类

$('#closeModal').click(function() {
    $('#modal').removeClass('show');
});

3. toggleClass() - 根据季节切换衣服

$('#myWardrobe').toggleClass('jacket');

这个方法很智能,它会检查衣柜里是否有"jacket"夹克:如果有就移除,没有就添加。就像春秋季节,早晚温差大,你可能需要随时穿脱夹克。

实际应用场景:切换夜间模式

$('#nightModeToggle').click(function() {
    $('body').toggleClass('night-mode');
});

高级用法

一次操作多个类

$('#myWardrobe').addClass('coat hat gloves');

就像冬天出门,你可以一次性添加多件衣物。

使用函数动态决定类名

$('.item').addClass(function(index) {
    return 'item-' + index;
});

这就像根据物品编号给它们贴上不同的标签。

移除所有类

$('#myWardrobe').removeClass();

不传参数时,会移除元素上的所有类,就像清空整个衣柜。

实际项目经验

在我之前的一个电商项目中,我们使用这些方法实现了:

  1. 商品筛选功能 - 使用addClass()removeClass()来高亮显示选中的筛选条件
  2. 主题切换 - 使用toggleClass()在浅色和深色主题间切换
  3. 表单验证 - 使用这些方法添加或移除错误提示样式

记住,直接操作CSS类比直接修改样式更高效,因为:

  • 样式集中维护在CSS文件中,便于统一修改
  • 浏览器可以优化类名的变化,性能更好
  • 代码更清晰,行为与表现分离

就像管理衣柜一样,合理使用这些方法可以让你的"前端衣橱"整洁有序!

jQuery DOM操作之元素属性操作

让我用一个电商网站的实际案例来讲解jQuery中的属性操作方法。

故事背景:电商商品管理页面

假设我们正在开发一个电商后台管理系统,需要处理商品的各种属性。比如商品是否上架、是否推荐、是否有库存等。这些状态通常通过HTML元素的属性来控制。

1. attr() 和 removeAttr() - 操作标准HTML属性

// 给商品图片添加alt属性(SEO优化)
$('.product-img').attr('alt', '优质商品展示');
 
// 当商品下架时,移除"data-featured"属性
$('#product-123').removeAttr('data-featured');

真实案例:有一次我们需要为所有外部链接添加rel="nofollow"属性,使用attr()方法批量处理:

$('a').attr('rel', 'nofollow');

2. prop() 和 removeProp() - 操作DOM属性

// 设置商品复选框为选中状态(上架商品)
$('#product-checkbox').prop('checked', true);
 
// 移除自定义DOM属性(不常用)
$('#special-product').removeProp('specialOffer');

经验分享:在处理表单元素时,特别是复选框和单选按钮,一定要用prop()而不是attr()。曾经有个bug困扰了我们半天,就是因为用attr()设置checked属性,实际表现不正常:

// 错误做法 - 可能不会生效 
$('#checkbox').attr('checked', true);
 
// 正确做法
$('#checkbox').prop('checked', true);

3. 实际项目中的综合应用

// 商品批量操作
function toggleProducts(enable) {
    // 禁用/启用所有操作按钮
    $('.product-actions button').prop('disabled', !enable);
    
    // 添加/移除loading状态
    $('#product-list').attr('data-loading', enable ? 'true' : null);
    
    // 切换复选框状态 
    $('.product-select').prop('checked', enable);
}

性能优化建议:在操作大量元素时,避免多次DOM操作:

// 不好 - 多次DOM操作
$('.product').attr('data-loaded', 'true');
$('.product').addClass('loaded');
$('.product').prop('disabled', true);
 
// 好 - 链式操作,一次DOM访问 
$('.product')
    .attr('data-loaded', 'true')
    .addClass('loaded')
    .prop('disabled', true);

关键区别总结

方法适用场景示例注意事项
attr()HTML标准属性src, alt, title对布尔属性可能表现不一致
removeAttr()移除HTML属性移除disabled属性会完全移除属性节点
prop()DOM元素属性checked, disabled适合布尔属性/JavaScript属性
removeProp()移除DOM属性移除自定义属性不常用,可能影响原生属性

记住这个原则:当处理HTML特性(attributes)时用attr(),当处理DOM属性(properties)时用prop()

jQuery DOM操作:元素插入与删除

让我用一个生动的故事来解释jQuery中的元素插入与删除方法,就像我平时给团队讲解技术那样。

故事场景:图书馆的书架管理

想象你是一个图书管理员,负责整理图书馆的书架(DOM树)。你有四种基本操作方式:

1. insertAfter() - 在指定书籍后面插入新书

$("<div>新书《Java编程》</div>").insertAfter("#database-books");

这就像你拿到一本新书《Java编程》,然后决定把它放在"数据库类书籍"的后面。

2. insertBefore() - 在指定书籍前面插入新书

$("<div>新书《Python入门》</div>").insertBefore("#web-books");

这相当于你把《Python入门》这本书放在"网页开发类书籍"的前面。

3. appendTo() - 把书放到某个书架的最下面

$("<div>新书《算法导论》</div>").appendTo("#computer-science-section");

就像你把《算法导论》添加到"计算机科学"书架的最底部(作为最后一个子元素)。

4. prependTo() - 把书放到某个书架的最上面

$("<div>新书《设计模式》</div>").prependTo("#software-engineering-section");

这相当于你把《设计模式》放在"软件工程"书架的最顶部(作为第一个子元素)。

删除元素 - 下架旧书

$(".outdated-books").remove();

就像你把所有标记为"过时"的书籍从书架上移除。

实际应用示例

// 在列表项2后面插入新项
$("<li>新项目</li>").insertAfter("#item2");
 
// 在列表开头插入新项
$("<li>首要项目</li>").prependTo("#myList");
 
// 删除所有完成的项目
$(".completed").remove();

经验分享

记得我刚工作时,在一个电商项目里需要动态更新商品列表。最初我用的是原始的DOM操作,代码又长又难维护。后来发现jQuery的这些方法后,代码量减少了70%。特别是appendTo()prependTo(),让动态内容更新变得非常简单。

就像整理图书馆一样,选择合适的方法能让你的DOM操作更高效、更易读。记住:insertAfter/Before是相对于兄弟节点操作,而appendTo/prependTo是相对于父节点操作子节点。

jQuery事件处理:绑定与解绑的实践指南

作为一名全栈工程师,我来分享一个关于jQuery事件处理的实际项目经历,就像餐厅服务员管理订单一样生动有趣。

1. 项目背景:电商网站的动态交互需求

去年我们团队开发一个电商网站,产品经理要求实现:

  • 商品卡片悬停显示详情
  • 点击加入购物车按钮
  • 防止用户重复提交订单
  • 动态加载内容后的事件绑定

2. 基础绑定:on()方法 - 招聘服务员

// 就像给餐厅招聘服务员
$('.add-to-cart').on('click', function() {
    console.log('商品已加入购物车');
    // 这里可以添加AJAX请求 
});

经验分享:在早期项目中,我们使用.click(),但当元素是动态生成时会出现问题,就像服务员离职后新来的没人接待顾客。

3. 事件委托:高效管理 - 设立接待处

// 在父元素上设立"接待处",处理动态子元素的事件 
$('#product-container').on('click', '.product-item', function() {
    console.log('点击了商品:' + $(this).data('id'));
});

实际案例:我们曾经有个列表页,每次筛选都会重新渲染商品,最初绑定事件在商品上导致内存泄漏,后来改用委托方式解决了问题。

4. 一次性事件:one() - 限时优惠

// 就像限时优惠,只生效一次
$('.limited-offer').one('click', function() {
    alert('您已领取限时优惠券!');
    $(this).prop('disabled', true);
});

项目应用:在注册表单提交时,我们使用one()防止用户重复提交,就像餐厅只允许每位顾客点一次特色菜。

5. 解绑事件:off() - 服务员轮班

// 定义事件处理函数
function addToCartHandler() {
    console.log('加入购物车');
    
    // 达到限购数量后解绑事件 
    if(cartCount >= maxLimit) {
        $('.add-to-cart').off('click', addToCartHandler);
    }
}
 
// 初始绑定
$('.add-to-cart').on('click', addToCartHandler);

性能优化:在一个SPA项目中,我们忘记在页面切换时解绑事件,导致内存不断增长,后来通过off()在页面销毁时清理事件监听器解决了问题。

6. 多事件处理 - 多功能服务员

// 一个服务员同时处理多个任务 
$('.product-card').on({
    mouseenter: function() {
        $(this).find('.details').show();
    },
    mouseleave: function() {
        $(this).find('.details').hide();
    },
    click: function() {
        // 处理点击 
    }
});

7. 命名空间 - 给服务员分组

// 给事件添加命名空间,方便管理
$('#btn').on('click.shoppingCart', addToCart);
$('#btn').on('click.userProfile', updateProfile);
 
// 只移除购物车相关事件 
$('#btn').off('click.shoppingCart');

团队协作经验:在大项目中,命名空间可以避免不同模块间的事件冲突,就像给餐厅服务员分区域负责。

8. 实际项目中的最佳实践

  1. 动态内容:总是使用事件委托处理动态生成的元素
  2. 内存管理:在不需要时及时解绑事件
  3. 性能优化:避免在大量元素上直接绑定事件
  4. 代码组织:使用命名空间使代码更清晰

9. 常见问题解决方案

问题1:事件处理函数中的this指向什么?

  • this指向触发事件的DOM元素,就像服务员知道是哪个桌子的顾客按了服务铃

问题2:如何阻止事件冒泡?

$('.inner').on('click', function(e) {
    e.stopPropagation(); // 阻止事件冒泡
});

问题3:如何阻止默认行为?

$('a.no-redirect').on('click', function(e) {
    e.preventDefault(); // 阻止链接跳转 
});

通过合理使用jQuery的事件处理方法,就像管理一支高效的服务团队,可以创建出响应迅速、用户体验良好的Web应用。

jQuery事件处理:事件委托(delegate()/undelegate())

让我用一个餐厅管理的例子来解释jQuery的事件委托机制,就像我之前解释多线程那样。

餐厅服务员的故事

想象你是一家大型餐厅的经理(相当于网页中的父元素),餐厅里有100张桌子(子元素)。现在有三种管理方式:

1. 传统方式(直接绑定)

$('.table').on('click', function() {
    // 处理点击事件
});

这就像给每张桌子都分配一个专属服务员。当有新桌子加入时,新桌子没有服务员,而且管理100个服务员成本很高。

2. 事件委托方式(delegate)

$('#restaurant').delegate('.table', 'click', function() {
    // 处理点击事件
});

这就像只在餐厅门口安排几个接待员。无论何时有顾客(事件)需要服务(点击),接待员会根据顾客所在的桌子(事件目标)来提供相应服务。即使新桌子加入,接待员也能自动处理。

3. 现代方式(on)

$('#restaurant').on('click', '.table', function() {
    // 处理点击事件
});

这是jQuery 1.7+推荐的方式,原理和delegate相同,但语法更统一。

为什么使用事件委托?

  1. 动态元素处理:就像新加入的桌子自动获得服务,动态添加的元素无需重新绑定事件
  2. 性能优化:1000个子元素只需要1个事件处理程序,而不是1000个
  3. 内存效率:减少事件处理器的数量,就像减少服务员数量一样节省成本

undelegate() - 解雇接待员

$('#restaurant').undelegate('.table', 'click');

这就像解雇专门处理桌子点击事件的接待员。当某种服务不再需要时,可以精确地取消它。

实际代码示例

// 事件委托绑定 
$('#userList').delegate('li', 'click', function() {
    console.log('用户ID: ' + $(this).data('id'));
});
 
// 动态添加新用户
$('#addUser').click(function() {
    $('#userList').append('<li data-id="' + newId + '">新用户</li>');
    // 新li元素自动拥有点击事件处理 
});
 
// 取消委托
$('#userList').undelegate('li', 'click');

记住,在jQuery 3.0中,delegate()/undelegate()已被标记为废弃,推荐统一使用on()/off()方法,但原理完全相同。

就像优秀的餐厅经理知道如何高效分配服务员一样,优秀的开发者应该掌握事件委托来高效管理DOM事件。

jQuery事件处理与事件对象详解

让我用一个生动的故事来解释jQuery事件处理和事件对象的关键概念。

故事:商场里的意外事件

想象你是一家大型商场的经理(相当于网页中的document对象)。某天发生了一起顾客投诉事件(相当于浏览器事件),我们来分析这个事件:

1. event.type - 事件类型

“经理!有人在食品区打翻了饮料!”(事件类型是"打翻饮料")

在jQuery中:

$("#foodArea").on("click", function(event) {
    console.log(event.type); // 输出: "click"
});

2. event.target - 事件源

你调查后发现,是张三(8岁男孩)在果汁摊位前不小心碰倒了杯子(事件源是张三)。

jQuery代码:

$(document).on("click", function(event) {
    console.log("事件源头是: " + event.target.tagName); // 比如输出: "事件源头是: BUTTON"
});

3. event.preventDefault() - 阻止默认行为

按照商场规定,发生此类事件应自动启动清洁程序。但这次你想先评估情况再决定。

jQuery代码:

$("a").on("click", function(event) {
    event.preventDefault(); // 阻止链接默认的跳转行为
    console.log("链接点击了,但不会跳转");
});

4. event.stopPropagation() - 阻止事件冒泡

事件上报流程:果汁摊员工 → 食品区主管 → 楼层经理 → 总经理。你想在食品区主管层面解决,不必惊动更高层。

jQuery代码:

$(".foodSection").on("click", function(event) {
    console.log("食品区处理事件");
    event.stopPropagation(); // 阻止事件冒泡到上层 
});
 
$("#floorManager").on("click", function() {
    // 如果上面调用了stopPropagation(),这里的处理程序不会执行 
    console.log("楼层经理处理事件");
});

完整示例代码

$(document).ready(function() {
    // 示例1:获取事件类型和目标 
    $("#myButton").on("click", function(event) {
        console.log("事件类型: " + event.type); // click 
        console.log("事件目标: ", event.target); // 触发事件的DOM元素
    });
    
    // 示例2:阻止默认行为 
    $("a.noRedirect").on("click", function(event) {
        event.preventDefault();
        alert("这个链接不会跳转!");
    });
    
    // 示例3:阻止事件冒泡 
    $(".innerDiv").on("click", function(event) {
        console.log("内部div点击 - 事件不会冒泡");
        event.stopPropagation();
    });
    
    $(".outerDiv").on("click", function() {
        console.log("外部div点击 - 如果内部调用了stopPropagation(),这里不会执行");
    });
    
    // 示例4:同时使用
    $("form").on("submit", function(event) {
        event.preventDefault(); // 阻止表单提交 
        event.stopPropagation(); // 阻止事件冒泡
        console.log("表单提交被拦截");
    });
});

实际应用场景

  1. 表单验证:阻止无效表单提交
$("#signupForm").on("submit", function(event) {
    if(!validateForm()) {
        event.preventDefault(); // 验证不通过时阻止提交 
    }
});
  1. 下拉菜单:点击菜单项时不触发文档点击事件
$(".dropdown-menu").on("click", function(event) {
    event.stopPropagation(); // 防止菜单点击触发document的点击处理 
});
 
$(document).on("click", function() {
    $(".dropdown-menu").hide(); // 点击页面其他部分隐藏菜单
});
  1. 事件委托:利用event.target处理动态元素
$("#todoList").on("click", "li", function(event) {
    // 只有点击li元素时才触发
    console.log("完成了: " + $(event.target).text());
});

记住这个商场事件的故事,你就能轻松理解jQuery事件处理的核心概念了!

思维导图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java自学之旅

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值