LESSON 03 / 6   ·   产品与开发

让 HTML、CSS、JS 各司其职

本课交付:用语义元素与安全文本构建列表。

读案例 · 自己做 · 对照检查
讲义与练习单

核心方法

浏览器中的网页通常由三部分协作:HTML 描述内容与结构,CSS 控制视觉呈现,JavaScript 处理交互和数据。理解职责划分,可以让你向 AI 提出更准确的修改要求,也能更快定位“页面出来了,但按钮没反应”的原因。

本课程资料包包含完整的 index.html、style.css 和 app.js。下面展示与页面结构直接相关的代码片段;它们用于讲解,不是要求你用片段覆盖完整文件。初次运行请使用资料包中的三个完整文件。

本课的成果

通过本地 HTTP 服务器打开示例,确认样式和脚本成功加载,并能说明主要元素如何对应上一课的线框。命令中的工具需要在自己的电脑上安装;课程没有在你的设备上预先安装它们。

案例拆解

第一步:准备同一目录中的三个文件

reading-list/
  index.html   页面入口与语义结构
  style.css    排版、颜色、窄屏适配、焦点样式
  app.js       校验、存储、渲染、事件处理

HTML 中使用相对路径 style.css 和 app.js。这样把整个目录部署在网站子目录时也能找到资源。文件名的大小写要一致;某些本机文件系统容忍大小写差异,服务器未必如此。

第二步:理解入口的关键部分

<!doctype html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>下一本 · 我的阅读清单</title>
  <link rel="stylesheet" href="style.css">
  <script src="app.js" defer></script>
</head>

lang 声明页面语言,charset 避免中文编码错误,viewport 让移动端按设备宽度呈现。defer 使外部脚本在 HTML 解析后执行,减少脚本查找页面元素时它们尚不存在的问题。

<form id="book-form" novalidate>
  <label for="book-title">书名</label>
  <input id="book-title" aria-describedby="input-hint">
  <button type="submit">加入清单</button>
  <p id="input-hint">书名限制 1–80 个 Unicode 码点。</p>
</form>
<p id="status" role="status" aria-live="polite"></p>
<ul id="book-list"></ul>

这里的 novalidate 表示本示例由 JavaScript 统一处理输入规则,不是取消校验。不能删除脚本中的长度检查,又以为 HTML 会自动实现同样规则。状态区域用于反馈,列表由真实数据生成。

第三步:用少量 CSS 建立布局

* { box-sizing: border-box; }
main { max-width: 720px; margin: 0 auto; padding: 72px 24px; }
.input-row { display: flex; gap: 10px; }
input { flex: 1; min-width: 0; }
li span { overflow-wrap: anywhere; }
:focus-visible { outline: 3px solid #6335e8; outline-offset: 4px; }
@media (max-width: 480px) {
  .input-row { flex-direction: column; }
}

最大宽度保持长屏上的阅读尺度;min-width: 0 允许弹性布局中的输入框收缩;长书名可以换行;窄屏改为上下排列。不要删除焦点轮廓来“清爽一点”,它是键盘用户判断当前位置的重要反馈。

第四步:运行本地预览

如果已安装 Python,在项目目录打开终端运行:

python -m http.server 8099 --bind 127.0.0.1

浏览器打开 http://127.0.0.1:8099。端口被占用时可以改为另一个未使用端口,同时修改访问地址。也可以使用编辑器的静态预览服务。这个命令只提供本机预览,不会自动把网站发布到互联网;停止服务按 Ctrl+C。

第五步:检查加载,而不是凭感觉猜

打开开发者工具的 Network,刷新页面,确认三个文件没有 404;在 Console 查看脚本错误。如果完全没有样式,先检查路径和文件名;如果布局正常但新增无效,再检查脚本加载和报错位置。不要一开始就让模型重写整个项目。

提示词与使用说明

我在运行一个原生 HTML/CSS/JS 阅读清单。请帮我定位问题。
先根据证据提出最可能原因和验证步骤,再给最小修改。
不要更换技术栈,不增加构建工具,不要求我提供私密密钥。

目录结构:[粘贴]
访问地址:[填写本机地址]
预期行为:[填写]
实际行为:[填写]
控制台错误与失败请求:[粘贴相关内容,去掉敏感信息]
相关文件片段:[粘贴]

独立练习

先把答案写进本课笔记,再展开解析。以下人物、活动和数据均为教学用的虚构材料;练习记录请填写你实际完成的过程。

给定材料

输入例:<img src=x onerror=alert(1)>
代码片段:row.innerHTML = title;
添加控件使用 <div onclick="add()">添加</div>。

你的任务

把输入显示改成普通文字,再把添加控件换成能用键盘操作的元素。解释为何只过滤 <script> 仍不够。

完成后,对照参考解析

用 row.textContent = title 显示纯书名,不把输入当 HTML 解析;按钮使用 <button type="submit"> 并通过 form 的 submit 事件处理,配合 label 关联输入框。危险行为不只来自 script 标签,事件属性也可能执行。不要在正式网站运行不可信片段;此例用于识别代码边界。文本显示方案适合书名,不是富文本编辑器的完整清洗方案。

验收与迁移

对照自己的成果逐项检查。未达到的项目,写明缺什么、怎样补;这些标准用于自查,不会自动标记课时完成。

  • 用户输入以文本节点显示
  • Tab 和 Enter 可完成添加
  • 知道语义标签与输入安全各解决什么问题

带回自己的场景

在课程实验室中检查同类代码;需要富文本时使用经过评估的清洗方案,而非自己拼黑名单。

延伸资料

浏览器存储的使用与限制 ↗。资料用于核对方法和技术边界,案例与练习由 Nextory 编写。

← 上一课下一课

给好奇心,留一页笔记。

让 HTML、CSS、JS 各司其职 · 仅当前浏览器可访问

输入停止 2 秒后自动保存
课程目录
不妨从这里开始
搜索课程 · 实战指南 · AI 前沿↑↓ 选择 ↵ 进入 esc 关闭
探索 Nextory

确认操作