Web-Dev-For-Beginners 之 Terrarium 项目:HTML、CSS 与 DOM 拖放交互实战及 Azure Static Web Apps 部署指南
【免费下载链接】Web-Dev-For-Beginners24 Lessons, 12 Weeks, Get Started as a Web Developer项目地址: https://gitcode.com/GitHub_Trending/we/Web-Dev-For-Beginners
本项目是 Web-Dev-For-Beginners 课程第三单元「3-terrarium」的完整解决方案,用纯 HTML、CSS 与原生 JavaScript 构建了一个可交互的「虚拟植物玻璃罐」界面:14 株植物分列两侧,可被自由拖拽放入玻璃罐中任意位置。本指南以解决方案文档(translations/de/3-terrarium/solution/README.md)为主线,结合仓库内的 index.html、style.css、script.js 源码,讲解项目结构、三个核心技术环节(HTML 语义结构、CSS 玻璃罐绘制、基于闭包的 Pointer Events 拖放实现),并完整还原将项目部署到 Azure Static Web Apps 的步骤,读完即可亲手运行、改造并发布自己的 Terrarium。
项目概览:一个"代码冥想"式的小型全栈练习
从解决方案文档可知,这个项目被作者定义为 "a small drag and drop code-meditation"——一个短小精悍、可用于冥想式练习的拖放项目:只需要少量 HTML、JavaScript 和 CSS,就能完成「构建网页界面 → 美化样式 → 添加交互」的完整闭环。它之所以适合入门,是因为没有任何构建工具、框架或后端依赖,三个静态文件加一个图片目录即可运行:
| 文件 | 作用 | 核心知识点 |
|---|---|---|
| index.html | 页面结构与内容 | 语义化标签、容器布局、图片引入 |
| style.css | 全部视觉样式 | 绝对定位、CSS 绘制玻璃罐、响应式导航 |
| script.js | 拖放交互逻辑 | DOM 操作、Pointer Events、JavaScript 闭包 |
其中植物插画由作者 Jen Looper 使用 Procreate 手绘,玻璃罐外观则参考了 Jakub Mandra 的 CSS 玻璃罐作品——这正好呼应了课程的三个子章节:1-intro-to-html、2-intro-to-css、3-intro-to-DOM-and-closures。解决方案文档同时注明,本翻译版由 AI 翻译服务生成,若需权威内容应以英文原版(3-terrarium/solution/README.md)为准。
从源码看三大部分的实现细节
1. HTML:语义化结构是交互的地基
打开 index.html 可以看到,页面遵循 HTML5 标准文档结构:<head>中声明utf-8字符集、viewport移动端适配,并通过<link rel="stylesheet" href="./style.css" />与<script src="./script.js" defer></script>分别引入样式与脚本——其中defer属性确保脚本在 DOM 解析完成后才执行,避免getElementById找不到元素。
页面主体包含三个区块:
- 导航栏
<nav>:Home、Plants、Care Tips、About、Contact 五个链接,均搭配 Font Awesome 图标; - 植物陈列区:
#left-container与#right-container各容纳 7 个plant-holder容器,每个容器内是一张带唯一id(plant1~plant14)的植物图片plantN.png; - 玻璃罐区
#terrarium:由jar-top、jar-walls(内含jar-glossy-long/jar-glossy-short两个高光元素)、dirt、jar-bottom组成。
关键设计在于:每株植物都拥有全局唯一 ID,这是后续 JavaScript 通过document.getElementById('plant1')精准绑定拖放行为的必要前提(同一页面上 ID 不可重复)。
2. CSS:用绝对定位与半透明形状"画"出玻璃罐
style.css 展现了「不用一张图片、纯 CSS 绘制容器」的技巧:
.container采用position: absolute固定左右侧栏,宽度 15%,背景#eee;.plant图片position: absolute且max-width/height: 150%、z-index: 2,确保植物浮在罐子之上;- 玻璃罐由四个元素拼合:
jar-walls(高 80%、宽 60%、border-radius: 1rem、背景#d1e1df、opacity: 0.5)、jar-top、jar-bottom,以及dirt泥土层(#3a241d、z-index: -1置于罐后); jar-glossy-long/jar-glossy-short两根白色圆角细条(#ddfbff)模拟玻璃反光,让罐子更真实;- 后半部分还补充了导航栏渐变背景、hover/focus 态、页脚样式,以及
@media (max-width: 700px)下导航栏纵向堆叠的响应式适配。
这一节对应课程2-intro-to-css中「层叠(cascade)、选择器优先级、盒模型与定位」的知识点:正是position: absolute+z-index+opacity的组合,让平面 div 变成了半透明玻璃罐。
3. JavaScript:闭包 + Pointer Events 实现多对象独立拖放
script.js 是整个交互的核心,只有 64 行,却演示了两个重要概念:
(1)通过闭包为每株植物维护私有状态。文件顶部先对 14 个植物元素逐一调用dragElement(document.getElementById('plantN'))。而dragElement函数内部声明了pos1~pos4四个局部变量,并定义了pointerDrag、elementDrag、stopElementDrag三个内部函数。由于闭包特性,每次调用dragElement都会创建一份独立的pos变量副本——这 14 株植物因此各自"记得"自己的坐标,互不干扰,这正是「每株植物拥有独立数据记录」的实现机制。
(2)Pointer Events 统一鼠标与触屏。事件流完整覆盖了拖放生命周期:
function pointerDrag(e) { e.preventDefault(); // 阻止文本选中等默认行为 pos3 = e.clientX; pos4 = e.clientY; // 记录按下点坐标 document.onpointermove = elementDrag; // 挂载移动监听(挂在 document 上) document.onpointerup = stopElementDrag; } function elementDrag(e) { pos1 = pos3 - e.clientX; // 本次水平位移 pos2 = pos4 - e.clientY; // 本次垂直位移 pos3 = e.clientX; pos4 = e.clientY; // 更新基准点 terrariumElement.style.top = (terrariumElement.offsetTop - pos2) + 'px'; terrariumElement.style.left = (terrariumElement.offsetLeft - pos1) + 'px'; } function stopElementDrag() { document.onpointerup = null; // 清理监听,防止内存泄漏 document.onpointermove = null; }这里的两个工程细节值得注意:一是onpointermove/onpointerup挂载在document上而非植物元素上,这样指针移出植物甚至移出窗口时拖拽仍不中断;二是拖放结束后将两个监听置空,避免事件监听器累积导致性能问题。源码注释也标明,此方案借鉴了 w3schools 的可拖拽 HTML 元素示例,适合作为进一步学习的参考起点。
本地运行与体验
项目无任何构建步骤,运行方式极其简单,二选一即可:
- 直接双击打开
3-terrarium/solution/index.html(浏览器会以file://协议渲染页面); - 起一个本地静态服务器(推荐,便于后续模拟真实部署环境):
cd 3-terrarium/solution python3 -m http.server 8000 # 浏览器访问 http://localhost:8000验证交互时,按住任意植物拖动,观察其跟随指针移动,松开后停留在新位置;用鼠标或触屏均可操作,这正是 Pointer Events 带来的跨设备一致性。从源码结构看,代码没有预设"放置区"限制,用户可以把植物摆到页面上任意位置——这是有意的设计,赋予用户完全的创作自由。
部署到 Azure Static Web Apps
解决方案文档给出了将 Terrarium 发布到公网的官方途径:Azure Static Web Apps。这是一项专为静态站点设计的托管服务,天然适合本项目这种"无 API、纯前端"的应用。完整步骤如下:
- Fork 本仓库到自己的 GitHub 账号下(需要先把代码放到自己的 GitHub 仓库中);
- 创建 Azure Static Web App:进入 Azure 门户创建 Static Web App 资源(原文档中提供了 "Deploy to Azure" 一键部署按钮,可直接跳转到创建向导);
- 走完创建向导,关键配置为:
- App root(应用根目录)设置为
/solution,或设置为你的代码根目录——Terrarium 的全部静态资源都位于该目录下,设置错误将导致发布后无法加载页面; - API 可跳过:本项目没有任何后端 API,向导中无需配置;
- 向导完成后,Azure 会在你的 fork 仓库中自动创建一个
.github工作流目录,其中包含 Azure Static Web Apps 的构建/发布配置;后续每次推送到对应分支,CI 都会自动重新构建并部署到新生成的 URL。
- App root(应用根目录)设置为
部署完成后,Azure 会分配一个形如https://<app-name>.azurestaticapps.net的公网地址,你的 Terrarium 即可分享给任何人访问。
延伸练习建议
结合课程3-intro-to-DOM-and-closures的课后任务,完成基础拖放后可以尝试以下扩展,进一步巩固 DOM 与状态管理能力:
- 双击置顶:通过修改
z-index让双击的植物浮到最上层; - 拖拽边界:限制植物不能移出玻璃罐区域(
#terrarium的边界判定); - 位置持久化:用
localStorage保存每株植物的坐标,刷新后还原布局; - 重置功能:页面加载时记录初始位置,提供按钮配合 CSS 过渡动画让植物平滑回到侧栏;
- hover 反馈:指针悬停时给植物添加微弱发光效果,提升交互质感。
小结
从translations/de/3-terrarium/solution/README.md这份解决方案文档出发,结合仓库源码可以看到:Terrarium 用最少的工具链,串起了 Web 开发入门最核心的三块拼图——HTML 语义结构、CSS 视觉呈现、基于闭包与 Pointer Events 的 DOM 交互;而 Azure Static Web Apps 的部署流程则补全了"开发 → 发布"的最后一环。这套源码同时是3-terrarium三个子章节(1-intro-to-html、2-intro-to-css、3-intro-to-DOM-and-closures)的标准答案,适合边读课程边对照验证。更详细的拖放原理讲解可继续阅读 3-intro-to-DOM-and-closures/README.md,玻璃罐 CSS 的视觉参考可查看 2-intro-to-css/README.md。
【免费下载链接】Web-Dev-For-Beginners24 Lessons, 12 Weeks, Get Started as a Web Developer项目地址: https://gitcode.com/GitHub_Trending/we/Web-Dev-For-Beginners
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考