jQuery实战开发:从功能实现到项目落地

在前端开发中,jQuery的核心价值是**“高效解决业务场景中的交互需求”**——无论是电商页面的商品筛选、后台系统的表单提交,还是移动端的弹窗交互,都能通过jQuery快速实现。本文以“实战驱动”为核心,跳过冗余理论,直接聚焦企业项目中高频的功能开发、复杂交互与性能优化,结合完整代码案例,带你掌握jQuery实战开发的核心能力,最终能独立完成中小型项目的交互开发。

一、高频业务功能开发:解决80%的日常需求

企业项目中,80%的交互需求可归纳为“表单处理、数据渲染、动态筛选、弹窗交互”四大类。本节针对每类需求提供完整解决方案,代码可直接复用。

1. 高级表单处理:带进度条的文件上传

文件上传是电商(头像上传)、后台系统(Excel导入)的常见需求,核心是“实时显示上传进度、校验文件格式/大小、处理上传结果”。

实战代码:带进度条的头像上传

<body>

    <div class="upload-container">

        <h3>头像上传(支持预览+进度条)</h3>

        <!-- 上传按钮:隐藏原生input,用自定义按钮触发 -->

        <label for="avatarInput" class="upload-btn btn">

            选择头像

            <input type="file" id="avatarInput" accept="image/jpg,image/png,image/jpeg" hidden>

        </label>


        <!-- 预览区域 -->

        <div class="preview-area" style="margin: 20px 0; display: none;">

            <img id="avatarPreview" src="" alt="头像预览" style="width: 150px; height: 150px; border-radius: 50%; object-fit: cover; border: 1px solid #eee;">

        </div>


        <!-- 进度条区域 -->

        <div class="progress-area" style="width: 300px; display: none;">

            <div class="progress-label" style="display: flex; justify-content: space-between; margin-bottom: 5px;">

                <span>上传进度</span>

                <span id="progressPercent">0%</span>

            </div>

            <div class="progress-bar" style="height: 8px; background: #eee; border-radius: 4px; overflow: hidden;">

                <div id="progressFill" style="width: 0%; height: 100%; background: #4285f4; transition: width 0.3s ease;"></div>

            </div>

        </div>


        <!-- 结果提示 -->

        <div id="uploadResult" style="margin-top: 10px; font-size: 14px;"></div>

    </div>

    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>

    <script>

        $(function() {

            const $avatarInput = $('#avatarInput');

            const $avatarPreview = $('#avatarPreview');

            const $previewArea = $('.preview-area');

            const $progressArea = $('.progress-area');

            const $progressFill = $('#progressFill');

            const $progressPercent = $('#progressPercent');

            const $uploadResult = $('#uploadResult');

            // 1. 选择文件后预览头像

            $avatarInput.on('change', function(e) {

                const file = e.target.files[0];

                if (!file) return;

                // 校验文件格式

                const validTypes = ['image/jpg', 'image/png', 'image/jpeg'];

                if (!validTypes.includes(file.type)) {

                    $uploadResult.text('请上传JPG/PNG格式的图片!').css('color', '#e53935');

                    return;

                }

                // 校验文件大小(限制2MB以内)

                const maxSize = 2 * 1024 * 1024; // 2MB

                if (file.size > maxSize) {

                    $uploadResult.text('图片大小不能超过2MB!').css('color', '#e53935');

                    return;

                }

                // 预览图片:用FileReader读取文件

                const reader = new FileReader();

                reader.onload = function(event) {

                    $avatarPreview.attr('src', event.target.result);

                    $previewArea.show(); // 显示预览区域

zq-mobile.zhaopin.com/moment/85949794

zq-mobile.zhaopin.com/moment/85949794

zq-mobile.zhaopin.com/moment/85949840

zq-mobile.zhaopin.com/moment/85949840

zq-mobile.zhaopin.com/moment/85952112

zq-mobile.zhaopin.com/moment/85952342

zq-mobile.zhaopin.com/moment/85952398

                    $uploadResult.text('').css('color', ''); // 清空之前的提示

                };

                reader.readAsDataURL(file);

                // 触发上传(实际项目中可改为“点击上传按钮后上传”)

                uploadFile(file);

            });

            // 2. 上传文件(模拟FormData+Ajax上传,支持进度监听)

            function uploadFile(file) {

                // 创建FormData对象(用于传递文件数据)

                const formData = new FormData();

                formData.append('avatar', file); // 'avatar'是后端接收的参数名

                // 显示进度条

                $progressArea.show();

                $progressFill.css('width', '0%');

                $progressPercent.text('0%');

                // 发送Ajax请求

                $.ajax({

                    url: '/api/upload/avatar', // 后端上传接口(实际项目替换为真实地址)

                    method: 'POST',

                    data: formData,

                    // 关键配置:不处理数据和 contentType,让浏览器自动处理

                    processData: false,

                    contentType: false,

                    // 监听上传进度

                    xhr: function() {

                        const xhr = new XMLHttpRequest();

                        // 监听progress事件

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

                            if (e.lengthComputable) {

                                // 计算进度百分比

                                const percent = Math.round((e.loaded / e.total) * 100);

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

                                $progressPercent.text(percent + '%');

                            }

                        });

                        return xhr;

                    },

                    // 上传成功

                    success: function(res) {

                        if (res.code === 200) {

                            $uploadResult.text('上传成功!头像已更新').css('color', '#43a047');

                            // 实际项目中可保存后端返回的头像URL:res.data.avatarUrl

                        } else {

                            $uploadResult.text('上传失败:' + res.msg).css('color', '#e53935');

                        }

                    },

                    // 上传失败

                    error: function() {

                        $uploadResult.text('网络错误,上传失败!').css('color', '#e53935');

                    }

                });

            }

        });

    </script>

