mcpField
J
jquery

jquery

github.com/btafoya开发0121 次安装37 周前更新
代码仓库

关于 jquery

jquery 技能为使用 jQuery 的开发者提供 API 知识和常见代码模式,涵盖 DOM 操作、事件、AJAX、动画及插件。它也支持调试现有代码,并将常见 jQuery 写法迁移为原生 JavaScript。

主要功能

  1. 01使用选择器遍历和操作 DOM
  2. 02绑定、触发与移除事件
  3. 03配置 AJAX 请求和回调
  4. 04实现动画与效果
  5. 05编写插件并使用工具函数
  6. 06对照原生 JavaScript 迁移写法

适用场景

  1. 01实现页面元素交互与表单处理
  2. 02为前端代码添加 AJAX 请求
  3. 03排查 jQuery 事件或 DOM 问题
  4. 04将 jQuery 代码改写为原生 JavaScript

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/btafoya/jquery-agent-skill --skill jquery

安装后在 Claude Code 中输入/jquery确认已加载。

附带文件.claude-plugin/plugin.json

详细介绍

jQuery

jQuery 是一个快速、小巧且功能丰富的 JavaScript 库,它通过易于使用且适用于众多浏览器的 API,大幅简化了 HTML 文档遍历与操作、事件处理、动画和 AJAX。

何时使用此技能

当用户遇到以下情况时,应使用此技能:

  • 提到 jQuery、$ 或 jQuery 语法模式
  • 询问如何使用 $('#id') 或 $('.class') 等选择器操作 DOM
  • 使用 .on()、.click()、.submit()、.hover() 等事件处理程序
  • 需要了解如何使用 $.ajax()、$.get()、$.post() 或 $.getJSON() 发起 AJAX 请求
  • 想添加 .fadeIn()、.slideUp()、.animate() 等动画或效果
  • 询问 jQuery 插件或如何扩展 $.fn
  • 需要调试 jQuery 代码或修复常见问题
  • 想将 jQuery 代码迁移到原生 JavaScript
  • 询问 $.each()、$.map()、$.extend() 等 jQuery 工具方法
  • 需要了解 jQuery 对象、链式调用或延迟 Promise

核心概念

jQuery 对象 $ 和 jQuery

全局函数 $(及其别名 jQuery)是所有 jQuery 操作的入口。它会返回一个 jQuery 对象(通常称为“包装集”),其中包含匹配的 DOM 元素。

// These are equivalent
$('#myElement')
jQuery('#myElement')

// The jQuery object is array-like
var $el = $('#myElement');
console.log($el.length); // Number of matched elements
console.log($el[0]);      // First DOM element (unwrapped)
就绪处理程序

始终将 jQuery 代码放在文档就绪处理程序中,以确保 DOM 已完全加载:

// Shorthand
$(document).ready(function() {
    // Your code here
});

// Or shorter
$(function() {
    // Your code here
});
链式调用

jQuery 方法会返回 jQuery 对象,因此可以进行方法链式调用:

$('#myElement')
    .addClass('highlight')
    .css('color', 'red')
    .fadeIn(300)
    .on('click', handleClick);

选择器

jQuery 使用类似 CSS 的选择器查找元素:

// Basic selectors
$('#id')              // ID selector
$('.class')           // Class selector
$('div')              // Element selector
$('*')                // Universal selector

// Multiple selectors
$('#id, .class, div') // Comma-separated

// Hierarchy
$('div p')            // Descendant
$('div > p')          // Direct child
$('div + p')          // Adjacent sibling
$('div ~ p')          // General sibling

// Attribute
$('[data-id]')        // Has attribute
$('[data-id="123"]')  // Attribute equals
$('input[type="text"]')

// Filters
$('li:first')         // First element
$('li:last')          // Last element
$('li:even')          // Even-indexed elements
$('li:odd')           // Odd-indexed elements
$('li:eq(2)')         // Element at index 2
$('li:gt(2)')         // Elements after index 2
$('li:lt(5)')         // Elements before index 5
$('li:not(.exclude)') // Negation

