Core & Selectors
Everything starts with $(). A jsKjs set is a real Array subclass, so native methods (map, spread, for...of) work alongside the chainable API.
$()
$(selector [, context]) · $(element) · $(html) · $(fn)
The heart of the library. Accepts a CSS selector (optionally scoped to a context), a DOM node, window, a NodeList/array, an HTML string (creates elements), or a function (runs on DOM ready).
$('.card') // CSS selector
$('li', '#menu') // scoped to context
$(document.body) // wrap a node
$('<div class="x">Hi</div>') // create elements
$(() => console.log('DOM ready'));
.each()
.each((index, element) => {}) → self
Iterate the set jQuery-style. Inside the callback, this is the current element.
$('.item').each(function (i, el) {
console.log(i, el.id, this === el); // true
});
.get()
.get([index]) → element | element[]
Without arguments returns a plain array of all elements; with an index returns that raw element (negative indexes count from the end). Bracket access $(x)[0] also works.
$('.item').get(); // [el, el, el]
$('.item').get(-1); // last raw element
.eq()
.eq(index) → KJ
Reduce the set to the element at the given index, returned as a new chainable set. Negative indexes count from the end.
$('.item').eq(1).addClass('second');
$('.item').eq(-1).text('last');
.first() / .last()
.first() → KJ · .last() → KJ
Shortcuts for .eq(0) and .eq(-1).
$('li').first().addClass('head');
$('li').last().addClass('tail');
.index()
.index([element]) → number
Without arguments, the position of the first element among its siblings. With an element, its position within this set.
$('.active').index(); // e.g. 2
.add()
.add(selector | elements) → KJ
Merge more elements into the set (deduplicated).
$('.card').add('.banner').addClass('highlight');
Content
Read and write element content and form values.
.html()
.html([value]) → string | self
Get the first element’s innerHTML, or set it on every element in the set.
$('#box').html(); // read
$('#box').html('<b>New</b>'); // write
.text()
.text([value]) → string | self
Get or set textContent. Setting always escapes — it can never inject HTML.
$('#title').text('Safe & sound');
.val()
.val([value]) → any | self
Get or set form values. Checkboxes read/write booleans; multi-selects read as arrays.
$('#email').val(); // 'a@b.c'
$('#agree').val(true); // checks the box
$('#tags').val(); // ['js', 'css'] for multi-select
Attributes & Data
HTML attributes, DOM properties, and per-element data storage (backed by a WeakMap, so removed elements are garbage-collected automatically).
.attr()
.attr(name [, value]) · .attr(object) → string | self
Get an attribute from the first element, or set one or many on all elements.
$('img').attr('src');
$('img').attr('alt', 'Logo');
$('a').attr({ href: '/', title: 'Home' });
.removeAttr()
.removeAttr(name) → self
Remove an attribute from every element in the set.
$('input').removeAttr('disabled');
.prop()
.prop(name [, value]) → any | self
Get or set a DOM property (as opposed to an HTML attribute) — checked, disabled, selectedIndex, etc.
$('#opt-in').prop('checked'); // true/false
$('button').prop('disabled', true);
.data()
.data([key [, value]]) · .data(object) → any | self
Read data-* attributes (JSON auto-parsed) or store arbitrary values against elements. Stored values live in a WeakMap — no memory leaks, no cleanup.
<div id="u" data-config='{"admin":true}'></div>
$('#u').data('config').admin; // true (parsed)
$('#u').data('profile', { id: 7 }); // store anything
$('#u').data(); // all data merged
.removeData()
.removeData(key) → self
Delete a stored data value.
$('#u').removeData('profile');
Classes
Space-separated multi-class strings are supported everywhere.
.addClass()
.addClass(names) → self
Add one or more classes.
$('.card').addClass('active highlight');
.removeClass()
.removeClass([names]) → self
Remove classes; with no argument, removes all classes.
$('.card').removeClass('active');
$('.card').removeClass(); // wipe class attribute
.toggleClass()
.toggleClass(names [, force]) → self
Toggle classes, optionally forcing on/off with a boolean.
$('.menu').toggleClass('open');
$('.menu').toggleClass('open', isOpen);
.hasClass()
.hasClass(name) → boolean
True if any element in the set has the class.
if ($('#panel').hasClass('open')) close();
CSS & Geometry
Styles, sizes, positions, scrolling, visibility. Numbers get px automatically (except unitless properties like opacity); CSS custom properties (--vars) are supported.
.css()
.css(name [, value]) · .css(object) → string | self
Get a computed style from the first element, or set styles on all.
$('.card').css('color'); // computed
$('.card').css('margin-top', 20); // → '20px'
$('.card').css({ opacity: .5, '--accent': 'red' });
.width() / .height()
.width([value]) · .height([value]) → number | self
Measured size (from getBoundingClientRect) or set the CSS size. On $(window), returns the viewport size.
$('.card').width(); // 320
$('.card').height(200); // set
$(window).width(); // viewport
.offset()
.offset() → { top, left }
Position relative to the document, including scroll.
const { top } = $('#hero').offset();
.position()
.position() → { top, left }
Position relative to the offset parent.
const p = $('.tooltip').position();
.scrollTop() / .scrollLeft()
.scrollTop([value]) · .scrollLeft([value]) → number | self
Get or set scroll position. Works on elements and on $(window).
$(window).scrollTop(); // read page scroll
$('#panel').scrollTop(0); // scroll to top
.show() / .hide() / .toggle()
.show() · .hide() · .toggle([state]) → self
Instant visibility via display. .hide() remembers the previous display value so .show() restores it correctly.
$('.modal').show();
$('.hint').toggle(); // flip
$('.hint').toggle(isAdmin); // force
Insertion & Removal
All insertion methods accept HTML strings, elements, jsKjs sets, or plain text — and multiple arguments at once.
.append() / .prepend()
.append(...content) · .prepend(...content) → self
Insert content inside each element, at the end or the start.
$('#list').append('<li>End</li>');
$('#list').prepend($('<li>Start</li>'));
.before() / .after()
.before(...content) · .after(...content) → self
Insert content outside each element, as a previous or next sibling.
$('.section').before('<hr>');
.appendTo() / .prependTo()
.appendTo(target) · .prependTo(target) → self
Reversed form: insert this set into the target.
$('<li>New</li>').appendTo('#list');
.wrap()
.wrap(html) → self
Wrap each element in the given structure.
$('img').wrap('<figure class="frame">');
.remove()
.remove() → self
Remove elements from the DOM. Data cleanup is automatic (WeakMap).
$('.toast').remove();
.empty()
.empty() → self
Remove all children of each element.
$('#results').empty();
.clone()
.clone([deep = true]) → KJ
Deep-copy the elements.
$('#template-row').clone().appendTo('#table');
.replaceWith()
.replaceWith(content) → self
Replace each element with new content.
$('.old-banner').replaceWith('<div class="new">Hi</div>');
Traversal
Walk the tree. Every method returns a new chainable set; results are deduplicated.
.find()
.find(selector) → KJ
All descendants matching a selector.
$('#app').find('.btn').addClass('ready');
.filter()
.filter(selector | fn) → KJ
Keep only matching elements. Accepts a selector or a predicate (i, el) => boolean.
$('.item').filter('.active');
$('.item').filter((i, el) => el.dataset.price > 100);
.not()
.not(selector) → KJ
Drop matching elements.
$('.item').not('.sold-out').show();
.is()
.is(selector | element) → boolean
Test whether any element in the set matches.
if ($(e.target).is('button')) { … }
.closest()
.closest(selector) → KJ
Nearest matching ancestor (including the element itself). The backbone of event delegation.
$(e.target).closest('.card').addClass('selected');
.parent() / .parents()
.parent() · .parents([selector]) → KJ
Direct parent, or all ancestors (optionally filtered).
$('.btn').parent();
$('.btn').parents('.section');
.children()
.children([selector]) → KJ
Direct children, optionally filtered.
$('#list').children('li.active');
.siblings()
.siblings([selector]) → KJ
All siblings, optionally filtered.
$('.tab.active').siblings().removeClass('active');
.next() / .prev()
.next([selector]) · .prev([selector]) → KJ
Adjacent siblings, optionally required to match a selector.
$('.step.current').next().addClass('upcoming');
Events
Modern event handling with delegation, namespaces, once-only handlers, and custom events with payloads.
.on()
.on(types [, delegateSelector], handler) → self
Attach handlers. Multiple space-separated events and .namespace suffixes are supported. With a delegate selector, the handler fires for matching descendants — including ones added later — and this is the matched element.
$('.btn').on('click', e => save());
$('.btn').on('click.menu keydown.menu', handler);
// Delegation — survives DOM swaps
$('#list').on('click', '.item', function (e) {
$(this).toggleClass('selected');
});
.one()
.one(types [, delegateSelector], handler) → self
Like .on() but the handler runs at most once.
$('#intro').one('click', dismiss);
.off()
.off([types] [, handler]) → self
Remove handlers — all of them, by event type, by namespace, or by specific handler reference.
$('.btn').off('click');
$('.btn').off('.menu'); // whole namespace
$('.btn').off(); // everything
.trigger()
.trigger(type [, detail]) → self
Dispatch an event (bubbling, cancelable). The optional payload arrives as the handler’s second argument.
$('#app').on('cart:add', (e, item) => render(item));
$('#app').trigger('cart:add', { sku: 'A-1' });
.hover()
.hover(enterFn [, leaveFn]) → self
Shorthand for mouseenter/mouseleave.
$('.card').hover(
function () { $(this).addClass('lift'); },
function () { $(this).removeClass('lift'); });
Shortcuts
.click([fn]) .change([fn]) .submit([fn]) … → self
With a handler: binds it. Without: triggers the event. Available for click, dblclick, change, input, submit, keydown, keyup, keypress, mousedown, mouseup, mousemove, mouseenter, mouseleave, scroll, resize, touchstart, touchend, contextmenu.
$('#save').click(() => submit());
$('#save').click(); // programmatic click
.focus() / .blur()
.focus([fn]) · .blur([fn]) → self
Bind a handler, or move focus when called without one.
$('#search').focus(); // focus the field
$('#search').focus(onFocus); // bind
AJAX
Powered by fetch. Every call returns a native Promise (so await just works) with jQuery-style .done/.fail/.always shims attached.
$.ajax()
$.ajax(url | options [, options]) → Promise
Full-control requests. Options: url, method (or jQuery’s type), data (object → urlencoded or querystring; FormData; string), json: true (send JSON body), dataType (’json’ | ’auto’), headers, timeout (ms, auto-aborts), credentials, and callbacks success(data, status, res), error(err), complete(). The promise also has .abort().
const p = $.ajax({
url: '/api/items', method: 'POST',
data: { title: 'Hello' }, json: true,
headers: { 'X-Token': 'abc' }, timeout: 5000,
});
p.done(d => render(d)).fail(err => alert(err.status));
// or simply: const d = await p;
$.get()
$.get(url [, data] [, success]) → Promise
GET shorthand; data becomes the query string.
const html = await $.get('/partials/nav.html');
$.get('/api/search', { q: 'cats' }, render);
$.post()
$.post(url [, data] [, success]) → Promise
POST shorthand (urlencoded body by default).
await $.post('/api/save', { name: 'Ada' });
$.getJSON()
$.getJSON(url [, data] [, success]) → Promise
GET with forced JSON parsing.
const users = await $.getJSON('/api/users');
.load()
.load(url [ + ’ selector’] [, done]) → self
Fetch HTML into the element. Add a space + selector to insert only a fragment of the response.
$('#panel').load('/partials/news.html');
$('#panel').load('/page.html #main');
.serialize()
.serialize() → string
URL-encode a form’s fields.
$('#signup').serialize(); // "name=Ada&plan=pro"
.serializeObject()
.serializeObject() → object
A form’s fields as a plain object (jsKjs extra).
const { email } = $('#signup').serializeObject();
Hyper — Declarative AJAX
htmx-style: describe requests in HTML with kj-* attributes and never write the handler. A MutationObserver auto-binds content added later, including content swapped in by Hyper itself.
kj-get / kj-post / kj-put / kj-patch / kj-delete
kj-<verb>="/url"
The URL to request with that HTTP verb. Forms auto-serialize their fields; named inputs, selects and textareas send their own value. Default triggers: forms → submit, inputs/selects → change, everything else → click.
<button kj-get="/api/joke" kj-target="#out">Joke</button>
<form kj-post="/api/subscribe" kj-target="#msg">
<input name="email" type="email">
<button>Subscribe</button>
</form>
kj-target
kj-target="#selector"
Where the response HTML goes (default: the element itself).
<button kj-get="/api/stats" kj-target="#stats">Refresh</button>
kj-swap
kj-swap="innerHTML | outerHTML | textContent | beforebegin | afterbegin | beforeend | afterend | none"
How the response is inserted into the target. outerHTML replaces the target entirely; the four position values insert adjacent to it; none makes the request without touching the DOM.
<button kj-delete="/api/items/7" kj-target="#row-7"
kj-swap="outerHTML">Delete</button>
kj-trigger
kj-trigger="event [delay:Nms] | load | revealed | every Ns"
When to fire: any DOM event (with optional debounce), load (immediately), revealed (when scrolled into view, via IntersectionObserver), or every Ns (polling).
<input name="q" kj-get="/api/search"
kj-trigger="keyup delay:300ms" kj-target="#results">
<div kj-get="/api/comments" kj-trigger="revealed">…</div>
<span kj-get="/api/price" kj-trigger="every 10s"></span>
kj-confirm
kj-confirm="message"
Show a native confirm dialog before requesting.
<button kj-delete="/api/acct" kj-confirm="Really delete?">✕</button>
kj-indicator
kj-indicator="#selector"
Element to show while the request is in flight (the trigger also gets aria-busy="true").
<button kj-get="/slow" kj-indicator="#spinner">Go</button>
<span id="spinner" hidden>Loading…</span>
kj-include / kj-vals
kj-include="#form" · kj-vals=’{"k":"v"}’
Send extra data: the fields of another form, and/or literal JSON values.
<button kj-post="/api/filter" kj-include="#filters"
kj-vals='{"page": 2}' kj-target="#grid">Next</button>
kj-push-url
kj-push-url="true | /path"
Push the request URL (or a given path) into browser history after a successful swap.
<a kj-get="/products?page=2" kj-target="#grid"
kj-push-url="true">Page 2</a>
Lifecycle events
kj:before · kj:after · kj:error · kj:load
Fired on the triggering element (kj:before/after/error, with { url, verb, … } detail) and on the target after a swap (kj:load).
$('#btn').on('kj:error', (e, d) =>
toast('Failed: ' + d.error.status));
$('#grid').on('kj:load', highlightNew);
Pulse — Reactivity
Alpine-style: declare state on an element with kj-data; bind it with directives. Mutating state re-renders the component. No virtual DOM, no build step. Inside expressions, $el is the element and $event the event.
kj-data
kj-data="{ … }" | kj-data="componentName"
Declares a component and its reactive scope. An init() method, if present, runs on mount. Pass a registered component name to reuse logic.
<div kj-data="{ count: 0, open: false }">…</div>
<div kj-data="dropdown">…</div> <!-- registered -->
kj-text / kj-html
kj-text="expr" · kj-html="expr"
Bind textContent or innerHTML to an expression. Prefer kj-text for anything user-supplied.
<span kj-text="count"></span>
<p kj-text="name ? 'Hi ' + name : 'Who?'"></p>
kj-show
kj-show="expr"
Show/hide via display based on a truthy expression.
<ul kj-show="open">…</ul>
kj-model
kj-model="property"
Two-way binding for inputs, textareas, selects. Checkboxes bind booleans.
<input kj-model="email">
<input type="checkbox" kj-model="agreed">
@event / kj-on:event
@click="expr" · kj-on:input="expr" · modifiers: .prevent .stop .enter .escape
Run an expression on an event. Modifiers call preventDefault/stopPropagation or filter keys.
<button @click="count++">+1</button>
<form @submit.prevent="save()">…</form>
<input @keyup.enter="search($el.value)">
:attr / kj-bind:attr
:src="expr" · kj-bind:class="expr"
Bind any attribute to an expression. :class merges with the element’s static classes; false/null removes the attribute.
<img :src="user.avatar" :alt="user.name">
<button :disabled="saving">Save</button>
<div :class="open ? 'expanded' : ''">…</div>
$.component()
$.component(name, factory)
Register a reusable component factory, then reference it by name in kj-data.
$.component('counter', () => ({
count: 0,
init() { console.log('mounted'); },
}));
// <div kj-data="counter">…</div>
$.store()
$.store(name [, initial]) → reactive object
Create or retrieve a global reactive store. Any component reading it re-renders when it changes. Getters work as computed values.
const cart = $.store('cart', {
items: [],
get total() { return this.items.length; },
});
cart.items.push({ sku: 'A-1' }); // UI updates
$.reactive()
$.reactive(object) → proxy
A standalone reactive proxy without auto-rendering — for your own change-tracking logic.
const state = $.reactive({ x: 1 });
Motion — Animation
GSAP-style tweening on requestAnimationFrame. Transform shorthands (x, y, rotate, scale…) plus any numeric CSS property. Durations in seconds. All tweens return Promises.
$.to()
$.to(target, { …props, duration, delay, ease, stagger, onComplete }) → Promise
Tween to a state. stagger offsets each element’s start; onComplete fires after the last finishes. Also chainable on sets: $(sel).to(props).
$.to('.card', { x: 200, rotate: 10, opacity: .8,
duration: .6, ease: 'back.out' });
await $.to('#modal', { opacity: 0, duration: .3 });
$('#modal').hide();
$.from()
$.from(target, props) → Promise
Jump to the given state, then tween back to the original — the classic entrance pattern.
$.from('.hero h1', { y: 40, opacity: 0,
duration: .8, ease: 'power2.out' });
$.fromTo()
$.fromTo(target, fromProps, toProps) → Promise
Explicit start and end states.
$.fromTo('.badge', { scale: 0 },
{ scale: 1, duration: .5, ease: 'elastic.out' });
$.timeline()
$.timeline([defaults]) → timeline
Sequence tweens. Steps run one after another; pass position ’<’ to start a step together with the previous one. .add(fn) inserts arbitrary steps. Auto-plays.
$.timeline({ duration: .5, ease: 'power2.out' })
.from('.hero', { opacity: 0 })
.from('.hero h1', { y: 30 })
.from('.hero p', { y: 30 }, '<') // together
.to('.cta', { scale: 1.1 });
stagger
stagger: seconds
Offset each element in a multi-element tween — the signature "cascade" effect.
$.to('.item', { y: 0, opacity: 1,
duration: .4, stagger: .08 });
Easings
ease: name | (t) => number
Built in: linear, ease-in, ease-out, ease-in-out, power2.in, power2.out, power2.inOut, back.out, elastic.out, bounce.out — or pass any function mapping 0→1 progress.
$.to('.ball', { y: 200, ease: 'bounce.out', duration: 1 });
$.to('.dot', { x: 100, ease: t => t * t });
jQuery Effect Shims
The classics, rebuilt on the Motion engine. Durations in milliseconds, exactly as jQuery developers expect.
.fadeIn() / .fadeOut() / .fadeToggle()
.fadeIn([ms = 400] [, complete]) → self
Fade elements in (from hidden) or out (hiding when done).
$('.toast').fadeIn(300);
$('.toast').fadeOut(300, function () { $(this).remove(); });
.slideDown() / .slideUp() / .slideToggle()
.slideDown([ms = 400] [, complete]) → self
Animate height to reveal or collapse.
$('#faq-answer').slideToggle(250);
.animate()
.animate(props [, ms = 400] [, ease] [, complete]) → self
jQuery-signature tween of numeric CSS properties.
$('.box').animate({ marginLeft: 100, opacity: .5 }, 600);
Utilities
Small helpers on the $ namespace.
$.each()
$.each(arrayOrObject, (keyOrIndex, value) => {})
Iterate arrays, array-likes, or plain objects.
$.each({ a: 1, b: 2 }, (k, v) => console.log(k, v));
$.map()
$.map(collection, fn) → array
Map + flatten one level.
$.map([1, 2], n => [n, n * 10]); // [1,10,2,20]
$.extend()
$.extend([deep], target, …sources) → target
Merge objects; pass true first for deep merge.
$.extend(defaults, options);
$.extend(true, config, { api: { retries: 3 } });
$.debounce()
$.debounce(fn [, wait = 300]) → fn
Returns a function that fires only after calls stop for wait ms.
$('#q').on('input', $.debounce(search, 300));
$.throttle()
$.throttle(fn [, wait = 300]) → fn
Returns a function that fires at most once per wait ms.
$(window).on('scroll', $.throttle(onScroll, 100));
$.param()
$.param(object) → string
Serialize an object to a query string.
$.param({ a: 1, b: 'x y' }); // "a=1&b=x+y"
$.parseHTML()
$.parseHTML(html) → element[]
Parse an HTML string into an array of nodes.
const [li] = $.parseHTML('<li>Hi</li>');
$.escape()
$.escape(string) → string
HTML-escape text — use it whenever you string-build HTML from user data.
$('#out').html('<b>' + $.escape(userInput) + '</b>');
$.uuid()
$.uuid() → string
A cryptographically strong UUID (v4).
const id = $.uuid();
Type checks
$.isArray(x) · $.isFunction(x) · $.isPlainObject(x) · $.trim(s)
Small predicates and string trim, kept for jQuery compatibility.
$.isPlainObject({}); // true
$.isArray('nope'); // false
$.noConflict()
$.noConflict() → $
Restore the previous window.$ and return jsKjs (also always available as kj and jsKjs).
const j = $.noConflict();
j('#app').addClass('ready');
$.version
$.version → string
The library version.
console.log($.version); // "1.0.0"