首页
/ freeCodeCamp HTML 表单课程精讲:用 checked 属性让单选按钮与复选框默认选中

freeCodeCamp HTML 表单课程精讲:用 checked 属性让单选按钮与复选框默认选中

2026-09-06 19:05:16作者:袁立春Spencer

本指南围绕 freeCodeCamp 响应式网页设计(Responsive Web Design)认证下 "Basic HTML and HTML5" 模块的第 24 个挑战(标题为 Check Radio Buttons and Checkboxes by Default)展开,系统讲解 HTML 表单中 checked 属性的作用、写法、运行时语义,并结合该挑战的题目、自动化测试(hints)与官方参考实现进行逐行剖析。读完你不仅能独立完成这道闯关练习,还能理解"HTML 标记中的默认选中"与"浏览器中的实际选中状态"之间的关系,以及 checkedvaluename 等属性在表单数据提交中的分工。

挑战在课程体系中的定位

该挑战文件位于 curriculum/challenges/english/blocks/basic-html-and-html5/bad87fee1348bd9aedd08835.md,元数据(frontmatter)表明它属于 challengeType: 0(基础代码闯关型挑战),并挂载了配套的视频讲解与论坛主题链接。

从模块的编排文件 curriculum/structure/blocks/basic-html-and-html5.json 可以看到,它处在一组层层递进的表单课程末尾部分,其直接前驱是:

  1. Create a Set of Radio Buttonsbad87fee1348bd9aedf08834.md)——掌握 name 相同即构成单选组、选项互斥的原理;
  2. Create a Set of Checkboxesbad87fee1348bd9aedf08835.md)——掌握多选控件的基本写法;
  3. Use the value attribute with Radio Buttons and Checkboxes5c6c06847491271903d37cfd.md)——掌握提交表单时数据如何以 name=value 形式上报。

本挑战是这个链条的收尾:此前课程只要求"能选中",本课则要求"默认就处于选中状态"。同模块后续的 Nest Many Elements within a Single div ElementDeclare the Doctype of an HTML Document 等则转向结构语义与文档骨架,说明本挑战是 CatPhotoApp 表单部分最后一块交互拼图。

核心知识点:checked 布尔属性

课程说明给出的一句话定义是本课的题眼:

你可以通过 checked 属性让一个复选框(checkbox)或单选按钮(radio button)在页面加载时默认处于选中状态。

实现方式极为简单:只需在对应的 input 元素内部加上单词 checked,例如:

<input type="radio" name="test-name" checked>

需要说明的是,checked 属于 HTML 的布尔属性(boolean attribute)之一。它的判定规则是"只看属性是否存在,不看值",因此:

<input type="radio" checked>              <!-- 合法,默认选中 -->
<input type="radio" checked="checked">    <!-- 合法,默认选中 -->
<input type="radio" checked="">           <!-- 合法,默认选中 -->
<input type="radio">                      <!-- 未选中 -->
<input type="checkbox" checked>           <!-- 复选框同样适用 -->

在绝大多数情况下,按课程示例直接书写裸属性 checked 即可,这也是最能体现布尔属性本意的写法。

单选按钮组与复选框的默认状态差异

虽然 checkedtype="radio"type="checkbox" 都生效,但它们的互斥语义截然不同,这正是本挑战设计成"单选按钮和复选框各设置一个默认选中"的原因:

  • 单选按钮(radio):同一组(name 相同)中任何时候最多只能有一个处于选中状态。用户点击任意一个,同组其他项自动取消选中。
  • 复选框(checkbox):同一组内每个复选框相互独立,可以同时勾选多个,也可以全部不勾选。

与之对应,HTML 规范规定:如果同一单选组中有多个元素在标记里写了 checked,浏览器解析后只会让其中某一个处于选中(实践中通常表现为树序中最后一个),因此不要通过"写多个 checked"试图实现多选——单选组天然不允许这种状态。而在一个组里给多个输入写 checked 也不会在提交时生效为多值。反观复选框没有此限制,想默认勾选几个就写几个。

任务实操:让 CatPhotoApp 表单单选与复选默认选中

挑战的指令(instructions)非常明确:

将你表单中的第一个单选按钮和第一个复选框都设置为默认选中。

--seed-- 段给出了完整起始代码。为了便于对照行号,其表单部分结构如下(完整代码见 bad87fee1348bd9aedd08835.md 的 seed 段):