// Form selectors
$(':input')           // All form elements
$(':text')            // Text inputs
$(':checkbox')        // Checkboxes
$(':checked')         // Checked elements
$(':selected')        // Selected elements
$(':disabled')        // Disabled elements

DOM 操作

获取和设置内容
// Get/set HTML
$('#myDiv').html();                   // Get innerHTML
$('#myDiv').html('<p>New content</p>'); // Set innerHTML

// Get/set text
$('#myDiv').text();                   // Get text content
$('#myDiv').text('New text');         // Set text content

// Get/set form values
$('#myInput').val();                  // Get value
$('#myInput').val('New value');       // Set value

// Get/set attributes
$('#myImage').attr('src');            // Get attribute
$('#myImage').attr('src', 'new.jpg'); // Set attribute
$('#myImage').removeAttr('alt');      // Remove attribute

// Get/set data attributes
$('#myDiv').data('id');               // Get data-* value
$('#myDiv').data('id', '123');        // Set data-* value
修改元素
// Classes
$('#myDiv').addClass('highlight');           // Add class
$('#myDiv').removeClass('highlight');        // Remove class
$('#myDiv').toggleClass('active');           // Toggle class
$('#myDiv').hasClass('active');              // Check if has class

// CSS
$('#myDiv').css('color', 'red');             // Set single property
$('#myDiv').css({
    'color': 'red',
    'background': 'blue',
    'padding': '10px'
});                                          // Set multiple properties
$('#myDiv').css('color');                    // Get property

// Dimensions
$('#myDiv').width();                         // Inner width
$('#myDiv').height();                        // Inner height
$('#myDiv').innerWidth();                    // Inner width + padding
$('#myDiv').innerHeight();                   // Inner height + padding
$('#myDiv').outerWidth();                    // Width + padding + border
$('#myDiv').outerHeight();                   // Height + padding + border
$('#myDiv').outerWidth(true);                // Include margin

// Position
$('#myDiv').offset();                        // Position relative to document
$('#myDiv').position();                      // Position relative to parent
$('#myDiv').offset({ top: 100, left: 50 });  // Set position

// Scrolling
$(window).scrollTop();                       // Get scroll position
$(window).scrollTop(200);                    // Set scroll position
创建和插入元素
// Create element
var $newDiv = $('<div class="new">Content</div>');

// Insert methods
$parent.append($newDiv);      // Append to end of parent
$parent.prepend($newDiv);     // Prepend to beginning of parent
$newDiv.appendTo($parent);    // Append this element to parent
$newDiv.prependTo($parent);   // Prepend this element to parent

$element.after($newDiv);      // Insert after element
$element.before($newDiv);     // Insert before element
$newDiv.insertAfter($element);
$newDiv.insertBefore($element);

// Wrap
$element.wrap('<div class="wrapper"></div>');
$elements.wrapAll('<div class="wrapper"></div>');
$element.wrapInner('<span></span>');

// Remove
$element.remove();            // Remove element from DOM
$element.empty();             // Remove all children
$element.detach();            // Remove but keep data/events

// Replace
$element.replaceWith('<div>Replacement</div>');

遍历

// Filtering
$('li').first();              // First element
$('li').last();               // Last element
$('li').eq(2);                // Element at index 2
$('li').filter('.active');    // Filter by selector
$('li').not('.exclude');      // Exclude elements
$('li').has('.child');        // Has descendant matching selector
$('li').slice(1, 4);          // Slice elements

// Finding
$('#parent').find('.child');  // Find descendants
$element.children();          // Direct children only
$element.children('.active'); // Direct children matching selector

// Relationships
$element.parent();            // Direct parent
$element.parents();           // All ancestors
$element.parentsUntil('.container'); // Ancestors until match
$element.closest('.ancestor'); // Closest ancestor (includes self)
$element.siblings();          // All siblings
$element.siblings('.active'); // Siblings matching selector
$element.next();              // Next sibling
$element.nextAll();           // All next siblings
$element.nextUntil('.stop');  // Next siblings until match
$element.prev();              // Previous sibling
$element.prevAll();           // All previous siblings
$element.prevUntil('.stop');  // Previous siblings until match

