Я использую JS API библиотеки HTMX для добавления содержимого. например:
htmx.ajax('GET', url, {
target: '#js-product-list',
swap: 'beforeend', // Adding new stuff to already existing content
})
.then(() => {
...
Теперь предположим, что я хотел бы также обновить компонент фильтра на странице. Возможно ли использовать JS API (без атрибутов hx-*)?
Я пытался
htmx.ajax('GET', url, {
target: '#js-product-list',
swap: 'beforeend',
swapOptions: {
swapOOB: '#js-filter-wrapper'
}
})
.then(() => {
...
Детали разметки:
htmx.ajax('GET', url, {
target: '#js-product-list',
swap: 'beforeend',
swapOptions: {
swapOOB: '#js-filter-wrapper'
}
})
<div class = "container position-relative" id = "js-main-content">
<header>
<div class = "d-flex justify-content-between mx-1 my-3" id = "js-filter-wrapper">
Filter content
</div>
<div class = "mt-3 ms-1" id = "js-main-title-wrapper">
<h1>Heading</h1>
</div>
</header>
<main class = "row" id = "js-product-list">
Product list content
</main>
</div>
Вот что будет возвращено в ответ:
<div id = "js-filter-wrapper" hx-swap-oob = "#js-filter-wrapper">
Updated filter that will replace current filter
</div>
<div>
New products that will be appended to current ones using beforeend selector
</div>
Я слышал, что это плохо для SEO из-за неизвестных атрибутов. Кроме того, мне обычно нужно запускать анимацию с использованием библиотеки gsap.com после запроса ajax, который, вероятно, будет работать с использованием событий htmx, но я считаю, что проще использовать JS API.
вы можете использовать функцию htmx.on для прослушивания события htmx:afterSwap, вызов htmx.ajax обновляет компонент #js-product-list, и после завершения обновления запускается событие htmx:afterSwap. или используйте внеполосные замены (OOB), которые сразу работают с несколькими обновлениями в одном запросе. затем используйте функцию, которая у вас есть
В свой HTML-код вы можете добавить этот фрагмент кода: <div id = "js-product-list"> <!-- Содержимое списка продуктов здесь --> </div> <hx-swap-oob target = "#js-filter -wrapper"> <!-- Фильтровать содержимое компонента здесь --> </hx-swap-oob>
Итак, вы предлагаете использовать атрибуты? Боюсь, это не пойдет на пользу SEO.
Пробовали ли вы использовать js для выполнения запроса ajax, а затем обновить обе части страницы, используя селекторы запросов
Не могли бы вы привести пример? Своп AFAIK не может иметь более одной цели.
Я обнаружил, что можно использовать selectOOB с использованием JS API htmx.org/api > - swapOptions - дополнительные необязательные параметры для подкачки > selectOOB - селектор содержимого для внеполосной замены (эквивалент hx- select-oob) Знаете ли вы, как и можно ли с его помощью поменять фильтр OOB способом?
возможно, но вы не предоставили дополнительную информацию о своем формате HTML, это усложняет задачу. но я приведу вам пример.
Я предоставил вам обновленную функцию на основе вашего HTML. проверь, поможет ли это
Вы можете отправлять отдельные запросы HTMX для обновления разных компонентов. Зачастую это самый простой подход, если компоненты, которые вы хотите обновить, различны и их обновления не зависят друг от друга.
htmx.ajax('GET', productUrl, {
target: '#js-product-list',
swap: 'beforeend'
})
.then(() => {
});
htmx.ajax('GET', filterUrl, {
target: '#js-filter-wrapper',
swap: 'innerHTML'
})
.then(() => {
});
В моем случае обновлять одно без обновления другого не имеет смысла. Кроме того, мне нужна одна и та же конечная точка на сервере как для ajax, так и для полностраничных запросов в целях SEO, а для этого потребуется ненужная конечная точка, которая не будет работать для полностраничных запросов.
Чтобы заменить фильтр внештатным способом, вам потребуется обновить нужные вам компоненты. Я привел пример.
<div id = "js-product-list">
<!-- Product list content here -->
</div>
<div id = "js-filter-wrapper" hx-swap-oob = "true">
<!-- Filter component content here -->
</div>
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<meta name = "viewport" content = "width=device-width, initial-scale=1.0">
<title>HTMX Example</title>
<script src = "https://unpkg.com/[email protected]"></script>
</head>
<body>
<div class = "container position-relative" id = "js-main-content">
<header>
<div id = "js-filter-wrapper">
<!-- Initial filter component content -->
</div>
<div class = "mt-3 ms-1" id = "js-main-title-wrapper">
<h1>Heading</h1>
</div>
</header>
<main class = "row" id = "js-product-list">
<!-- Initial product list content -->
</main>
</div>
<script>
function updateComponents(url) {
htmx.ajax('GET', url, {target: '#js-product-list', swap: 'beforeend'})
.then((response) => {
const parser = new DOMParser();
const doc = parser.parseFromString(response, 'text/html');
// Extract and update the filter component
const newFilter = doc.querySelector('#js-filter-wrapper');
if (newFilter) {
document.querySelector('#js-filter-wrapper').innerHTML = newFilter.innerHTML;
}
})
.catch((error) => {
console.error('Error updating components:', error);
});
}
// Example usage
updateComponents('/your-endpoint');
</script>
</body>
</html>
К сожалению, это не помогло. Содержимое фильтра добавляется к существующему (под фильтром, а не заменяет его), следует добавлять только новое содержимое списка продуктов. Я обновил вопрос, добавив детали разметки и некоторые дополнительные пояснения.
hx-swap-oob работает, но было бы идеально не использовать теги hx из-за SEO.
Я только что понял, что могу добавить атрибут hx-swap-oob на серверную часть только в том случае, если это запрос AJAX и поэтому он не будет виден роботам. Это решает мои опасения по поводу SEO. Спасибо за ваши усилия.
@Аскалот, да, пожалуйста. всегда рад помочь.
почему вы не хотите использовать (без атрибутов hx-*)?