jquery

📁 btafoya/jquery-agent-skill 📅 3 days ago
3
总安装量
3
周安装量
#60273
全站排名
安装命令
npx skills add https://github.com/btafoya/jquery-agent-skill --skill jquery

Agent 安装分布

github-copilot 3
codex 3
kimi-cli 3
gemini-cli 3
cursor 3
opencode 3

Skill 文档

jQuery

jQuery is a fast, small, and feature-rich JavaScript library that makes HTML document traversal and manipulation, event handling, animation, and AJAX much simpler with an easy-to-use API that works across a multitude of browsers.

When to Use This Skill

This skill should be used when the user:

  • Mentions jQuery, $, or jQuery syntax patterns
  • Asks about DOM manipulation using selectors like $('#id') or $('.class')
  • Works with event handlers like .on(), .click(), .submit(), .hover()
  • Needs help with AJAX requests using $.ajax(), $.get(), $.post(), or $.getJSON()
  • Wants to add animations or effects like .fadeIn(), .slideUp(), .animate()
  • Asks about jQuery plugins or extending $.fn
  • Needs to debug jQuery code or fix common issues
  • Wants to migrate jQuery code to vanilla JavaScript
  • Asks about jQuery utilities like $.each(), $.map(), $.extend()
  • Needs help with the jQuery object, chaining, or deferred promises

Core Concepts

The jQuery Object $ and jQuery

The global function $ (and its alias jQuery) is the entry point for all jQuery operations. It returns a jQuery object (often called a “wrapped set”) containing matched DOM elements.

// 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)

Ready Handler

Always wrap jQuery code in a document ready handler to ensure the DOM is fully loaded:

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

// Or shorter
$(function() {
    // Your code here
});

Chaining

jQuery methods return the jQuery object, enabling method chaining:

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

Selectors

jQuery uses CSS-like selectors to find elements:

// 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 Manipulation

Getting and Setting Content

// 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

Modifying Elements

// 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

Creating and Inserting Elements

// 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>');

Traversing

// 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

Event Handling

Binding Events

// 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!');
});

Unbinding Events

// Remove specific handler
$('#myButton').off('click', myHandler);

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

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

Event Object

$('#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);
    }
});

Utility Events

// 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 and HTTP Requests

Basic 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');
});

Shorthand Methods

// 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: 'john@example.com' }, 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 Configuration

$.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');
        }
    }
});

Global AJAX Events

// 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 Setup

// 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();
    }
});

Animations and Effects

Basic Effects

// 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

Custom Animations

// 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);

Animation Control

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 });

Utilities

Array/Object Utilities

// 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

String Utilities

// 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

Type Checking

$.isFunction(function() {});   // true
$.isArray([1, 2, 3]);         // true
$.isPlainObject({});          // true
$.isNumeric(123);             // true
$.isNumeric('123');           // true
$.isEmptyObject({});          // true
$.isWindow(window);           // true

Deferred and Promises

Basic Deferred

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 (Parallel)

$.when(asyncTask1(), asyncTask2())
    .done(function(result1, result2) {
        console.log('All done:', result1, result2);
    })
    .fail(function() {
        console.error('One or more failed');
    });

Promise Methods

// 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);
    });

Plugin Development

Basic Plugin Pattern

// 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 });

Plugin with Public Methods

(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 pattern)

If using jQuery UI, use the 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');

Best Practices

Performance

// 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);

Safety

// 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);
});

Namespace Events

// 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);

Avoid Global Variables

// Wrap code in IIFE
(function($) {
    // Your code here
    var privateVariable = 'local';

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

Common Patterns

Form Validation

$('#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');
            }
        });
    }
});

Infinite Scroll

$(window).on('scroll', function() {
    if ($(window).scrollTop() + $(window).height() >= $(document).height() - 100) {
        loadMoreItems();
    }
});

Modal Dialog

$('#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 Navigation

$('.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');
});

Debugging Tips

// 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);

Migration to Vanilla JavaScript

When helping users migrate from jQuery to vanilla JS, here are common equivalents:

// 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)

Resources