事件处理

绑定事件
// Basic event binding
$('#myButton').click(function() {
    console.log('Clicked!');
});

// Shorthand methods available for most events:
// .click(), .dblclick(), .mouseenter(), .mouseleave(),
// .mouseover(), .mouseout(), .mousedown(), .mouseup(),
// .mousemove(), .keydown(), .keyup(), .keypress(),
// .submit(), .change(), .focus(), .blur(), .scroll()

// Using .on() for all events
$('#myButton').on('click', function(event) {
    event.preventDefault(); // Prevent default behavior
    event.stopPropagation(); // Stop event bubbling
    console.log('Clicked!', event);
});

// Multiple events
$('#myButton').on('click mouseenter', function() {
    $(this).addClass('active');
});

// Event-specific handler
$('#myButton').on({
    click: function() { console.log('Clicked'); },
    mouseenter: function() { console.log('Entered'); }
});

// Pass data to handler
$('#myButton').on('click', { name: 'John' }, function(event) {
    console.log('Hello, ' + event.data.name);
});

// Event delegation (for dynamically added elements)
$(document).on('click', '.dynamic-button', function() {
    console.log('Dynamic button clicked!');
});
解绑事件
// Remove specific handler
$('#myButton').off('click', myHandler);

// Remove all click handlers
$('#myButton').off('click');

// Remove all event handlers
$('#myButton').off();
事件对象
$('#myElement').on('click keypress', function(event) {
    console.log('Event type:', event.type);
    console.log('Target:', event.target);
    console.log('Current target:', event.currentTarget);
    console.log('Timestamp:', event.timeStamp);
    console.log('Which:', event.which); // For key/button codes

    // Keyboard events
    if (event.type === 'keypress') {
        console.log('Key:', event.key);
        console.log('Code:', event.code);
    }

    // Mouse events
    if (event.type === 'click') {
        console.log('Page X:', event.pageX);
        console.log('Page Y:', event.pageY);
        console.log('Client X:', event.clientX);
        console.log('Client Y:', event.clientY);
    }
});
常用事件
// One-time event
$('#myButton').one('click', function() {
    console.log('Will only fire once');
});

// Trigger events programmatically
$('#myButton').trigger('click');
$('#myButton').click(); // Shorthand

// Custom events
$(document).on('customEvent', function(event, param1, param2) {
    console.log(param1, param2);
});
$('#myButton').trigger('customEvent', ['hello', 'world']);

AJAX 和 HTTP 请求

基本 AJAX
// Basic $.ajax()
$.ajax({
    url: '/api/data',
    method: 'GET',
    dataType: 'json',
    success: function(data) {
        console.log('Success:', data);
    },
    error: function(xhr, status, error) {
        console.error('Error:', error);
    },
    complete: function(xhr, status) {
        console.log('Request complete');
    }
});

// Promise-style (jQuery 3+)
$.ajax({
    url: '/api/data',
    method: 'GET',
    dataType: 'json'
})
.done(function(data) {
    console.log('Success:', data);
})
.fail(function(xhr, status, error) {
    console.error('Error:', error);
})
.always(function() {
    console.log('Always runs');
});
简写方法
// GET request
$.get('/api/data', function(data) {
    console.log(data);
});

// GET with parameters
$.get('/api/data', { id: 123, name: 'John' }, function(data) {
    console.log(data);
});

// POST request
$.post('/api/data', { name: 'John', email: '[email protected]' }, function(data) {
    console.log(data);
});

// GET JSON
$.getJSON('/api/data.json', function(data) {
    console.log(data);
});

