首页 / 资讯中心 / 文章详情

htmx JavaScript API 完全指南:编程式 AJAX、运行时配置与扩展开发实战

htmx JavaScript API 完全指南:编程式 AJAX、运行时配置与扩展开发实战 ★ FEATURED ARTICLE
前端【免费下载链接】htmxhtmx - high power tools for HTML项目地址https://gitcode.com/GitHub_Trending/ht/htmx点击查看免费下载htmx 以声明式 HTML 属性hx-*闻名但它同时提供了一套小而精的 JavaScript API用于在需要编程控制的场景中发起 AJAX 请求、操作 DOM、管理事件与扩展。本指南以官方 API 文档 为主体结合仓库源码 src/htmx.js 中的真实实现与 test/core/api.js 测试用例完整讲解每个方法、属性的签名、参数、默认值与底层原理。读完本文你将能够脱离属性声明用纯 JavaScript 完成请求触发、内容交换、事件监听、值解析、类名控制与扩展注册并理解htmx.config中每一项配置对运行时行为的实际影响。API 的定位与适用场景htmx 官方文档明确说明虽然编程式调用并非库的专注点htmx 仍然提供了一小组辅助方法主要面向扩展开发extension development与事件管理event management。需要更完整脚本化支持的应用可以配合 hyperscript 项目使用。整个 API 定义在仓库的 src/htmx.js 中一个htmx对象先以空引用声明全部入口onLoad、process、on、off、trigger、ajax、find、findAll、closest、values、remove、addClass、removeClass、toggleClass、takeClass、swap、defineExtension、removeExtension、logAll、logNone、parseInterval等随后在 L302-L322 将这些引用逐一绑定到内部实现函数。与此同时htmx还暴露了两个内部性质的口子htmx._internalEval见 src/htmx.js#L863-L867与htmx.location以及只读的htmx.version当前仓库版本为2.0.11见 src/htmx.js#L299。这些 API 的完整 TypeScript 类型声明可在 src/htmx.esm.d.ts 中查阅包含HtmxAjaxHelperContext、HtmxSwapSpecification、HtmxExtension等辅助类型是扩展开发者最可靠的签名参考。运行时配置htmx.confightmx.config是一个保存 htmx 运行时全部配置的属性。官方文档特别指出使用meta标签是设置这些属性的首选机制见 docs.md 的配置章节因为它可以避免脚本执行时序问题meta namehtmx-config content{defaultSwapStyle:outerHTML} /等效的编程式写法// 将历史缓存大小更新为 30 htmx.config.historyCacheSize 30;从源码看所有配置项的默认值集中定义在 src/htmx.js#L77-L289官方文档与源码逐项对应完整清单如下配置属性默认值说明attributesToSettle[class, style, width, height]在 settling沉降阶段需要合并的属性列表refreshOnHistoryMissfalse为true时历史记录 miss 将触发整页刷新而非 AJAX 请求defaultSettleDelay20内容交换完成后到属性沉降之间的默认延迟毫秒defaultSwapDelay0收到服务器响应后到执行交换之间的默认延迟毫秒defaultSwapStyleinnerHTML未写hx-swap时的默认交换方式historyCacheSize10历史支持在sessionStorage中保留的页面数historyEnabledtrue是否启用历史功能includeIndicatorStylestrue为true时注入少量 CSS使指示器在缺少htmx-indicator类时不可见indicatorClasshtmx-indicator请求进行中放置到指示器上的类requestClasshtmx-request请求进行中放置到触发元素上的类addedClasshtmx-added临时放置到 htmx 新增 DOM 元素上的类settlingClasshtmx-settlingsettling 阶段放置到目标元素上的类swappingClasshtmx-swappingswapping 阶段放置到目标元素上的类allowEvaltrue是否允许 htmx 使用类 eval 功能启用hx-vars、触发条件与 script 标签求值可设为false以兼容 CSPallowScriptTagstrue是否允许新内容中的 script 标签被求值inlineScriptNonce添加到内联脚本上的 nonce 值inlineStyleNonce添加到内联样式上的 nonce 值withCredentialsfalse是否允许携带凭证cookie、授权头、TLS 客户端证书的跨站 Access-Control 请求timeout0请求超时毫秒数超过后自动终止wsReconnectDelayfull-jittergetWebSocketReconnectDelay的默认实现用于Abnormal Closure、Service Restart、Try Again Later等异常断开后的重连wsBinaryTypeblobWebSocket 连接接收的二进制数据类型disableSelector[hx-disable], [data-hx-disable]带有该属性或其父级带有的元素不会被 htmx 处理disableInheritancefalse为true时完全禁用属性继承可配合hx-inherit显式指定继承scrollBehaviorinstanthx-swap的show修饰符使用的滚动行为取值instant/smooth/autodefaultFocusScrollfalse是否将聚焦元素滚动到视口内可用focus-scroll交换修饰符覆盖getCacheBusterParamfalse为true时在GET请求上追加org.htmx.cache-bustertargetElementId参数globalViewTransitionsfalse为true时交换新内容使用 View Transition APImethodsThatUseUrlParams[get, delete]这些方法将参数编码进 URL 而非请求体selfRequestsOnlytrue是否只允许向当前文档同域发起 AJAX 请求ignoreTitlefalse为true时新内容中的title标签不再更新文档标题scrollIntoViewOnBoosttrueboosted 元素的目标是否滚动进视口未写hx-target时目标默认为body会导致页面滚回顶部triggerSpecsCachenull存储已求值触发规格的缓存对象用内存换解析性能可传普通对象或基于 Proxy 的自定义实现responseHandling见下文响应状态码的默认处理方式交换或报错allowNestedOobSwapstrue是否处理嵌套在主响应元素内的 OOB 交换见hx-swap-oob的嵌套 OOBhistoryRestoreAsHxRequesttrue历史缓存 miss 的整页刷新请求是否作为HX-Request返回响应头若依赖HX-Request头选择性返回局部响应应始终禁用reportValidityOfFormsfalse是否向用户报告输入校验错误并将焦点移到第一个校验失败的表单控件与浏览器默认提交行为一致重点配置responseHandlingresponseHandling是 htmx 2.x 中控制“哪些响应码应该被交换、哪些应该视为错误”的核心配置。源码中的默认值src/htmx.js#L264-L268responseHandling: [ { code: 204, swap: false }, { code: [23].., swap: true }, { code: [45].., swap: false, error: true } ]htmx 收到响应后会按顺序遍历该数组把每一项的code当作正则表达式与当前响应码匹配命中即决定如何处理。可用字段包括code正则字符串、swap是否交换进 DOM、error是否视为错误、ignoreTitle、select、target与swapOverride。一个典型场景是后端框架在表单校验失败时返回422而默认规则[45]..会忽略它。通过 meta 配置即可让 422 被正常交换示例来自 docs.mdmeta namehtmx-config content{ responseHandling:[ {code:204, swap: false}, {code:[23].., swap: true}, {code:422, swap: true}, {code:[45].., swap: false, error:true}, {code:..., swap: true} ] } /如果希望无论响应码如何都交换内容可以简化为meta namehtmx-config content{responseHandling: [{code:.*, swap: true}]} /编程式发起请求htmx.ajax()htmx.ajax(verb, path, context)以 htmx 风格发起 AJAX 请求并返回一个 Promise可在内容插入 DOM 后执行回调。官方文档给出三种调用签名签名一目标元素// 向 /example 发起 GET将响应 HTML 放入 #myDiv htmx.ajax(GET, /example, #myDiv) // 内容插入 DOM 后执行位于 htmx:afterOnLoad 之后、htmx:xhr:loadend 之前 htmx.ajax(GET, /example, #myDiv).then(() { console.log(Content inserted successfully!); });签名二选择器字符串等价于签名一的简写最终被解析为元素签名三context 上下文对象可包含以下字段字段说明source请求的源元素影响请求的hx-*属性将相对该元素及其祖先解析event“触发”请求的事件handler处理响应 HTML 的回调target响应要交换进去的目标swap响应相对目标的交换方式values随请求提交的值headers随请求提交的请求头select从响应中选择要交换的内容selectOOB从响应中选择要做带外out-of-band交换的内容push为true或一个路径将 URL 推入浏览器历史replace为true或一个路径替换浏览器历史中的 URL// 向 /example 发起 GET用 outerHTML 方式把 #myDiv 替换为响应内容 htmx.ajax(GET, /example, {target:#myDiv, swap:outerHTML})源码视角请求是如何被发出的htmx.ajax绑定到ajaxHelpersrc/htmx.js#L4111-L4145。它做了几件关键的事将 verb 统一转为小写后委托给issueAjaxRequestsrc/htmx.js#L4319当context是元素或字符串时解析出targetOverride当目标是字符串但无法解析、或提供了source但目标和源都无法解析时会使用一个DUMMY_ELT源码中的虚拟output元素作为目标从而触发htmx:targetError错误事件避免请求意外替换掉整个 bodyissueAjaxRequest内部依次处理hx-confirm确认、hx-sync同步策略drop / abort 等、verifyPath同源校验src/htmx.js#L4166-L4177受htmx.config.selfRequestsOnly控制以及htmx:validateUrl事件当etc.returnPromise为真且环境支持 Promise 时构造并返回 Promise其 resolve 时机位于内容成功插入之后。测试套件 test/core/api.js 对这一行为有大量覆盖ajax api works、ajax api works by ID、ajax api does not fall back to body when target invalid、ajax api fails when target invalid、ajax returns a promise、ajax api can pass parameters、ajax api push Url should push an element into the cache when true/string等test/core/api.js#L215-L358。DOM 查询助手find/findAll/closest这三个方法提供与 jQuery 风格一致的 DOM 查询能力// 查找 id 为 my-div 的 div var div htmx.find(#my-div) // 在该 div 内查找 id 为 another-div 的元素不含根元素自身 var anotherDiv htmx.find(div, #another-div) // 查找所有 div var allDivs htmx.findAll(div) // 在 #my-div 内查找所有 p 元素 var allParagraphsInMyDiv htmx.findAll(htmx.find(#my-div), p) // 查找 #demo 最近的祖先 div包含自身 htmx.closest(htmx.find(#demo), div);参数规则find/findAll既可只传选择器相对整个文档也可传“根元素 选择器”closest(elt, selector)返回包含元素自身在内的最近匹配祖先。源码实现非常直接findsrc/htmx.js#L910-L916在根元素上调用querySelectorclosestsrc/htmx.js#L1086-L1092调用原生elt.closest(selector)且三者都经由resolveTargetsrc/htmx.js#L1256-L1262支持“元素或选择器字符串”的混合传参。对应测试见 test/core/api.js#L11-L38should find properly、should find all properly、should find closest element properly。CSS 类管理addClass/removeClass/toggleClass/takeClass// 为 #demo 添加 myClass htmx.addClass(htmx.find(#demo), myClass); // 1 秒后添加 htmx.addClass(htmx.find(#demo), myClass, 1000); // 移除 myClass6 秒后移除 htmx.removeClass(htmx.find(#my-div), myClass); htmx.removeClass(htmx.find(#my-div), myClass, 6000); // 切换 selected 类 htmx.toggleClass(htmx.find(#tab2), selected); // 把 selected 类从 tab2 的所有兄弟元素上拿走仅保留在 tab2 上 htmx.takeClass(htmx.find(#tab2), selected);源码实现细节值得注意addClassToElementsrc/htmx.js#L1003-L1016若传入延迟先setTimeout再递归调用若元素解析失败则静默返回elt asElement(resolveTarget(elt))后判空。removeClassFromElementsrc/htmx.js#L1027-L1046当元素最后一个类被移除、classList长度归零时会额外删除class属性本身保证 DOM 干净。takeClassForElementsrc/htmx.js#L1069-L1075遍历elt.parentElement.children逐一移除该类再给目标元素加上实现了典型的“tab 高亮互斥”效果。对应测试覆盖了带选择器传参、延迟添加/移除以及“对非法元素移除类不报错”等边界场景test/core/api.js#L69-L200。DOM 操作remove/swaphtmx.remove(elt[, delay])从 DOM 中移除元素支持元素或选择器字符串可选延迟毫秒数// 立即移除 htmx.remove(htmx.find(#my-div)); // 2 秒后移除 htmx.remove(htmx.find(#my-div), 2000);源码removeElementsrc/htmx.js#L950-L960先resolveTarget有延迟则setTimeout后递归否则直接parentElt(elt).removeChild(elt)。htmx.swap(target, content, swapSpec[, swapOptions])执行 HTML 内容的交换与沉降settling是hx-swap属性的编程式等价物。swapSpec对应hx-swap的参数集swapStyle必填——交换方式innerHTML、outerHTML、beforebegin、afterbegin、beforeend、afterend、delete、none等swapDelay/settleDelaynumber——交换与沉降前的延迟transitionbool——是否使用视图过渡ignoreTitlebool——禁用页面标题更新headstring——head标签处理策略merge或append留空则禁用 head 处理scroll/scrollTarget/show/showTarget/focusScroll——交换后的滚动处理。swapOptions是额外的可选参数select——要交换内容的选取器等价于hx-selectselectOOB——带外交换内容的选取器等价于hx-select-oobeventInfo——附加到htmx:afterSwap与htmx:afterSettle事件上的对象anchor——触发滚动的锚点元素沉降时滚动进视口contextElement——交换操作的上下文 DOM 元素用于查找该元素启用的扩展afterSwapCallback/afterSettleCallback——交换后、沉降后调用的回调无参数。// 将 #output 的 innerHTML 替换为包含 Swapped! 的 div htmx.swap(#output, divSwapped!/div, {swapStyle: innerHTML});源码swapsrc/htmx.js#L1924是一个完整的交换管线解析目标 → 处理 OOB 与selectOOB→ 处理hx-partial局部交换 → 主交换swapWithStyle→ 恢复焦点与选区 → 触发htmx:afterSwap→ 处理标题 → 执行沉降任务并触发htmx:afterSettle。它还特别支持textContent交换方式不做 HTML 解析直接插入文本。测试覆盖了基础交换、交换延迟、View Transition、select/selectOOB、outerHTML等场景test/core/api.js#L492-L565。事件处理on/off/trigger/onLoad添加与移除监听htmx.on()与htmx.off()都支持两种调用形态省略 target 时默认绑定到body或显式指定目标元素// 在 body 上监听 click var myEventListener htmx.on(click, function(evt){ console.log(evt); }); // 在 #my-div 上监听 click var myEventListener htmx.on(#my-div, click, function(evt){ console.log(evt); }); // 仅触发一次 var myEventListener htmx.on(#my-div, click, function(evt){ console.log(evt); }, { once: true }); // 移除监听 htmx.off(click, myEventListener); htmx.off(#my-div, click, myEventListener)on的第四个可选参数可以是 addEventListener 的 options 对象如{ once: true }、{ capture: true }或 useCapture 布尔值。源码addEventListenerImplsrc/htmx.js#L1312-L1319把注册推迟到 DOM ready 之后执行并返回 listener 本身方便后续off移除参数归一化由processEventArgssrc/htmx.js#L1283-L1299完成——当第二个参数是函数时自动把第一个参数当作事件名、目标缺省为document.body。触发事件// 在 #tab2 上触发 myEvent 事件携带 detail {answer:42} htmx.trigger(#tab2, myEvent, {answer:42});triggerEventsrc/htmx.js#L3156-L3180的行为比普通dispatchEvent更丰富detail 缺省时自动补{}并始终注入detail.elt被触发元素事件以bubbles: true, cancelable: true, composed: true构造可穿透 Shadow DOMcamelCase 事件名会自动以 kebab-case 再触发一次如myEvent同时派发my-event保证两种命名风格都能被监听若htmx.logger已设置触发前会调用 logger 记录最后会遍历元素上启用的扩展逐一调用其onEvent钩子。htmx.onLoad(callback)为htmx:load事件添加回调用于处理新加载的内容例如初始化第三方库htmx.onLoad(function(elt){ MyLibrary.init(elt); })源码onLoadHelpersrc/htmx.js#L877-L882本质上就是htmx.on(htmx:load, ...)的包装把事件 detail 中的elt传给回调。htmx 的全部事件清单可查阅 events.md含htmx:beforeRequest、htmx:afterRequest、htmx:beforeSwap、htmx:afterSwap、htmx:afterSettle、htmx:confirm等是编写事件驱动逻辑时的权威参考。内容处理htmx.process(elt)当内容由非 htmx 请求周期的途径加入 DOM例如手动设置innerHTML时htmx 属性不会自动生效此时需要显式调用process让 htmx 接管document.body.innerHTML div hx-get/exampleGet it!/div // 处理新加入的内容使 hx-get 生效 htmx.process(document.body);源码processNodesrc/htmx.js#L3056-L3079会先解析目标、检查disableSelector禁用状态然后收集需要初始化的元素含hx-on通配符元素逐一调用initNode完成监听器与行为的安装。值解析htmx.values(elt[, type])返回给定元素经 htmx 值解析机制得到的输入值对象。第二个参数是请求类型如get/post非 GET 请求会包含元素所在的外层表单默认为post// 获取该表单关联的值 var values htmx.values(htmx.find(#myForm));其底层是getInputValuessrc/htmx.js#L3656-L3707实现要点包括基于FormData收集非 GET 请求额外处理关联表单考虑lastButtonClicked被点击的提交按钮的 name/value纳入hx-include指定的元素及其内部输入表单值优先级高于普通值overrideFormData。测试中的values api returns formDataProxy with correct form data even if clicked button removedtest/core/api.js#L567验证了按钮被移除后值解析依然正确。调试工具logAll/logNone/loggerhtmx.logAll(); // 记录所有 htmx 事件便于调试 htmx.logNone(); // 关闭日志自定义日志记录器htmx.logger function(elt, event, data) { if(console) { console.log(INFO:, event, elt, data); } }源码中logAllsrc/htmx.js#L889-L895就是把htmx.logger设置为向 console 输出的默认函数logNonesrc/htmx.js#L897-L899将logger置为null。logger 的调用点在triggerEvent中src/htmx.js#L3163-L3165且htmx:afterProcessNode事件会被跳过以免日志刷屏ignoreEventForLogging。定时解析htmx.parseInterval(str)以 htmx 一致的方式解析时间间隔字符串对带定时属性的扩展插件非常有用// 返回 3000 var milliseconds htmx.parseInterval(3s); // 官方文档示例提示此处返回 3 —— 注意见下方源码行为说明 var milliseconds htmx.parseInterval(3m);官方文档给出的“Caution”是只接受s或ms后缀其余值走parseFloat。但查阅当前仓库源码 src/htmx.js#L373-L389 可以发现实际实现比文档描述更进一步ms后缀按毫秒解析、s后缀乘以 1000、m后缀乘以 60000即 3 分钟 180000 毫秒其余情况使用parseFloat无法解析时返回undefined而非 NaN。因此文档示例中的“3m返回 3”在当前版本源码中已不再成立应以源码行为为准——这也提醒扩展作者写计时属性时优先使用s/ms后缀。扩展开发defineExtension/removeExtension/createEventSource/createWebSocket注册与注销扩展// 定义一个傻乎乎的扩展记录所有触发的事件名 htmx.defineExtension(silly, { onEvent : function(name, evt) { console.log(Event name was triggered!) } }); // 移除扩展 htmx.removeExtension(my-extension);源码defineExtensionsrc/htmx.js#L5055-L5060在扩展定义含init时会以internalAPI内部辅助函数集合见 src/htmx.js#L324-L352调用它完成初始化然后把扩展与基类合并后登记到extensions注册表removeExtensionsrc/htmx.js#L5069-L5071则直接删除注册项。扩展如何被元素启用向上遍历hx-ext属性、支持ignore:前缀见getExtensionssrc/htmx.js#L5081-L5108。更系统的扩展编写指南可参考 extensions 文档 与 building.md。覆盖 SSE 与 WebSocket 工厂htmx.createEventSource与htmx.createWebSocket是两个可被覆盖的属性分别负责创建 Server-Sent Events 与 WebSocket 连接用于自定义建立方式// 覆盖 SSE 工厂不使用凭证 htmx.createEventSource function(url) { return new EventSource(url, {withCredentials:false}); }; // 覆盖 WebSocket 工厂使用指定协议 htmx.createWebSocket function(url) { return new WebSocket(url, [wss]); };createEventSource的签名是func(url)返回一个新的EventSourcecreateWebSocket的签名同为func(url)返回一个新的WebSocket。相关的重连与二进制类型行为则由前面提到的htmx.config.wsReconnectDelay与htmx.config.wsBinaryType控制。类型声明与测试给你的代码加上类型安全如果项目使用 TypeScript仓库提供的 src/htmx.esm.d.ts 完整声明了全部 API 的类型htmx命名空间下的每个方法签名L155-L219、HtmxSwapStyle、HtmxSwapSpecification、HtmxAjaxHelperContext、HtmxRequestConfig、HtmxResponseHandlingConfig、HtmxExtension等类型均可在其中找到是判断参数合法性、避免低级错误的第一手依据。与此同时仓库的浏览器测试套件 test/core/api.js 对上述 API 的行为做了系统性验证覆盖查询、类操作、AJAX 目标解析与 Promise、push/replace历史操作、swap各模式、onLoad、trigger、values、process、logAll/logNone等场景。阅读这些用例例如ajax api does not fall back to body when target invalid、swap outerHTML works when parent is removed能帮助你理解 API 的边界行为是编写可靠业务代码的最佳参考。小结htmx 的 JavaScript API 虽然精简却是连接声明式属性与命令式逻辑的桥梁htmx.config让你以编程或 meta 标签方式全局调优htmx.ajax与htmx.swap覆盖了请求与交换的完整生命周期on/off/trigger/onLoad提供与 htmx 事件体系一致的事件管理find/findAll/closest、类操作与values补齐了 DOM 操作和表单取值的日常需求而defineExtension等入口则支撑起整个扩展生态。掌握这套 API即可在保持 htmx 优雅声明式风格的同时获得与框架内部机制完全一致的编程控制能力。赞分享前端【免费下载链接】htmxhtmx - high power tools for HTML项目地址https://gitcode.com/GitHub_Trending/ht/htmx点击查看免费下载相关推荐LMCache Internal API Server 完全指南运行时管理接口的配置、路由发现与扩展LMCache Internal API Server 完全指南运行时管理接口的配置、路由发现与扩展 LMCache 的 Internal API Serve人工智能大模型缓存抽象模型推理服务Apache Druid JavaScript 扩展开发指南运行时动态扩展的七类能力与安全实践Apache Druid JavaScript 扩展开发指南运行时动态扩展的七类能力与安全实践 Apache Druid 允许通过 JavaScript 在运数据库OLAP大数据后端TVM Relay TensorRT 集成实战BYOC 编译、运行时配置与算子扩展指南TVM Relay TensorRT 集成实战BYOC 编译、运行时配置与算子扩展指南 本指南围绕 TVM 中 Relay 与 NVIDIA TensorRT编译器深度学习模型优化上一篇5分钟快速入门Nacos SpringSpring应用配置管理的终极解决方案下一篇Arduino CLI国际化支持多语言本地化实现详解创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?
咨询建站