入门
安装与主题
jQuery UI 需要 jQuery 作为依赖。引入 CSS 主题和 JS 文件。ThemeRoller 可自定义主题。所有组件都在 DOM 元素上初始化。
<!-- jQuery UI requires jQuery core first -->
<link rel="stylesheet"
href="https://code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js"></script>文档就绪
在 $(function(){})(文档就绪)中初始化组件,确保 DOM 已存在。通过在 jQuery 集合上调用组件名称作为方法来初始化组件。选项以对象形式传入;方法通过传入方法名字符串来调用。
# Install via npm
npm install jquery jquery-ui
# Import in your bundle
import $ from "jquery";
import "jquery-ui/ui/widgets/datepicker";
import "jquery-ui/themes/base/all.css";
// Or import the full bundle
import "jquery-ui";组件方法模式
所有 jQuery UI 组件共享相同的 API:用选项初始化、通过名称字符串调用方法、通过 'option' 读写选项、用 'destroy' 销毁。'disable' 和 'enable' 切换禁用状态。这个一致的模式适用于每个组件。
$(function () {
// Initialize a widget on a selector
$("#datepicker").datepicker();
$("#dialog").dialog();
// Pass options as an object
$("#accordion").accordion({
active: false,
collapsible: true,
});
// Get or set an option after init
$("#accordion").accordion("option", "active", 1);
});ThemeRoller 基础
ThemeRoller(jqueryui.com/themeroller)是构建自定义 jQuery UI 主题的官方工具。它生成一个包含颜色、圆角和图标变量的 CSS 文件。CSS 框架类(ui-widget、ui-state-*、ui-corner-*)被所有组件共享,保持主题一致性。
// All widgets share the same API conventions
$("#dialog").dialog("open"); // call a method
$("#dialog").dialog("option", "title"); // get an option
$("#dialog").dialog("option", "modal", true); // set an option
$("#dialog").dialog("disable"); // disable widget
$("#dialog").dialog("enable"); // enable widget
$("#dialog").dialog("widget"); // get the wrapper element
$("#dialog").dialog("destroy"); // remove widget entirelyCDN 与下载
CDN 是最快速的入门方式。生产环境中,下载构建器只打包你选择的组件 ,减小文件体积。使用 npm 时,可以导入单个组件模块(jquery-ui/ui/widgets/...),让打包工具 tree-shake 未使用的代码。
<!-- Default base theme -->
<link rel="stylesheet"
href="https://code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
<!-- Other bundled themes: ui-lightness, ui-darkness, smoothness, redmond, ... -->
<link rel="stylesheet"
href="https://code.jquery.com/ui/1.13.2/themes/smoothness/jquery-ui.css">
<!-- Override theme with your own CSS -->
<link rel="stylesheet" href="jquery-ui.css">
<link rel="stylesheet" href="my-theme-overrides.css">无冲突与版本检查
读取 $.ui.version 验证已加载的版本。jQuery UI 基于 jQuery 构建,所以 $.noConflict() 在全局释放 $;用 jQuery(function($){...}) 包裹代码以在局部别名 $。检查 $.ui.<组件> 可检测某组件模块是否已加载(对自定义下载构建器打包很有用)。
/* jQuery UI CSS classes are namespaced with ui- */
.ui-widget /* base widget class */
.ui-widget-header /* header bar (accordion, datepicker) */
.ui-widget-content /* content area */
.ui-state-default /* default interactive state */
.ui-state-hover /* mouse-over state */
.ui-state-active /* active/selected state */
.ui-state-focus /* keyboard focus state */
.ui-state-disabled /* disabled state */
.ui-corner-all /* rounded corners (themable) */
.ui-icon /* base icon class */日期选择器
基础日期选择器
Datepicker 附加到 <input>(弹出式)或 <div>/<span>(内联式)。minDate/maxDate 接受 Date 对象、数字(距今天的天数)或字符串如 '+1Y +1M'。numberOfMonths 同时显示多个月份。选中的值默认放入 input。
<!-- HTML -->
<div id="box" class="ui-widget-content" style="width:100px;height:100px;">
Drag me
</div>
<!-- JS -->
<script>
$(function () {
$("#box").draggable();
});
</script>日期格式
dateFormat 控制选中日期在输入框中的显示方式。令牌:yy=四位年份,y=两位,mm=月份(01),m=1,MM=完整月份名,dd=日(01),d=1,DD=完整星期名。使用 altField + altFormat 在隐藏 input 中存储机器可读的值(如 ISO),同时向用户显示友好格式。
$("#box").draggable({
axis: "x", // constrain to x or y axis
containment: "parent", // or "window", "document", or selector
cursor: "move", // cursor while dragging
cursorAt: { left: 5 }, // offset cursor from drag handle
grid: [20, 20], // snap to grid
delay: 100, // ms delay before drag starts
distance: 5, // px before drag starts
revert: true, // snap back to start
revertDuration: 200, // revert animation duration
scroll: false, // prevent auto-scroll
helper: "clone", // "original", "clone", or function
opacity: 0.6, // opacity while dragging
zIndex: 1000, // z-index while dragging
});本地化 (i18n)
每个语言环境位于 i18n/datepicker-<lang>.js 文件中,填充 $.datepicker.regional[lang],包含翻译的月/日名称、dateFormat 和 firstDay。将该对象传给 datepicker() 可切换整个 UI,也可覆盖单个字符串进行精细控制。firstDay: 0 = 周日,1 = 周一。
$("#box").draggable({
start: function (event, ui) {
console.log("Drag started", ui.position);
},
drag: function (event, ui) {
// Fires continuously during drag
console.log(ui.position.left, ui.position.top);
},
stop: function (event, ui) {
console.log("Drag stopped at", ui.position);
console.log("Offset:", ui.offset);
},
});最小/最大日期与禁用日期
minDate/maxDate 限定可选范围。beforeShowDay 是对每个日期单元格调用的回调;返回 [可选, 类名, 提示] 来控制某天是否可选及其外观。这是将周末、假日或业务特定禁用日期置灰的标准方法。
<!-- Only the header acts as the drag handle -->
<div id="box" class="ui-widget-content">
<div class="drag-handle">Drag from here</div>
<div class="content">Some content here</div>
<textarea>Editable content</textarea>
</div>
<script>
$("#box").draggable({
handle: ".drag-handle", // only this starts the drag
cancel: "textarea", // these elements never start a drag
});
</script>月份与年份下拉框
changeMonth 和 changeYear 添加下拉框,用户可以直接跳转年份而无需逐月翻页。yearRange 限制下拉框的年份范围(绝对值 '2020:2030' 或相对值 '-10:+10')。showButtonPanel 在日历底部显示 Today 和 Done 按钮。
// Constrain within a parent element
$("#box").draggable({ containment: "parent" });
// Constrain within the window
$("#box").draggable({ containment: "window" });
// Constrain within a specific selector
$("#box").draggable({ containment: "#drag-area" });
// Constrain to an explicit bounding box [x1, y1, x2, y2]
$("#box").draggable({ containment: [0, 0, 500, 300] });
// Snap to a 50px grid
$("#box").draggable({ grid: [50, 50] });事件与方法
onSelect 在用户选择某天时触发;onClose 在弹出框关闭时触发(无论是否有选择);onChangeMonthYear 在用户切换月份时触发。getDate 返回 JS Date;setDate 接受 Date、数字或字符串。show/hide 以编程方式控制弹出框。
$(".card").draggable({
snap: ".snap-target", // selector of elements to snap to
snapMode: "inner", // "inner", "outer", or "both"
snapTolerance: 30, // px distance to trigger snap
});
// Snap to all siblings of the same class
$(".card").draggable({
snap: ".card",
snapTolerance: 20,
});自动完成
基础自动完成
Autocomplete 在用户输入时建议匹配项。source 是数据源:字符串数组、{label, value} 对象数组(label 显示在菜单中,value 插入输入框)、URL 字符串(服务端过滤)或函数。当 source 是本地数组时,菜单默认在客户端过滤。
<div id="draggable" class="ui-widget-content">Drag me</div>
<div id="droppable" class="ui-widget-header">Drop here</div>
<script>
$(function () {
$("#draggable").draggable();
$("#droppable").droppable({
drop: function (event, ui) {
$(this).addClass("ui-state-highlight")
.html("Dropped!");
},
});
});
</script>远程数据源 (AJAX)
对于大型数据集,在服务端过滤。source 函数接收 request(其中 request.term = 当前输入)和 response 回调。异步获取匹配项并传给 response。minLength 避免过早请求;delay 对输入去抖以减少服务器负载。
$("#droppable").droppable({
accept: ".special", // only accept matching draggables
activeClass: "ui-state-default", // class while a drag is active
hoverClass: "ui-state-hover", // class while draggable is over
tolerance: "fit", // drop detection mode
greedy: true, // stop event propagation
disabled: false, // disable the droppable
});自定义数据与 renderItem
覆盖实例的 _renderItem 可完全控制每个菜单行的 HTML —— 适用于富结果(头像、描述、徽章)。默认插入 item.label。手动设置输入值时务必从 select/focus 返回 false,防止组件覆盖它。通过 .autocomplete('instance') 访问实例。
$("#droppable").droppable({
activate: function (event, ui) {
// Fires when an accepted draggable starts moving
$(this).addClass("ui-state-default");
},
deactivate: function (event, ui) {
// Fires when the drag ends (drop or cancel)
$(this).removeClass("ui-state-default");
},
over: function (event, ui) {
// Draggable entered the drop zone
$(this).addClass("ui-state-hover");
},
out: function (event, ui) {
// Draggable left the drop zone
$(this).removeClass("ui-state-hover");
},
drop: function (event, ui) {
// Draggable was released here
console.log("Dropped:", ui.draggable);
},
});分类
官方 Categories 示例通过 $.widget 扩展 autocomplete,覆盖 _renderMenu 将结果按分类标题分组。先按分类排序项目,使标题只出现一次。_renderItemData 渲染普通行;只需在分类变化时注入标题 <li>。
<!-- HTML: red and blue boxes -->
<div class="red draggable">Red</div>
<div class="blue draggable">Blue</div>
<div id="red-bin" class="bin">Red bin</div>
<div id="blue-bin" class="bin">Blue bin</div>
<script>
// Only accept elements matching the selector
$("#red-bin").droppable({ accept: ".red" });
$("#blue-bin").droppable({ accept: ".blue" });
// Or use a function for dynamic logic
$("#any-bin").droppable({
accept: function (drag) {
return $(drag).data("category") === "recyclable";
},
});
</script>多值输入
此多值模式(来自官方示例)允许用户在一个输入框中添加多个标签。每次选择时,将最后一个部分词替换为选中的值,并重新添加一个空词以继续输入。$.ui.autocomplete.filter 执行客户端匹配;keyCode.TAB 处理防止组件在输入过程中抢走焦点。
$("#droppable").droppable({
// "fit": draggable must be fully inside (default)
tolerance: "fit",
// "intersect": at least 50% overlap
tolerance: "intersect",
// "pointer": mouse pointer must be inside
tolerance: "pointer",
// "touch": any edge touching counts
tolerance: "touch",
});组合框 (Select + Autocomplete)
Combobox 组件(官方示例)用文本输入框包装原生 <select>,用户可以输入过滤或从下拉框中选择 —— 结合了 select 的选项与 autocomplete 的自由输入。这是一个起点:扩展 _createShowAllButton 和 _destroy 以满足需求。无障碍优先时建议使用原生 <select>。
<!-- CSS -->
<style>
.drop-active { border: 2px dashed #ccc; }
.drop-hover { border: 2px solid #0a0; background: #efe; }
</style>
<!-- JS -->
$("#zone").droppable({
accept: ".item",
activeClass: "drop-active",
hoverClass: "drop-hover",
drop: function (event, ui) {
$(this).append(ui.draggable);
ui.draggable.css({ top: 0, left: 0 });
},
});标签页
基础标签页
标记模式是一个 <ul> 中的 <li><a href='#panel-id'> 链接与共享这些 id 的内容面板配对。tabs() 连接链接来显示/隐藏面板并添加 ARIA 角色以支持无障碍。点击标签页切换面板;活动标签页获得 ui-tabs-active 类。
<div id="box" class="ui-widget-content">
Resize me from the corner
</div>
<script>
$(function () {
$("#box").resizable();
});
</script>AJAX 标签页
当 <a href> 指向 URL(非 #id) 时,tabs 在首次激活时通过 AJAX 将该 URL 加载到面板中。beforeLoad 允许你拦截 jqXHR(用于错误处理或缓存)。默认每个标签页只加载一次并缓存;如需每次重新加载,在 beforeLoad 中中止并自行管理。
$("#box").resizable({
handles: "n, e, s, w, ne, se, sw, nw", // all eight handles
});
// Or specify handle elements
$("#box").resizable({
handles: {
n: ".n-handle",
se: ".se-handle",
},
});可折叠与活动控制
active 设置初始打开的标签页;collapsible:true 时点击活动标签页可折叠(所有面板关闭)。disabled 接受标签页索引数组。event 更改触发方式(如 mouseover),但 click 最具无障碍性。方法允许以编程方式切换、禁用或查询活动标签页。
$("#box").resizable({
alsoResize: "#other", // resize another element in sync
animate: true, // animate to final size
animateDuration: 200, // ms
aspectRatio: 16 / 9, // preserve width:height ratio
autoHide: true, // hide handles until hover
containment: "parent", // restrict resize within parent
grid: [10, 10], // snap to grid
maxHeight: 400,
maxWidth: 600,
minHeight: 100,
minWidth: 100,
ghost: true, // show a ghost outline while resizing
});可排序标签页
用 sortable({ axis: 'x' }) 包装标签页导航(.ui-tabs-nav),用户可以拖动标签页重新排序。排序结束后调用 tabs('refresh') 让组件重新读取新的标签页顺序。如需持久化顺序,可结合 cookies/localStorage。
$("#box").resizable({
start: function (event, ui) {
console.log("Resize start", ui.size, ui.position);
},
resize: function (event, ui) {
// Fires continuously during resize
ui.size.width; // new width
ui.size.height; // new height
ui.position.left; // new position (may change for n/w handles)
},
stop: function (event, ui) {
console.log("Final size:", ui.size);
},
});标签页事件
beforeActivate 在标签页切换前触发(返回 false 可阻止);activate 在切换后触发,提供 ui.newTab/newPanel 和 ui.oldTab/oldPanel。beforeLoad/load 包装远程标签页的 AJAX 生命周期。这些钩子用于验证、懒加载或面板过渡动画。
// Keep a 4:3 ratio
$("#photo").resizable({ aspectRatio: 4 / 3 });
// Keep ratio and stay within bounds
$("#photo").resizable({
aspectRatio: 4 / 3,
maxWidth: 800,
maxHeight: 600,
minWidth: 100,
minHeight: 75,
});
// Snap to a grid of 20px
$("#grid-box").resizable({ grid: [20, 20] });标签页方法与刷新
tabs('refresh') 重新扫描 DOM,可在运行时添加/删除标签页 —— 在更改标记后调用它。load(idx) 强制重新加载 AJAX 标签页。destroy 移除组件并恢复原始 HTML。关闭图标模式是经典的'可关闭标签页'示例。
// Animate to the final size after release
$("#box").resizable({
animate: true,
animateDuration: "slow", // or ms number
animateEasing: "swing",
});
// Show a ghost outline while dragging, apply on release
$("#box").resizable({
ghost: true,
helper: "ui-resizable-helper", // class for the ghost
});
// Combine both
$("#box").resizable({ ghost: true, animate: true });手风琴
基础手风琴
手风琴期望成对的标题 + 内容元素(默认:h3 标题,div 面板)。一次只有一个部分打开;打开一个会关闭其他。标题元素可通过 header 选项配置(如 'h2' 或类名)。
<ol id="selectable">
<li class="ui-widget-content">Item 1</li>
<li class="ui-widget-content">Item 2</li>
<li class="ui-widget-content">Item 3</li>
</ol>
<script>
$(function () {
$("#selectable").selectable();
});
</script>可折叠模式
默认点击打开的标题不做任何事 —— 它保持打开。collapsible:true 允许关闭它,使所有部分都折叠。jQuery UI 的手风琴严格只开一个;如需多开行为,可手动构建 slideToggle 模式或使用多个独立的手风琴实例。
$("#selectable").selectable({
filter: "li", // which children can be selected
tolerance: "touch", // "touch" or "fit" for lasso overlap
distance: 0, // px before lasso starts
delay: 0, // ms delay before lasso starts
autoRefresh: true, // recompute positions on each drag
disabled: false,
cancel: "a, .no-select", // elements that never start selection
});活动控制
active 设置初始打开的部分(索引,或与 collapsible 配合使用 false)。animate 控制滑动持续时间/缓动(false 禁用)。refresh 在运行时添加或删除部分后重新计算高度/标题 —— 对动态手风琴必不可少。
$("#selectable").selectable({
selecting: function (event, ui) {
// ui.selecting: element being lassoed
$(ui.selecting).addClass("highlight");
},
selected: function (event, ui) {
// ui.selected: element just confirmed selected
console.log("Selected:", $(ui.selected).text());
},
unselecting: function (event, ui) {
$(ui.unselecting).removeClass("highlight");
},
unselected: function (event, ui) {
console.log("Unselected:", $(ui.unselected).text());
},
start: function (event, ui) { /* lasso started */ },
stop: function (event, ui) { /* lasso released */ },
});高度样式
heightStyle:'auto' 将所有面板设为最高面板的高度(切换时跳动);'fill' 填充父容器并滚动溢出;'content' 让每个面板保持自然高度(过渡最平滑)。'fill' 要求手风琴有定义的高度。
<ul id="gallery">
<li class="selectable-item">Photo 1</li>
<li class="locked">Locked</li>
<li class="selectable-item">Photo 2</li>
</ul>
<script>
$("#gallery").selectable({
filter: ".selectable-item", // only these can be selected
cancel: ".locked", // locked items never select
});
</script>图标与标题
header 允许使用任何选择器(h2、类名等)替代 h3。icons 将关闭(header)和打开(activeHeader)状态映射到 jQuery UI 图标类。设置 icons:false 可取消箭头。图标类来自主题的图标精灵图。
/* CSS */
#selectable .ui-selecting {
background: #feca40; /* while dragging */
}
#selectable .ui-selected {
background: #f39814; /* confirmed selection */
color: white;
}
#selectable li {
margin: 3px; padding: 6px;
border: 1px solid #ccc;
}
/* selected count badge */
function updateCount() {
var n = $("#selectable .ui-selected").length;
$("#count").text(n + " selected");
}
$("#selectable").on("selectablestop", updateCount);手风琴事件
beforeActivate 在面板打开/关闭前触发(返回 false 可阻止);activate 在之后触发,提供 ui.newHeader/newPanel 和 ui.oldHeader/oldPanel。用于懒加载内容到刚打开的面板、验证或触发布局重新计算。
// Refresh positions after DOM changes
$("#selectable").selectable("refresh");
// Disable / enable
$("#selectable").selectable("disable");
$("#selectable").selectable("enable");
// Remove the widget
$("#selectable").selectable("destroy");
// Manually select an item (set the class)
$("#selectable li").eq(2).addClass("ui-selected");
// Clear all selections
$("#selectable .ui-selected").removeClass("ui-selected");对话框
基础对话框
Dialog 将 div 转换为浮动窗口,带有标题栏(来自 title 属性)、关闭按钮和可配置按钮。autoOpen:true 立即打开;设为 false 则稍后调用 dialog('open')。buttons 数组是现代形式(包含 text 和 click 的对象)—— 优于旧版键值映射。
<ul id="sortable">
<li class="ui-widget-content">Item 1</li>
<li class="ui-widget-content">Item 2</li>
<li class="ui-widget-content">Item 3</li>
</ul>
<script>
$(function () {
$("#sortable").sortable();
});
</script>模态对话框
modal:true 使页面变暗并阻止与对话框后面元素的交互 —— 对确认和表单至关重要。draggable/resizable 默认开启。show/hide 接受效果对象用于打开/关闭动画。closeOnEscape 允许 Esc 键关闭对话框。
$("#sortable").sortable({
axis: "y", // constrain to vertical
cursor: "move",
handle: ".handle", // drag from this element only
placeholder: "sortable-placeholder", // class for the drop preview
forcePlaceholderSize: true, // match placeholder to item size
helper: "clone", // "original" or "clone"
opacity: 0.7,
revert: true, // animate item into place
tolerance: "pointer", // "intersect" or "pointer"
scroll: true, // auto-scroll the page
containment: "parent", // restrict within parent
});对话框按钮
buttons 数组形式支持每按钮图标,并允许轻松重排/重命名。在 click 处理函数内,'this' 是对话框元素,所以 $(this).dialog('close') 可关闭它。通过 dialog('option', 'buttons', [...]) 在运行时更改按钮。框架自动添加正确的 ARIA 角色以支持无障碍。
$("#sortable").sortable({
start: function (event, ui) {
ui.item; // the dragged element
ui.placeholder; // the placeholder element
ui.helper; // the helper being dragged
},
change: function (event, ui) {
// Position in list changed during drag
},
sort: function (event, ui) {
// Fires continuously while sorting
},
beforeStop: function (event, ui) {
// Just before the item is placed
},
stop: function (event, ui) {
console.log("Sort ended");
},
update: function (event, ui) {
// Order actually changed — persist it here
var order = $(this).sortable("toArray");
saveOrder(order);
},
});对话框中的表单
常见模式:在模态对话框中放置表单,在主按钮上验证,通过 AJAX 提交,并在 close 处理函数中重置表单,使重新打开时显示干净状态。用 dialog('open') 打开;通过按钮或 Esc 关闭。
<ul id="list-a" class="connected">
<li>Task A1</li><li>Task A2</li>
</ul>
<ul id="list-b" class="connected">
<li>Task B1</li>
</ul>
<script>
$(".connected").sortable({
connectWith: ".connected", // allow moving between lists
placeholder: "ui-state-highlight",
}).disableSelection();
</script>定位与动画
position 使用与 Position 工具相同的语法:my(对话框的哪条边)对齐到 at(目标 'of' 元素的哪条边)。默认在窗口中居中。show/hide 接受任何 jQuery UI 效果(blind、explode、fade、slide、drop、puff、scale...)。动态内容后重新设置 position 以保持居中。
$("#sortable").sortable({
placeholder: "ui-state-highlight", // class for the gap
forcePlaceholderSize: true,
helper: function (event, el) {
// Return a custom helper element
return $("<div class='custom-helper'>Moving...</div>");
},
cursorAt: { top: 10, left: 10 },
});
// Use a clone as the helper instead of moving the original
$("#sortable").sortable({ helper: "clone" });对话框方法与事件
open/close 切换可见性;moveToTop 将对话框提升到同栈的其他对话框之上;isOpen 查询状态。beforeClose 返回 false 可阻止关闭(适合'未保存更改'保护)。dragStop/resizeStop 在用户交互完成后触发。
// Get current order as an array of IDs
var order = $("#sortable").sortable("toArray");
// ["item-1", "item-3", "item-2"]
// Get option values
var placeholder = $("#sortable").sortable("option", "placeholder");
// Serialize items as a query string (uses id="name_number")
var data = $("#sortable").sortable("serialize");
// "item[]=1&item[]=2&item[]=3"
// Cancel the current sort (revert)
$("#sortable").sortable("cancel");
// Refresh positions after DOM changes
$("#sortable").sortable("refresh");
// Disable / enable / destroy
$("#sortable").sortable("disable");
$("#sortable").sortable("enable");
$("#sortable").sortable("destroy");按钮与按钮组
基础按钮
button() 为 <button>、<a> 和 <input type=submit/button/reset> 增添主题外观和悬停/激活状态。<a> 按钮适用于非表单操作。button() 用于单个元素;buttonset() 用于分组单选/复选框。
<div id="accordion">
<h3>Section 1</h3>
<div>Content for section 1</div>
<h3>Section 2</h3>
<div>Content for section 2</div>
<h3>Section 3</h3>
<div>Content for section 3</div>
</div>
<script>
$(function () {
$("#accordion").accordion();
});
</script>带图标的按钮
icon 添加主题图标(1.12+ 默认在左侧;使用 iconPosition 定位)。showLabel:false 创建纯图标按钮 —— 务必设置 label 以支持无障碍(屏幕阅读器 + title)。图标来自主题精灵图(ui-icon-<名称>)。
$("#accordion").accordion({
active: 0, // index of open panel (false = all closed)
collapsible: true, // allow closing all panels
disabled: false,
animate: 200, // ms or "ease name" or false
heightStyle: "content", // "auto", "fill", or "content"
header: "h3", // header selector
icons: {
header: "ui-icon-triangle-1-e",
activeHeader: "ui-icon-triangle-1-s",
},
event: "click", // event that toggles panels
});按钮组 (单选组)
buttonset() 将共享 name 的一组单选框(或复选框)样式化为连接的分段控件。底层 input 仍持有值,所以用 .prop('checked') 读写,并在更改的 input 上调用 button('refresh') 更新其视觉状态。
$("#accordion").accordion({
beforeActivate: function (event, ui) {
// ui.oldHeader, ui.oldPanel (closing)
// ui.newHeader, ui.newPanel (opening)
// Return false to cancel
if ($(ui.newHeader).data("locked")) return false;
},
activate: function (event, ui) {
// Fires after a panel finishes opening
console.log("Opened:", ui.newHeader.text());
},
create: function (event, ui) {
// Fires on initialization
console.log("Accordion created, open:", ui.header.text());
},
});复选框按钮
buttonset() 也适用于复选框,用于多切换工具栏。用 .prop('checked') 跟踪状态。以编程方式切换后,调用 button('refresh')(或刷新整个组)以同步按下外观。
$("#accordion").accordion({
icons: {
header: "ui-icon-circle-arrow-e",
activeHeader: "ui-icon-circle-arrow-s",
},
});
// Disable icons entirely
$("#accordion").accordion({ icons: false });
// Use your own icon classes (e.g. with FontAwesome)
$("#accordion").accordion({
icons: {
header: "fa fa-plus",
activeHeader: "fa fa-minus",
},
});分裂按钮
jQuery UI 没有内置分裂按钮 —— 常见配方是组合两个按钮(主按钮 + 箭头)和 menu 组件。点击箭头在其下方打开菜单;选择一项执行替代操作。使用 menu 组件作为下拉项。
// Allow all panels to be closed
$("#accordion").accordion({
collapsible: true,
active: false, // start with all closed
});
// Make every section independently toggleable
// (a true multi-open accordion = separate collapsibles)
$(".section").each(function () {
$(this).accordion({
collapsible: true,
active: false,
header: ".section-header",
});
});按钮方法与事件
disable/enable 切换禁用状态并添加正确的 ARIA。refresh 在通过 jQuery 更改元素状态(选中/禁用/标签)后重新读取 —— 每当修改源 input 时都要调用。Button 本身不发自定义事件;在底层元素上绑定 click/change。
// Refresh after adding content
$("#accordion").append("<h3>New</h3><div>Content</div>");
$("#accordion").accordion("refresh");
// Switch the open panel
$("#accordion").accordion("option", "active", 2);
// Disable / enable
$("#accordion").accordion("disable");
$("#accordion").accordion("enable");
// Destroy
$("#accordion").accordion("destroy");
// Load content on demand (AJAX-style)
$("#accordion").accordion({
beforeActivate: function (event, ui) {
var panel = ui.newPanel;
if (panel.is(":empty")) {
panel.load("/api/section/" + ui.newHeader.data("id"));
}
},
});菜单
基础菜单
Menu 将嵌套 <ul> 转换为可键盘导航的菜单,支持子菜单。每个项是包含 <div>(或 <a>)标签的 <li>;嵌套 <ul> 成为在悬停/箭头时打开的子菜单。组件处理箭头键导航、ARIA 角色和自动聚焦。
<label for="city">City:</label>
<input id="city" type="text">
<script>
$(function () {
var cities = ["London", "Paris", "Berlin", "Madrid", "Rome"];
$("#city").autocomplete({ source: cities });
});
</script>带图标与禁用的菜单
在项的 div 内放置带主题的 span.ui-icon 可添加图标。添加 ui-state-disabled 类可禁用项(键盘/鼠标会忽略)。仅包含短横线 '-' 的 <li> 渲染为分隔符。这些是组件自动识别的标记约定。
$("#city").autocomplete({
source: "/api/cities", // server endpoint
minLength: 2, // start suggesting after 2 chars
delay: 300, // ms between keystroke and request
});
// The server should return JSON like:
// ["London", "Paris", "Berlin"]
// or [{ "label": "London, UK", "value": "London" }]子菜单与定位
position 控制每个子菜单相对于其父项出现的位置,使用 Position 工具语法。默认向右打开;'collision: flip' 在空间不足时镜像翻转 —— 对靠近视口右边缘的菜单必不可少。delay 避免鼠标经过时意外打开子菜单。
$("#city").autocomplete({
source: cities, // array, URL, or function
minLength: 1, // chars before suggestions appear
delay: 300, // ms between keystroke and request
autoFocus: true, // focus first item automatically
appendTo: "#container", // where to render the menu
position: { my: "left top", at: "left bottom" },
disabled: false,
});菜单方法
编程导 航方法(next/previous/first/last/expand/collapse)镜像键盘行为,适用于测试或自定义键盘处理。focus(null, item) 设置活动项;refresh 在动态添加/删除项后重建。
$("#city").autocomplete({
source: function (request, response) {
// request.term is the typed text
// response() must be called with the results array
$.getJSON("/api/cities", { q: request.term })
.done(function (data) {
response(data);
})
.fail(function () {
response([]); // always call response, even on error
});
},
select: function (event, ui) {
// ui.item.label, ui.item.value
$("#city-id").val(ui.item.id);
},
});菜单事件
select 在用户选择项时触发(点击或 Enter);ui.item 是选中的 <li>。focus/blur 跟踪哪个项被高亮(鼠标悬停或键盘)。在 select 中编写业务逻辑 —— 它相当于菜单项的点击处理函数。
$("#city").autocomplete({
source: cities,
focus: function (event, ui) {
// Fires when an item is highlighted (not selected)
$("#preview").text(ui.item.label);
return false; // prevent setting the input value on focus
},
select: function (event, ui) {
// Fires when an item is chosen
$("#city").val(ui.item.label);
$("#city-id").val(ui.item.value);
return false; // prevent default behavior
},
change: function (event, ui) {
// Fires when input loses focus
if (!ui.item) {
// User typed something not in the list
console.log("No match:", this.value);
}
},
});Categories & Custom Rendering
Override _renderMenu or _renderItem to customize the dropdown layout. This example groups suggestions by category with header rows. The $.widget pattern extends the base autocomplete, so all original options and events still work. Common for search interfaces.
$.widget("custom.catcomplete", $.ui.autocomplete, {
_renderMenu: function (ul, items) {
var that = this, currentCategory = "";
$.each(items, function (index, item) {
if (item.category !== currentCategory) {
ul.append("<li class='ui-autocomplete-category'>"
+ item.category + "</li>");
currentCategory = item.category;
}
that._renderItemData(ul, item);
});
},
});
// Use the new widget
$("#search").catcomplete({
source: [
{ label: "Java", category: "Languages" },
{ label: "JavaScript", category: "Languages" },
{ label: "React", category: "Frameworks" },
],
});选择菜单
基础选择菜单
selectmenu() 用带主题、支持无障碍的下拉框替换原生 <select>,同时保持底层 <select> 同步(表单仍可正确提交)。width 通常需要显式设置,因为样式化组件不像原生控件那样自动调整大小。
<label for="date">Pick a date:</label>
<input type="text" id="date">
<script>
$(function () {
$("#date").datepicker();
});
</script>自定义渲染
覆盖菜单的 _renderItem(通过 selectmenu('menuWidget').menu('instance') 访问)可为每个选项添加图标、描述或样式化徽章。item.element 是原始 <option>,所以 .data() 可附加每选项元数据。底层值仍正常提交。
$("#date").datepicker({
dateFormat: "yy-mm-dd", // ISO format
defaultDate: "+1", // tomorrow when calendar opens
minDate: 0, // no past dates (today+)
maxDate: "+1Y", // up to one year ahead
numberOfMonths: 2, // show 2 months side by side
showButtonPanel: true, // Today/Done buttons
changeMonth: true, // dropdown for month
changeYear: true, // dropdown for year
showAnim: "fadeIn", // open animation
duration: "fast",
firstDay: 1, // start week on Monday
showWeek: true, // show week numbers
});禁用选项与选项组
selectmenu 尊重 <optgroup>(渲染为不可选的组标题)和 disabled <option>(置灰、不可点击)。用 disable/enable 禁用整个组件。组件镜像原生语义,可作为 <select> 的直接替换。
$("#date").datepicker({
dateFormat: "yy-mm-dd", // 2026-07-04
});
// Format tokens:
// d - day of month, no leading zero (1)
// dd - day, two digits (01)
// D - short day name (Mon)
// DD - full day name (Monday)
// m - month, no leading zero (1)
// mm - month, two digits (01)
// M - short month name (Jan)
// MM - full month name (January)
// y - two-digit year (26)
// yy - four-digit year (2026)
// @ - Unix timestamp
// ! - Windows ticks
// Common formats:
// "mm/dd/yy" -> 07/04/2026
// "yy-mm-dd" -> 2026-07-04
// "DD, MM d, yy" -> Friday, July 4, 2026选择菜单方法
open/close 以编程方式切换下拉框。value('Fast') 选择值为 'Fast' 的选项;不传参数读取。添加/删除/修改 <option> 元素后调用 refresh 使样式化菜单反映更改。destroy 恢复原生 <select>。
// Restrict to a date range
$("#start").datepicker({
minDate: 0,
maxDate: "+6M",
onSelect: function (dateText) {
// Set the end date's minimum to the start date
$("#end").datepicker("option", "minDate", dateText);
},
});
$("#end").datepicker({
minDate: 0,
maxDate: "+6M",
onSelect: function (dateText) {
$("#start").datepicker("option", "maxDate", dateText);
},
});
// Disable weekends
$("#date").datepicker({
beforeShowDay: $.datepicker.noWeekends,
});选择菜单事件
change 是主要事件 —— 在用户选择不同选项时触发,ui.item 持有选中的 {value, label, element}。select 在每次选择时触发(即使未更改)。open/close/focus 支持 UI 反馈(如懒加载选项列表)。
// Set the regionalization
$("#date").datepicker($.datepicker.regional["fr"]);
// Override specific strings
$("#date").datepicker({
monthNames: ["janvier","février","mars","avril","mai","juin",
"juillet","août","septembre","octobre","novembre","décembre"],
dayNamesMin: ["Di","Lu","Ma","Me","Je","Ve","Sa"],
firstDay: 1,
dateFormat: "dd/mm/yy",
prevText: "Précédent",
nextText: "Suivant",
closeText: "Fermer",
currentText: "Aujourd'hui",
});
// Include the regional file for built-in locales:
// <script src="jquery-ui/i18n/datepicker-fr.js"></script>Inline Datepicker & Events
Apply datepicker to a div instead of an input for an always-visible inline calendar — great for booking interfaces. onSelect fires when a date is picked, onChangeMonthYear when navigating months. getDate/setDate work with Date objects for programmatic control.
<!-- Inline (always visible) calendar -->
<div id="inline-calendar"></div>
<script>
$("#inline-calendar").datepicker({
onSelect: function (dateText, inst) {
console.log("Selected:", dateText);
},
onChangeMonthYear: function (year, month, inst) {
console.log("Viewing:", month + "/" + year);
},
beforeShow: function (input, inst) {
// Fires before the popup opens
return { /* override options */ };
},
onClose: function (dateText, inst) {
// Fires when the popup closes
},
});
// Methods
$("#date").datepicker("setDate", "+7"); // set to a week from today
$("#date").datepicker("getDate"); // returns a Date object
$("#date").datepicker("option", "minDate", new Date(2026, 0, 1));
</script>滑块
基础滑块
Slider 在轨道上创建可拖动的手柄。min/max 定义范围,value 初始位置,step 步长。slide 回调在用户拖动时持续触发 —— 用它更新实时标签。手柄的值在 ui.value 中。
<div id="dialog" title="Basic dialog">
<p>This is a simple dialog window.</p>
</div>
<script>
$(function () {
$("#dialog").dialog();
});
</script>范围滑块
range:true 配合 values:[a,b] 创建双柄滑块,两柄之间有填充段 —— 非常适合价格/年龄范围筛选。从 ui.values(数组)读取两个值。range:'min' 或 'max' 则从单柄向端点着色。