// Load HTML into element
$('#result').load('/api/content #section');
AJAX 配置
$.ajax({
    url: '/api/data',
    method: 'POST',
    dataType: 'json',
    contentType: 'application/json',
    data: JSON.stringify({ name: 'John' }),

    // Advanced options
    timeout: 5000,
    async: true,
    cache: false,
    headers: {
        'X-Custom-Header': 'value'
    },
    beforeSend: function(xhr) {
        xhr.setRequestHeader('Authorization', 'Bearer token');
    },

    // Response handling
    statusCode: {
        404: function() {
            console.log('Not found');
        },
        500: function() {
            console.log('Server error');
        }
    }
});
全局 AJAX 事件
// Show/hide loading indicator
$(document)
    .ajaxStart(function() {
        $('#loading').show();
    })
    .ajaxStop(function() {
        $('#loading').hide();
    })
    .ajaxError(function(event, xhr, settings, error) {
        console.error('AJAX error:', error);
    })
    .ajaxSuccess(function(event, xhr, settings) {
        console.log('AJAX success');
    });
AJAX 设置
// Set default AJAX options
$.ajaxSetup({
    timeout: 10000,
    error: function(xhr, status, error) {
        console.error('Default error handler:', error);
    }
});

// Prefilter requests
$.ajaxPrefilter(function(options, originalOptions, xhr) {
    if (options.url.match(/^\/api\//)) {
        options.headers = options.headers || {};
        options.headers['Authorization'] = 'Bearer ' + getToken();
    }
});

动画和效果

基本效果
// Show/Hide
$('#myElement').show();           // Show element
$('#myElement').hide();           // Hide element
$('#myElement').toggle();         // Toggle visibility
$('#myElement').show(500);        // Animate show with duration (ms)
$('#myElement').show('slow');     // 'slow', 'normal', 'fast'

// Fade
$('#myElement').fadeIn();         // Fade in
$('#myElement').fadeOut();        // Fade out
$('#myElement').fadeToggle();     // Toggle fade
$('#myElement').fadeTo(500, 0.5); // Fade to opacity (duration, opacity)

// Slide
$('#myElement').slideDown();      // Slide down
$('#myElement').slideUp();        // Slide up
$('#myElement').slideToggle();    // Toggle slide
自定义动画
// Animate CSS properties
$('#myElement').animate({
    opacity: 0.5,
    width: '200px',
    height: '200px',
    left: '100px',
    top: '100px'
}, 1000);

// Animation with options
$('#myElement').animate(
    { width: 'toggle' },
    {
        duration: 1000,
        easing: 'swing', // 'swing' or 'linear'
        complete: function() {
            console.log('Animation complete');
        },
        step: function(now, fx) {
            console.log('Current value:', now);
        },
        queue: true
    }
);

// Parallel animations
$('#myElement')
    .animate({ width: '200px' }, 1000)
    .animate({ height: '200px' }, 1000);
动画控制
var $el = $('#myElement');

// Stop animation
$el.stop();                      // Stop current animation
$el.stop(true);                  // Clear queue and stop
$el.stop(true, true);            // Jump to end

// Check if animating
if ($el.is(':animated')) {
    console.log('Currently animating');
}

// Delay
$el.fadeOut(300).delay(500).fadeIn(300);

// Disable queue
$el.animate({ left: '+=100' }, { queue: false });

工具方法

数组/对象工具方法
// Each
$.each([1, 2, 3], function(index, value) {
    console.log(index + ': ' + value);
});

$.each({ name: 'John', age: 30 }, function(key, value) {
    console.log(key + ': ' + value);
});

// Map
var doubled = $.map([1, 2, 3], function(value, index) {
    return value * 2;
}); // [2, 4, 6]

// Grep (filter)
var even = $.grep([1, 2, 3, 4, 5], function(value) {
    return value % 2 === 0;
}); // [2, 4]

// Extend (merge objects)
var obj1 = { name: 'John' };
var obj2 = { age: 30 };
var merged = $.extend({}, obj1, obj2); // { name: 'John', age: 30 }

// Deep extend
var obj1 = { user: { name: 'John' } };
var obj2 = { user: { age: 30 } };
var merged = $.extend(true, {}, obj1, obj2); // { user: { name: 'John', age: 30 } }

// Make array
var nodes = $('div').get(); // Returns array of DOM elements
var first = $('div').get(0); // Returns first DOM element

// Index
var index = $('li').index($('#myLi')); // Get index of element
字符串工具方法
// Trim
var trimmed = $.trim('  hello  '); // 'hello'

// Parse JSON
var obj = $.parseJSON('{"name":"John"}');

// Serialize (form)
var queryString = $('#myForm').serialize(); // name=John&age=30
var data = $('#myForm').serializeArray(); // Array of objects

// Param (object to query string)
var queryString = $.param({ name: 'John', age: 30 }); // name=John&age=30
类型检查
$.isFunction(function() {});   // true
$.isArray([1, 2, 3]);         // true
$.isPlainObject({});          // true
$.isNumeric(123);             // true
$.isNumeric('123');           // true
$.isEmptyObject({});          // true
$.isWindow(window);           // true

延迟对象和 Promise

基本延迟对象
function asyncTask() {
    var deferred = $.Deferred();

    setTimeout(function() {
        deferred.resolve('Success!');
    }, 1000);

    return deferred.promise();
}

asyncTask()
    .done(function(result) {
        console.log(result);
    })
    .fail(function(error) {
        console.error(error);
    })
    .always(function() {
        console.log('Always runs');
    });
When(并行)
$.when(asyncTask1(), asyncTask2())
    .done(function(result1, result2) {
        console.log('All done:', result1, result2);
    })
    .fail(function() {
        console.error('One or more failed');
    });
Promise 方法
// then
asyncTask().then(
    function(result) {
        // Success callback
    },
    function(error) {
        // Error callback
    }
);

// pipe (chaining)
asyncTask()
    .pipe(function(result) {
        return asyncTask2(result);
    })
    .done(function(finalResult) {
        console.log(finalResult);
    });

插件开发

基本插件模式
// Attach plugin to $.fn (jQuery prototype)
(function($) {
    $.fn.highlight = function(options) {
        // Default settings
        var settings = $.extend({
            color: 'yellow',
            duration: 500
        }, options);

        // Return this for chaining
        return this.each(function() {
            var $this = $(this);
            $this.css('background-color', settings.color);
            $this.fadeIn(settings.duration);
        });
    };
})(jQuery);

// Usage
$('#myElement').highlight({ color: 'red', duration: 1000 });
带公共方法的插件
(function($) {
    var methods = {
        init: function(options) {
            var settings = $.extend({
                color: 'yellow'
            }, options);
            return this.each(function() {
                var $this = $(this);
                $this.data('highlight', settings);
                $this.css('background-color', settings.color);
            });
        },
        destroy: function() {
            return this.each(function() {
                $(this).removeData('highlight');
            });
        },
        color: function(newColor) {
            if (newColor) {
                return this.each(function() {
                    $(this).css('background-color', newColor);
                });
            }
            return this.css('background-color');
        }
    };

    $.fn.highlight = function(method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist');
        }
    };
})(jQuery);