<h2>CatPhotoApp</h2>
<main>
  <p>Click here to view more <a href="#">cat photos</a>.</p>

  <a href="#"><img src="https://cdn.freecodecamp.org/curriculum/cat-photo-app/relaxing-cat.jpg" alt="A cute orange cat lying on its back."></a>

  <p>Things cats love:</p>
  <ul>
    <li>catnip</li>
    <li>laser pointers</li>
    <li>lasagna</li>
  </ul>
  <p>Top 3 things cats hate:</p>
  <ol>
    <li>flea treatment</li>
    <li>thunder</li>
    <li>other cats</li>
  </ol>
  <form action="https://www.freecatphotoapp.com/submit-cat-photo">
    <label for="indoor"><input id="indoor" type="radio" name="indoor-outdoor" value="indoor"> Indoor</label>
    <label for="outdoor"><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label><br>
    <label for="loving"><input id="loving" type="checkbox" name="personality" value="loving"> Loving</label>
    <label for="lazy"><input id="lazy" type="checkbox" name="personality" value="lazy"> Lazy</label>
    <label for="energetic"><input id="energetic" type="checkbox" name="personality" value="energetic"> Energetic</label><br>
    <input type="text" placeholder="cat photo URL" required>
    <button type="submit">Submit</button>
  </form>
</main>

动手步骤

  1. 找到表单中的第一组单选按钮。indoor-outdoor 组按文档顺序排列,第一个id="indoor"、标签文本为 Indoor 的那个 <input>,在它的标签内补上 checked
  2. 找到复选框组。personality 组中的第一个id="loving"、标签文本为 Loving<input>,同样补上 checked
  3. 保留其余控件(outdoorlazyenergetic、文本输入框、提交按钮)原封不动,尤其是两个 label 的显示文本必须保持不变,否则会触发后面的校验失败。

两个关键点:单选组内只能默认选中一个(indoor);复选框仅把组内第一个设为默认勾选,其余留空,以演示"复选框可部分默认选中"这一行为。

官方参考实现解析

--solutions-- 段给出了经过验证的完整答案,与 seed 的唯一差异正是两处 checked(对照 bad87fee1348bd9aedd08835.md):

<h2>CatPhotoApp</h2>
<main>
  <p>Click here to view more <a href="#">cat photos</a>.</p>

  <a href="#"><img src="https://cdn.freecodecamp.org/curriculum/cat-photo-app/relaxing-cat.jpg" alt="A cute orange cat lying on its back."></a>

  <p>Things cats love:</p>
  <ul>
    <li>catnip</li>
    <li>laser pointers</li>
    <li>lasagna</li>
  </ul>
  <p>Top 3 things cats hate:</p>
  <ol>
    <li>flea treatment</li>
    <li>thunder</li>
    <li>other cats</li>
  </ol>
  <form action="https://www.freecatphotoapp.com/submit-cat-photo">
    <label for="indoor"><input id="indoor" type="radio" name="indoor-outdoor" value="indoor" checked> Indoor</label>
    <label for="outdoor"><input id="outdoor" type="radio" name="indoor-outdoor" value="outdoor"> Outdoor</label><br>
    <label for="loving"><input id="loving" type="checkbox" name="personality" value="loving" checked> Loving</label>
    <label for="lazy"><input id="lazy" type="checkbox" name="personality" value="lazy"> Lazy</label>
    <label for="energetic"><input id="energetic" type="checkbox" name="personality" value="energetic"> Energetic</label><br>
    <input type="text" placeholder="cat photo URL" required>
    <button type="submit">Submit</button>
  </form>
</main>

可以看到:indoor 单选与 loving 复选框各加了一个 checked,结构零改动,这也印证了"默认选中只关乎属性本身,与元素顺序、嵌套层级无关"。

自动化校验(hints)逐条拆解

freeCodeCamp 的这类挑战会在你的代码于 iframe 中渲染后执行一段浏览器端 JavaScript 断言(hints),全部通过才算完成。本挑战共四条(见文档 hints 段):

assert.isTrue(document.querySelector('input[type="radio"]').checked);
  • 作用:断言页面第一个 type="radio" 输入(即 indoor)的 DOM 属性 .checkedtrue
  • 注意 document.querySelector 只返回文档中第一个匹配元素,因此该断言天然对应"第一个单选按钮"。
  • 校验的是运行时 DOM 的 checked 属性(property) 而非静态源码字符串——也就是说,只有当你把 checked 写在正确的 <input> 上,浏览器解析后 .checked 才会为真。
assert.isTrue(document.querySelector('input[type="checkbox"]').checked);
  • 同上,断言第一个复选框(loving)默认选中。checkbox 与 radio 的选择器前缀区分了控件类型,验证你两种类型都处理到了。