</body>

核心要点

文件预览:用FileReader读取本地文件,将结果作为图片src实现预览;

进度监听:通过XMLHttpRequest.upload的progress事件实时获取上传进度;

FormData:用于传递文件数据,需设置processData: false和contentType: false,避免jQuery对数据进行额外处理。

2. 动态数据渲染:带筛选的商品列表

电商、资讯类页面常需“加载数据并渲染列表,支持条件筛选”,核心是“异步请求数据、批量渲染DOM、筛选逻辑复用”。

实战代码:带价格筛选的商品列表

<body>

    <div class="product-container">

        <h3>商品列表(支持价格筛选)</h3>


        <!-- 筛选区域 -->

        <div class="filter-area" style="margin: 20px 0; padding: 15px; background: #f9fafb; border-radius: 8px;">

            <span>价格筛选:</span>

            <button class="filter-btn btn active" data-price="all">全部价格</button>

            <button class="filter-btn btn" data-price="0-100">0-100元</button>

            <button class="filter-btn btn" data-price="100-300">100-300元</button>

            <button class="filter-btn btn" data-price="300+">300元以上</button>


            <!-- 加载状态(初始隐藏) -->

            <div id="loading" style="display: inline-block; margin-left: 20px; color: #666;">加载中...</div>

        </div>


        <!-- 商品列表区域 -->

        <div id="productList" style="display: flex; flex-wrap: wrap; gap: 20px;"></div>


        <!-- 无数据提示(初始隐藏) -->

        <div id="noData" style="display: none; margin-top: 50px; text-align: center; color: #999;">暂无符合条件的商品</div>

    </div>

    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>

    <script>

        $(function() {

            const $productList = $('#productList');

            const $filterBtns = $('.filter-btn');

            const $loading = $('#loading');

            const $noData = $('#noData');

            let currentFilter = 'all'; // 当前筛选条件

            // 1. 页面加载时默认加载全部商品

            loadProducts(currentFilter);

            // 2. 筛选按钮点击事件

            $filterBtns.on('click', function() {

                const $this = $(this);

                currentFilter = $this.data('price'); // 获取筛选条件(如0-100)


                // 更新按钮样式(选中状态)

                $filterBtns.removeClass('active');

                $this.addClass('active');


                // 加载对应筛选条件的商品

                loadProducts(currentFilter);

            });

            // 3. 加载商品数据并渲染列表

            function loadProducts(filter) {

                // 显示加载状态,隐藏列表和无数据提示

                $loading.show();

                $productList.hide();

                $noData.hide();

                // 发送Ajax请求(模拟后端接口返回数据)

                $.ajax({

                    url: '/api/products',

                    method: 'GET',

                    data: { filter: filter }, // 传递筛选条件

                    success: function(res) {

                        const products = res.data || [];


                        // 隐藏加载状态

                        $loading.hide();

                        // 无数据时显示提示

                        if (products.length === 0) {

                            $noData.show();

                            return;

                        }

                        // 批量渲染商品列表(避免循环中频繁操作DOM)

                        let html = '';

                        products.forEach(product => {

                            html += `

                                <div class="product-item" style="width: 200px; border: 1px solid #eee; border-radius: 8px; padding: 15px;">

                                    <img src="${product.imgUrl}" alt="${product.name}" style="width: 100%; height: 150px; object-fit: cover; border-radius: 4px;">

                                    <h4 style="margin: 10px 0; font-size: 16px; height: 40px; overflow: hidden;">${product.name}</h4>

                                    <p style="color: #e53935; font-size: 18px; font-weight: bold;">¥${product.price.toFixed(2)}</p>

                                    <button class="add-cart-btn btn" data-id="${product.id}" style="width: 100%; margin-top: 10px;">加入购物车</button>

                                </div>

                            `;

                        });

                        // 插入DOM并显示列表

                        $productList.html(html).show();

                        // 绑定“加入购物车”按钮事件(动态元素需用事件委托)

                        $productList.on('click', '.add-cart-btn', function() {

                            const productId = $(this).data('id');

                            alert(`商品ID ${productId} 已加入购物车!`);

                        });

                    },

                    error: function() {

                        $loading.hide();

                        alert('网络错误,商品加载失败!');

                    }

                });

            }

        });

    </script>