// Usage
$('#myElement').highlight({ color: 'red' });
$('#myElement').highlight('color', 'blue');
$('#myElement').highlight('destroy');
Widget Factory(jQuery UI 模式)

如果使用 jQuery UI,请使用 Widget Factory:

$.widget('custom.highlighter', {
    options: {
        color: 'yellow'
    },
    _create: function() {
        this.element.css('background-color', this.options.color);
    },
    _setOption: function(key, value) {
        if (key === 'color') {
            this.element.css('background-color', value);
        }
        this._super(key, value);
    },
    color: function(newColor) {
        if (newColor) {
            this._setOption('color', newColor);
        }
        return this.options.color;
    }
});

// Usage
$('#myElement').highlighter({ color: 'red' });
$('#myElement').highlighter('color', 'blue');

最佳实践

性能
// Cache jQuery selectors
var $button = $('#myButton');
$button.on('click', handleClick);

// Use find() instead of context (faster in newer jQuery)
$('#container').find('.item'); // Better than $('.item', '#container')

// Use event delegation for many elements
$(document).on('click', '.dynamic-item', handleClick); // Better than binding to each

// Use .end() to return to previous state in chains
$('#container')
    .find('.item')
        .addClass('active')
    .end()
    .addClass('container-active');

// Minimize DOM reflows by batching changes
var $items = $('.item');
$items.css('opacity', 0); // Single reflow instead of many

