第三方 JavaScript

Htmx 与第三方库的集成度相当高。如果库在 DOM 上触发事件,你可以使用这些事件来触发来自 htmx 的请求。

SortableJS 演示就是一个很好的例子:

<form class="sortable" hx-post="/items" hx-trigger="end">
    <div class="htmx-indicator">Updating...</div>
    <div><input type='hidden' name='item' value='1'/>Item 1</div>
    <div><input type='hidden' name='item' value='2'/>Item 2</div>
    <div><input type='hidden' name='item' value='2'/>Item 3</div>
</form>

与大多数 javascript 库一样,使用 Sortable 时你需要在某个时候初始化内容。

在 jquery 中你可以这样做:

$(document).ready(function() {
    var sortables = document.body.querySelectorAll(".sortable");
    for (var i = 0; i < sortables.length; i++) {
        var sortable = sortables[i];
        new Sortable(sortable, {
            animation: 150,
            ghostClass: 'blue-background-class'
        });
    }
});

在 htmx 中,你可以改用该 htmx.onLoad 函数,并且只从新加载的内容中进行选择,而不是整个文档:

htmx.onLoad(function(content) {
    var sortables = content.querySelectorAll(".sortable");
    for (var i = 0; i < sortables.length; i++) {
        var sortable = sortables[i];
        new Sortable(sortable, {
            animation: 150,
            ghostClass: 'blue-background-class'
        });
    }
})

这将确保当 htmx 将新内容添加到 DOM 时,可排序元素得到正确初始化。

如果 javascript 向具有 htmx 属性的 DOM 中添加内容,则需要确保使用该 htmx.process() 函数初始化该内容。

例如,如果你要使用 fetchAPI 获取一些数据并将其放入 div 中,并且该 HTML 具有 htmx 属性,则需要添加 htmx.process() 如下调用:

let myDiv = document.getElementById('my-div')
fetch('http://example.com/movies.json')
    .then(response => response.text())
    .then(data => { myDiv.innerHTML = data; htmx.process(myDiv); } );

一些第三方库从 HTML 模板元素创建内容。例如,Alpine JS 使用模板上的属性有条件地添加内容。此类模板最初不是 DOM 的一部分,如果它们包含 htmx 属性,则在加载后x-if 需要调用。以下示例使用 Alpine 的函数来查找将触发条件内容的值的变化:htmx.process() $watch

<div x-data="{show_new: false}"
    x-init="$watch('show_new', value => {
        if (show_new) {
            htmx.process(document.querySelector('#new_content'))
        }
    })">
    <button @click = "show_new = !show_new">Toggle New Content</button>
    <template x-if="show_new">
        <div id="new_content">
            <a hx-get="/server/newstuff" href="#">New Clickable</a>
        </div>
    </template>
</div>