NOTE: Apart from
(and even then it's questionable, I'm Scottish). These are machine translated in languages I don't read. If they're terrible please contact me.
You can see how this translation was done in this article.
Sunday, 15 September 2024
//Less than a minute
На цьому сайті я використовую HTMX Широко, це дуже простий спосіб змусити ваш сайт почуватися більш чуйним і плавнішим, без необхідності писати багато JavaScript.
ЗАУВАЖЕННЯ: я ще не зовсім задоволений цим, у HTMX є деякі елементи, які роблять цю роботу заплутаною
Використання HTMX з ядром ASP.NET є трохи мрією, я написав про це раніше в цей допис. Це дуже легко для Вашого сайту, і це чудовий спосіб, щоб Ваш сайт почувався більш реагуючим.
Як частина моєї останньої поїздки, використовуючи HTMX, я вирішив зробити якомога більше посилань на цьому сайті, використовуючи HTMX якомога більше. Наприклад, якщо ви натиснете кнопку " Домівка," розташовану над нею, тепер використовуєте HTMX для завантаження вмісту сторінки.
Я досягну цього, просто додавши деякі властивості до теґу посилання, ось так:
<a asp-action="IndexPartial" asp-controller="Home" hx-swap="show:window:top" hx-target="#contentcontainer" hx-boost="true" class="mr-auto sm:mr-6">
<div class="svg-container">
<img src="/img/logo.svg" asp-append-version="true" width="180px" height="30px" alt="logo" :class="{ 'img-filter-dark': isDarkMode }"/>
</div>
</a>
Тут ви бачите, що я додаю hx-swap
attribute, за допомогою цього параметра можна наказати HTMX поміняти вміст елемента призначення на вміст, повернений з сервера.
ЗАУВАЖЕННЯ: НЕ використовуйте hx- pushurl, оскільки це змусить навігатора двічі перезавантажити сторінку на задній кнопці.
The hx-target
attribute повідомляє HTMX, куди пересунути вміст повернений з сервера. В цьому випадку це #contentcontainer
element (де завантажено весь вміст сторінки).
Я також додаю hx-swap="show:window:top
За допомогою цього пункту можна перегорнути вікно на вершину сторінки, якщо вміст буде змінено.
Частина C# є досить простою, вона просто дублює мій звичайний метод індексування, але натомість завантажує частковий перегляд. Нижче показано код. Знову це використовується HTMX. NET для виявлення hx-request
заголовок і повернути частковий перегляд. Є також скорочення, щоб повернути звичайний вигляд, якщо запит не є запитом на HTMX.
[Route("/IndexPartial")]
[OutputCache(Duration = 3600, VaryByHeaderNames = new[] { "hx-request" })]
[ResponseCache(Duration = 300, VaryByHeader = "hx-request",
Location = ResponseCacheLocation.Any)]
[HttpGet]
public async Task<IActionResult> IndexPartial()
{
ViewBag.Title = "mostlylucid";
if(!Request.IsHtmx()) return RedirectToAction("Index");
var authenticateResult = await GetUserInfo();
var posts = await BlogService.GetPagedPosts(1, 5);
posts.LinkUrl = Url.Action("Index", "Home");
var indexPageViewModel = new IndexPageViewModel
{
Posts = posts, Authenticated = authenticateResult.LoggedIn, Name = authenticateResult.Name,
AvatarUrl = authenticateResult.AvatarUrl
};
return PartialView("_HomePartial", indexPageViewModel);
}
Результатом цього є те, що це посилання (та інші використовують ту саму методику) навантаження на запити " AJAX " і вміст змінено без перезавантаження сторінки на повну. Це уникає набридливого спалаху світла, який ви отримаєте, коли сторінка перезавантажується через те, як працює зміна теми.
Таким чином, метод, поданий нижче, може бути приведений до роботи, але це дуже складно і трохи незграбно.
HTMX дуже любить працювати за допомогою методу, заснованого на атрибутах. Користування htmx.ajax
є свого роду "якщо все інше зазнає невдачі" метод і означає, що вам потрібно переплутати історію Борсера.
На жаль, журнал переглядача використовує pushState
replaceState
і popstate
це дійсно трохи біль в шиї (але може бути дуже потужним для випадків ребра).
Замість цього, я просто додаю hx-boost
до мітки, що містить вміст блогу.
<div class="prose prose max-w-none border-b py-2 text-black dark:prose-dark sm:py-2" hx-boost="true" hx-target="#contentcontainer">
@Html.Raw(Model.HtmlContent)
</div>
Це, здається, добре працює і hx-boost
можна використовувати батьківські методи і застосовувати до всіх зв'язків між дітьми. Це також більш стандартний HTMX, не втручаючись в історію і т.д.
У рідкісних випадках, коли ви НЕ хочете використовувати HTMX для окремих посилань, ви можете просто додати hx-boost="false"
з посиланням.
Але проблема з цим підходом була в тому, що мій блог посилається на такі посилання: HTMX для SPA-подібного досвіду які не є " нормальними " посиланнями. Ці посилання створюються інструментом обробки markdown. Під час написання додатка MarkDig для додавання атрибутів HTMX до посилань, автор вирішив скористатися іншим методом (оскільки у мене вже є тонна вмісту, я не хочу перепаровувати).
Замість цього я додав функцію JavaScript, яка шукає всі ці типи посилань, а потім використовує htmx.ajax
зробити заміну. Це, по суті, те, що HTMX робить в будь-якому випадку просто "вручну."
Як ви бачите, це просто функція, яка шукає всі посилання div.prose
елемент, який починається з a /
а тоді додає слухачеві події. Якщо посилання було натиснуто, події буде заборонено, буде видобуто адресу URL, а потім посилання htmx.ajax
function викликається за допомогою адреси URL і елемента призначення для оновлення.
(function(window) {
window.blogswitcher =() => {
const blogLinks = document.querySelectorAll('div.prose a[href^="/"]');
// Iterate through all the selected blog links
blogLinks.forEach(link => {
link.addEventListener('click', function(event) {
event.preventDefault();
let link = event.currentTarget;
let url = link.href;
htmx.ajax('get', url, {
target: '#contentcontainer', // The container to update
swap: 'innerHTML', // Replace the content inside the target
}).then(function() {
history.pushState(null, '', url);
window.scrollTo({
top: 0,
behavior: 'smooth' // For a smooth scrolling effect
});
});
});
});
};
})(window);
Крім того, після того як помінялися місцями, я переводжу нову адресу до історії браузера і прокручую сторінки на вершину сторінки. Я використовую цей підхід в декількох місцях (такий як пошук) для того, щоб дати масла гладким відчуттям.
Зворотна кнопка у цьому типі програми може бути проблематичною, багато з них " властиві " SCAS або вимкнути кнопку зворотного зв' язку, або виконати таку неправильну поведінку. Проте я хотів переконатися, що задня кнопка працює так, як очікувалося.
Примітка: Щоб зробити так, як очікувалося, нам також потрібно послухати popState
Замечательно. Цю подію буде запущено під час переходу користувача назад або вперед у історії переглядача. @ info: whatsthis Після запуску цієї події ми можемо перезавантажити вміст поточної адреси URL.
window.addEventListener("popstate", (event) => {
// When the user navigates back, reload the content for the current URL
event.preventDefault();
let url = window.location.href;
// Perform the HTMX AJAX request to load the content for the current state
htmx.ajax('get', url, {
target: '#contentcontainer',
swap: 'innerHTML'
}).then(function () {
// Scroll to the top of the page
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
});
У цьому коді ми запобігаємо типовій поведінці навігатора за допомогою event.preventDefault()
Дзвінок. Далі ми витягуємо поточний URL з window.location.href
властивість і виконання запиту HTMX AJAX на завантаження вмісту поточного стану. Як тільки зміст буде завантажено, ми гортатимемо його на вершину сторінки.
Як вже згадувалося раніше, ви не можете користуватися ТАКОЖ hx-pushurl
оскільки за допомогою цього пункту можна наказати переглядачу повторно перезавантажити сторінку на бічній кнопці.
Як ви, можливо, здогадалися, я дещо фанат HTMX, разом з ядром ASP.NET і розбиття альпійських.js це дає змогу devs створити дійсно чудовий досвід користувача з мінімальними зусиллями. Основна річ, яку я віддаю перевагу таким, як "докладніше сформовані" клієнтські оболонки на кшталт React / Кутовий тощо... це те, що вона все ще надає мені повний канал відображення на сервері з ядром ASP. NET, але "відчуття" SPA. Альпійський.js надає можливість простої взаємодії з клієнтами, дуже проста функція, яку я нещодавно додав, робить мої категорії "прихованими," але розгорненими після клацання.
Використання альпійських.js для цього означає, що додаткового JavaScript не потрібно.
<div class="mb-8 mt-6 border-neutral-400 dark:border-neutral-600 border rounded-lg" x-data="{ showCategories: false }">
<h4
class="px-5 py-1 bg-neutral-500 bg-opacity-10 rounded-lg font-body text-primary dark:text-white w-full flex justify-between items-center cursor-pointer"
x-on:click="showCategories = !showCategories"
>
Categories
<span>
<i
class="bx text-2xl"
:class="showCategories ? 'bx-chevron-up' : 'bx-chevron-down'"
></i>
</span>
</h4>
<div
class="flex flex-wrap gap-2 pt-2 pl-5 pr-5 pb-2"
x-show="showCategories"
x-cloak
x-transition:enter="max-h-0 opacity-0"
x-transition:enter-end="max-h-screen opacity-100"
x-transition:leave="max-h-screen opacity-100"
x-transition:leave-end="max-h-0 opacity-0"
>
@foreach (var category in ViewBag.Categories)
{
<partial name="_Category" model="category"/>
}
</div>
</div>
Тут ви бачите, що я використовую x-data
атрибут створення нового об' єкта даних альпійської. js, у нашому випадку showCategories
. Це булівське значення, яке буде перемикано, якщо h4
clicked element. The x-on:click
атрибут використовується для прив' язки події клацання до функції- перемикача.
В межах списку категорій Я потім використовую x-show
атрибут, який слід показати або сховати список категорій на основі значення showCategories
. Я також використовую x-transition
attribute, щоб додати ефект спадання під час показу або приховування категорій.
The x-cloak
attribute використовується для запобігання запуску JavaScript для показу категорій.
У мене є маленький клас CSS визначений для цього:
[x-cloak] { display: none !important; }
Ось і все, коротка стаття про те, як використовувати HTMX і місце альпійського.js, щоб ваш сайт почувався більш чуйним і "SPA-подібним." Я сподіваюсь, що вам це стане у пригоді, якщо у вас є запитання або коментарі, будь ласка, залиште їх внизу.