assert.equal(document.querySelector('label[for="indoor"]')?.innerText?.trim(), 'Indoor');
assert.equal(document.querySelector('label[for="loving"]')?.innerText?.trim(), 'Loving');
  • 这两条用于保护题目语义不被破坏:IndoorLoving 两个标签文本必须保持原样。代码中的可选链 ?. 表示若找不到对应 label 直接判失败,.trim() 去除首尾空白后再做严格相等比较。
  • 它们的存在意味着解题时不能通过改写选项文字来"作弊",只能靠 checked 达成目的。

这些测试的定义方式也对应着仓库中对挑战文件结构的校验规则:在 curriculum/schema/challenge-schema.js 中,tests 字段被定义为由 { text, testString } 组成的数组,testString 即上述 JS 断言字符串,而 hints 段中的每条提示正好一一映射为该挑战运行时执行的测试用例。

常见失败情形自查

现象 可能原因
第一条 radio 断言失败 checked 写在了 outdoor 而非 indoor 上;或两个单选都写了 checked 导致浏览器仅保留其中一个
第一条 checkbox 断言失败 checked 写在了 lazy/energetic 上;或根本没有添加该属性
label 文本断言失败 修改了 Indoor/Loving 的显示文字,或在标签中混入了多余空白以外的字符
语法层报错 checked 写成了 checked="true" 以外的非法组合或写在了 </input> 后——实际上 input 是空元素,属性只能写在其开始标签内

valuename 的关系:默认选中之后,表单提交什么?

前面的课程已经强调过 value 的作用,这里需要把三者的分工彻底厘清,否则很容易把"默认选中"和"提交内容"混淆:

  • name:定义控件的数据键。同一单选组共用同一个 name,提交时只上报被选中的那一项。
  • value:定义控件的数据值。如 5c6c06847491271903d37cfd.md 所强调的:若省略 value,表单数据会退化为无意义的 on;设置 value="indoor" 后,用户选中 indoor 并提交,服务器收到的就是 indoor-outdoor=indoor
  • checked:只决定初始呈现的选中状态,本身不参与数据提交。

也就是说,本挑战中的 indoor 单选同时具备三个属性,它们各司其职:

<input id="indoor" type="radio" name="indoor-outdoor" value="indoor" checked>
  • name="indoor-outdoor" 决定它属于哪个单选组;
  • value="indoor" 决定被选中后以 indoor-outdoor=indoor 提交;
  • checked 决定页面加载时它直接被勾选,用户不操作也能产生上述默认数据。

此外还有两个"运行时"层面的细节值得延伸:HTML 标记里的 checked 对应 DOM 中的 defaultChecked,它刻画的是"初始默认态";而 input.checked(本挑战断言所访问的属性)反映的是"当前实际选中态",用户后续点击会改变 .checked 但不会改写 defaultChecked。复选框中另一个相关规则是:只有处于选中状态的 checkbox 才会被纳入表单数据,未勾选的不产生任何键值对——这与单选组(始终有一项被提交,除非全组未设默认值且用户未选)行为不同。

无障碍与使用建议

延续本模块此前课程(如 bad87fee1348bd9aedf08834.md)反复强调的最佳实践,seed 代码中的结构本身就示范了几点值得在真实项目中沿用、同时也是本挑战正确通过的前提:

  • label 与 input 显式关联<label for="indoor"><input id="indoor"> 通过 id/for 配对,点击文字即可切换选中,屏幕阅读器也能正确朗读选项含义;
  • 单选组共享 nameindoor/outdoor 共用 indoor-outdoor,保证互斥语义成立,也保证"默认选中其中一项"才有确定含义;
  • 默认选中值的选择要有业务依据:给单选组设默认值通常用于表达"推荐项"或"最常见取值",从而减少用户操作;而复选框的默认勾选则常用于"订阅/同意"类意向确认——但涉及用户授权、订阅营销等场景时应审慎使用默认勾选,避免违背用户真实意图。

在真实项目中,"记住用户上次选择后再回显"也是常见的 checked 应用场景:服务端返回用户偏好后,前端动态设置 input.checked = true 即可(此时操作的是 DOM 属性而非 HTML 属性),效果与本题在静态标记中书写 checked 在用户可见层面一致。

小结

本挑战用最小改动(每个目标 input 增加一个 checked 属性)演示了 HTML 表单最常用的默认选中机制。通过对照 seed、solution 与四条浏览器断言可以发现:判断题解正确与否的锚点是 DOM 中真实存在的选中状态,单选按钮的组内互斥、复选框的独立多选、以及 checkedname/value/defaultChecked 的职责边界,共同构成了这道题希望学习者内化的完整知识图景。在完成本挑战后,可继续同模块的下一课,把 HTML 表单的结构能力延伸到更深的语义化布局学习中。

登录后查看全文
热门项目推荐
相关项目推荐