HTMX构建无重载闪烁的交互式页面

2025-04-02T17:52:46+08:00 | 4分钟阅读 | 更新于 2025-04-02T17:52:46+08:00

Macro Zhao

HTMX构建无重载闪烁的交互式页面

推荐超级课程:

@TOC

对于您的Web应用程序来说,React通常可能过于庞大,有时仅使用Web服务器和HTMX就能创建出具有交互性的应用程序,效果不亚于React框架。

在这篇博客文章中,我们将展示如何使用HTMX 构建无重载闪烁的交互式页面导航:

服务器设置



mkdir no-react-app   

cd no-react-app  

npm init -y  

npm install express nunjucks

然后我们创建一个服务器文件并运行


//文件:app.js  

const express = require("express")  

const app = express()  

  

const nunjucks = require('nunjucks');  

nunjucks.configure("views", {  

    autoescape: true,  

    express: app  

});  

  

app.get("/", (req, res) => {  

    res.render("pages/home.html")  

})  

  

app.get("/users", (req, res) => {  

    res.render("pages/users.html")  

})  

  

app.get("/posts", (req, res) => {  

    res.render("pages/posts.html")  

})  

  

app.listen(3000, () => {  

    console.info(`应用程序运行于 http://localhost:3000`)  

})

我们使用nunjucks作为模板引擎。所有模板、布局和部分文件都将存储在“views”目录中。因此,我们的项目结构将如下所示:

应用结构



app.js  

views  

  layouts  

    main.html  

  partials  

    sidenav.html  

  pages  

    user.html  

    home.html  

    posts.html

因为我们在使用模板引擎,所以让我们添加一个所有视图都将继承的主布局

主布局



<!--文件:views/layouts/main.html-->  

<!DOCTYPE html>  

<html lang="en">  

<head>  

    <meta charset="UTF-8">  

    <meta name="viewport" content="width=device-width, initial-scale=1.0">  

    <link rel="stylesheet"  

        href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.0.2/tailwind.min.css" />  

    <title>HTMX应用</title>  

</head>  

  

<body class="bg-gray-200">  

    <div class="flex h-screen">  

        <!-- 侧边导航 -->  

        {%- include('partials/sidenav.html')%}  

  

        <!-- 主内容区域 -->  

        <div class="w-full bg-white p-4" id="main">  

            {% block content %}{% endblock %}  

        </div>  

</body>  

  

</html>

我们已经将一个侧边导航模板组件重构为部分页面,并将其包含在我们的布局中。

侧边导航组件



<!--文件:views/partials/sidenav.html-->  

<div class="w-56 bg-gray-800 text-white p-4">  

    <a href="/" class="block py-2 px-4 text-white hover:bg-gray-600">首页</a>  

    <a href="/users" class="block py-2 px-4 text-white hover:bg-gray-600">用户</a>  

    <a href="/posts" class="block py-2 px-4 text-white hover:bg-gray-600">帖子</a>  

</div>

并创建了我们的主要页面,home.html,users.html 和 posts.html

页面



<!--views/pages/home.html-->  

{% extends 'layouts/main.html' %}  

  

{% block content %}  

<h1 class="text-2xl font-bold mb-4">HTMX 导航</h1>  

{% endblock %}

<!--views/pages/users.html-->  

{% extends 'layouts/main.html' %}  

  

{% block content %}  

<h1 class="text-2xl font-bold mb-4">用户</h1>  

{% endblock %}

<!--views/pages/posts.html-->  

{% extends 'layouts/main.html' %}  

  

{% block content %}  

<h1 class="text-2xl font-bold mb-4">帖子</h1>  

{% endblock %}

当我们运行服务器时,我们有了导航,但是会有整页重新加载:

我们必须通过引入一个轻量级的JavaScript库HTMX 来解决这个问题。这个库可以通过使导航更加无缝和互动来大大提升用户体验。需要注意的是,HTMX有更广泛的应用范围,但出于我们当前的目的,我们将专注于利用其能力来实现更平滑的导航。

使用HTMX逐步增强


使用HTMX的最快方式是通过CDN加载它。你可以简单地将以下代码添加到你的head标签中并开始使用:


<!--文件:views/layouts/main.html-->  

...  

    <script src="https://unpkg.com/htmx.org@latest"></script>  

    <title>HTMX 应用</title>  

</head>  

...