// Use document fragment for multiple insertions
var fragment = document.createDocumentFragment();
$.each(items, function(i, item) {
    fragment.appendChild(item);
});
$('#container').append(fragment);
安全
// Check if element exists
if ($('#myElement').length) {
    // Element exists
}

// Use $(this) carefully inside nested functions
$('#myButton').on('click', function() {
    var $this = $(this);
    setTimeout(function() {
        $this.addClass('clicked'); // $this still refers to button
    }, 100);
});
事件命名空间
// Namespaced events for easier cleanup
$('#myButton').on('click.myNamespace', handleClick);
$('#myButton').off('.myNamespace'); // Remove all events in namespace

// Multiple namespaces
$('#myButton').on('click.app.submit', handleSubmit);
避免使用全局变量
// Wrap code in IIFE
(function($) {
    // Your code here
    var privateVariable = 'local';

    $('#myButton').on('click', function() {
        console.log(privateVariable);
    });
})(jQuery);

常见模式

表单验证
$('#myForm').on('submit', function(e) {
    e.preventDefault();
    var $form = $(this);
    var isValid = true;

    $form.find('input[required]').each(function() {
        var $input = $(this);
        if (!$input.val().trim()) {
            $input.addClass('error');
            isValid = false;
        } else {
            $input.removeClass('error');
        }
    });

    if (isValid) {
        $.ajax({
            url: $form.attr('action'),
            method: $form.attr('method'),
            data: $form.serialize(),
            success: function(response) {
                console.log('Form submitted successfully');
            }
        });
    }
});
无限滚动
$(window).on('scroll', function() {
    if ($(window).scrollTop() + $(window).height() >= $(document).height() - 100) {
        loadMoreItems();
    }
});
模态对话框
$('#openModal').on('click', function() {
    $('#modal').fadeIn(300).addClass('open');
});

$('#modal').on('click', function(e) {
    if ($(e.target).is('#modal') || $(e.target).is('.close')) {
        $(this).fadeOut(300).removeClass('open');
    }
});
标签页导航
$('.tab').on('click', function(e) {
    e.preventDefault();
    var $tab = $(this);
    var target = $tab.data('target');

    $('.tab').removeClass('active');
    $('.tab-content').removeClass('active');

    $tab.addClass('active');
    $(target).addClass('active');
});

调试技巧

// Check if jQuery is loaded
if (typeof jQuery === 'undefined') {
    console.error('jQuery is not loaded!');
}

// Check jQuery version
console.log('jQuery version:', $.fn.jquery);

// Check selector matches
console.log('Matched elements:', $('.my-selector').length);

// Inspect jQuery object
console.dir($('#myElement')); // Shows all methods

// Use $.holdReady() for debugging
$.holdReady(true);
// Load your code, then:
$.holdReady(false);

迁移到原生 JavaScript

帮助用户将 jQuery 迁移到原生 JS 时,以下是一些常见的对应写法:

// jQuery → Vanilla JS

// Selectors
$('#id')                    → document.getElementById('id')
$('.class')                 → document.querySelectorAll('.class')
$('div')                    → document.querySelectorAll('div')

// Events
$('.class').on('click', fn) → document.querySelectorAll('.class').forEach(el → el.addEventListener('click', fn))

// Classes
$(el).addClass('class')     → el.classList.add('class')
$(el).removeClass('class')  → el.classList.remove('class')
$(el).toggleClass('class')  → el.classList.toggle('class')

// Content
$(el).html()                → el.innerHTML
$(el).text()                → el.textContent
$(el).val()                 → el.value

// Attributes
$(el).attr('src', 'url')    → el.setAttribute('src', 'url')
$(el).data('id', '123')     → el.dataset.id = '123'

// Styles
$(el).css('color', 'red')   → el.style.color = 'red'

// AJAX
$.ajax(...)                 → fetch(url, options).then(r → r.json())

// Ready handler
$(function() {})            → document.addEventListener('DOMContentLoaded', fn)

资源

评论

支持 Markdown