</body>

核心要点

批量渲染:通过字符串拼接所有商品HTML,再用html()一次性插入DOM,避免循环中频繁append()导致的性能问题;

动态元素事件:“加入购物车”按钮是渲染后生成的动态元素,需用事件委托($productList.on('click', '.add-cart-btn', ...))绑定事件;

筛选逻辑复用:将加载商品的逻辑封装为loadProducts()函数,筛选条件变化时直接调用,减少代码冗余。

3. 弹窗交互:可拖拽+遮罩层的模态框

弹窗(模态框)是确认提示、表单填写的常用组件,企业级需求中常需“支持拖拽、遮罩层、关闭逻辑、数据传递”。

实战代码:企业级可拖拽模态框

<body>

    <!-- 触发弹窗的按钮 -->

    <button id="openModalBtn" class="btn" style="margin: 50px;">打开弹窗</button>

    <!-- 遮罩层(初始隐藏) -->

    <div id="modalOverlay" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 999; display: none;"></div>

    <!-- 弹窗(初始隐藏) -->

    <div id="modal" style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 400px; background: white; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.15); z-index: 1000; display: none;">

        <!-- 弹窗头部(可拖拽区域) -->

        <div id="modalHeader" style="padding: 15px 20px; border-bottom: 1px solid #eee; cursor: move; user-select: none; display: flex; justify-content: space-between; align-items: center;">

            <h4 style="margin: 0; font-size: 16px;">商品编辑</h4>

            <button id="closeModalBtn" style="border: none; background: transparent; font-size: 20px; cursor: pointer; color: #999;">×</button>

        </div>

        <!-- 弹窗内容 -->

        <div id="modalContent" style="padding: 20px;">

            <div class="form-group" style="margin-bottom: 15px;">

                <label style="display: block; margin-bottom: 5px; font-size: 14px;">商品名称:</label>

                <input type="text" id="productName" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px;">

            </div>

            <div class="form-group" style="margin-bottom: 15px;">

                <label style="display: block; margin-bottom: 5px; font-size: 14px;">商品价格:</label>

                <input type="number" id="productPrice" step="0.01" min="0" style="width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px;">

            </div>

        </div>

        <!-- 弹窗底部(按钮区域) -->

        <div id="modalFooter" style="padding: 15px 20px; border-top: 1px solid #eee; display: flex; justify-content: flex-end; gap: 10px;">

            <button id="cancelBtn" class="btn" style="background: #eee; color: #333;">取消</button>

            <button id="confirmBtn" class="btn">确认保存</button>

        </div>

    </div>

    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>

    <script>

        $(function() {

            const $modal = $('#modal');

            const $modalOverlay = $('#modalOverlay');

            const $modalHeader = $('#modalHeader');

            const $openModalBtn = $('#openModalBtn');

            const $closeModalBtn = $('#closeModalBtn');

            const $cancelBtn = $('#cancelBtn');

            const $confirmBtn = $('#confirmBtn');

            const $productName = $('#productName');

            const $productPrice = $('#productPrice');

            let isDragging = false; // 拖拽状态标记

            let startX, startY, modalLeft, modalTop; // 初始位置变量

            // 1. 打开弹窗

            $openModalBtn.on('click', function() {

                // 模拟填充初始</doubaocanvas>

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

相关阅读更多精彩内容

友情链接更多精彩内容