现在,我们可以对侧边导航进行一个小改动

  1. 删除href属性并替换为hx-get属性。当用户点击这个链接时,会发出一个HTTP GET请求。

  2. 将hx-target属性添加到每个锚标签或锚标签的父div上。hx-target属性允许你指定一个元素,用于替换hx-get的响应。

  3. 给每个锚标签添加hx-push-url=”true”。hx-push-url属性允许你将一个URL推入浏览器位置历史记录。这会创建一个新的历史记录条目,允许使用浏览器的后退和前进按钮进行导航。

这样做的作用是:我们声明性地指示HTMX库在点击锚标签时进行服务器调用,并将响应插入到id为‘main’的div中


<div class="w-56 bg-gray-800 text-white p-4" hx-target="#main"  >  

    <a hx-get="/" hx-push-url="true"  class="block py-2 px-4 text-white hover:bg-gray-600">首页</a>  

    <a hx-get="/users" hx-push-url="true"  class="block py-2 px-4 text-white hover:bg-gray-600">用户</a>  

    <a hx-get="/posts" hx-push-url="true"  class="block py-2 px-4 text-white hover:bg-gray-600">帖子</a>  

</div>我们现在有以下内容。

我们解决了闪烁问题,并且如果我们要分享导航,URL会正确地推送至新URL

使应用支持HTMX


我们需要确定每个进入的服务器请求是否为HTMX调用。如果是,我们必须指示模板引擎跳过使用布局,并简单地返回该模板的HTML。为了实现这一点,我们需要融入特定的中间件!


//文件:app.js  

...  

app.use((req, res, next) => {  

    res.locals.useLayout = req.headers["hx-request"] !== "true";  

    next();  

})  

  

app.listen(3000, () => {  

    console.info(`应用运行于 http://localhost:3000`)  

})

仅当未检测到HTMX请求时使用布局。


<!--文件:views/layouts/main.html-->  

{% if useLayout %}  

<!DOCTYPE html>  

<html lang="en">  

  

<head>  

    <meta charset="UTF-8">  

    <meta name="viewport" content="width=device-width, initial-scale=1.0">  

    <link rel="stylesheet"  

        href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.0.2/tailwind.min.css" />  

    <script src="https://unpkg.com/htmx.org@latest"></script>  

    <title>HTMX应用</title>  

</head>  

<body class="bg-gray-200">  

    <div class="flex h-screen">  

        <!-- 侧边导航 -->  

        {%- include('partials/sidenav.html')%}  

        <!-- 主内容区域 -->  

        <div class="w-full bg-white p-4" id="main">  

{% endif %}  

  

            {% block content %}{% endblock %}  

  

{% if useLayout %}  

        </div>  

</body>  

</html>  

{% endif %}

我们成功实现了一个无缝且无重载闪烁的导航体验。

© 2011 - 2025 Macro Zhao的分享站

关于我

如遇到加载502错误,请尝试刷新😄

Hi,欢迎访问 Macro Zhao 的博客。Macro Zhao(或 Macro)是我在互联网上经常使用的名字。

我是一个热衷于技术探索和分享的IT工程师,在这里我会记录分享一些关于技术、工作和生活上的事情。

我的CSDN博客:
https://macro-zhao.blog.csdn.net/

欢迎你通过评论或者邮件与我交流。
Mail Me

推荐好玩(You'll Like)
  • AI 动·画
    • 这是一款有趣·免费的能让您画的画中的角色动起来的AI工具。
    • 支持几十种动作生成。
我的项目(My Projects)
  • 爱学习网

  • 小乙日语App

    • 这是一个帮助日语学习者学习日语的App。
      (当然初衷也是为了自用😄)
    • 界面干净,简洁,漂亮!
    • 其中包含 N1 + N2 的全部单词和语法。
    • 不需注册,更不需要订阅!完全免费!
  • 小乙日文阅读器

    • 词汇不够?照样能读日语名著!
    • 越读积累越多,积跬步致千里!
    • 哪里不会点哪里!妈妈再也不担心我读不了原版读物了!
赞助我(Sponsor Me)

如果你喜欢我的作品或者发现它们对你有所帮助,可以考虑给我买一杯咖啡 ☕️。这将激励我在未来创作和分享更多的项目和技术。🦾

👉 请我喝一杯咖啡

If you like my works or find them helpful, please consider buying me a cup of coffee ☕️. It inspires me to create and share more projects in the future. 🦾

👉 Buy me a coffee