表单与交互式元素

表单

<form> 元素

描述

<form> 元素用于表示一个超链接,该超链接可以通过一组与表单关联的元素进行操作。其中部分元素可表示可编辑的值,并可将这些值提交到服务器进行处理。

技术摘要
  • 类别

    • 流内容。

    • 可感知内容。

  • 此元素可使用的上下文:在需要流内容的地方。

  • 内容模型 :流内容,但其后代中不得包含 <form> 元素。

属性
  • action:处理表单提交的 URL。
    • 该值可被 <button><input type="submit"><input type="image"> 元素上的 formaction 属性覆盖。
    • 当设置了 method="dialog" 时,此属性将被忽略。
  • autocomplete:指示浏览器是否默认自动补全输入元素的值。
    • 可选值:
      • off:浏览器可能不会自动补全条目。
      • on:浏览器可能会自动补全条目。
    • 表单元素上的 autocomplete 属性会覆盖 <form> 上的此属性。
  • enctype:当 method 属性值为 post 时,enctype 指定表单提交的 MIME 类型。
    • 可选值:
      • application/x-www-form-urlencoded:默认值。
      • multipart/form-data:若表单包含 type=file<input> 元素,则需使用此值。
      • text/plain:调试时使用。
    • 该值可被 <button><input type="submit"><input type="image"> 元素上的 formenctype 属性覆盖。
  • method:提交表单时使用的 HTTP 方法。
    • 可选值:
      • get:默认值,使用 GET 方法,表单数据附加到 action URL 后,以 ? 分隔。当表单无副作用时使用此方法。
      • post:使用 POST 方法,表单数据作为请求体发送。
      • dialog:当表单位于 <dialog> 内时,提交后会关闭对话框并触发提交事件,但不会提交数据或清空表单。
    • 该值可被 <button><input type="submit"><input type="image"> 元素上的 formmethod 属性覆盖。
  • name:表单的名称。该值不能为空字符串,并且在所属的 forms 集合中必须唯一。
    • name 会成为 WindowDocumentdocument.forms 对象的属性,指向该表单元素。
  • novalidate:布尔属性,如果存在,提交时不验证表单。
    • 该值可被 <button><input type="submit"><input type="image"> 元素上的 formnovalidate 属性覆盖。
  • target:指定提交表单后响应的显示位置。
    • 取值和 <a> 元素的 target 属性一致。
使用示例

示例1:模拟登录

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>登录表单</title>
  <link rel="stylesheet" href="./css/index.css" />
</head>

<body>
  <div class="form-container">
    <h1>登录</h1>
    <form id="loginForm">
      <label for="username">用户名:</label>
      <input type="text" id="username" name="username" placeholder="admin 或 user" required>

      <label for="password">密码:</label>
      <input type="password" id="password" name="password" placeholder="123456" required>

      <button type="submit" id="submitBtn">登录</button>
    </form>
    <div id="message" class="message hidden"></div>
  </div>

  <script src="./js/index.js"></script>
</body>

</html>

示例2:submit() vs requestSubmit() 对比

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>submit() vs requestSubmit() 对比</title>
  <link rel="stylesheet" href="./css/index.css">
</head>

<body>
  <div class="container">
    <h1>两种提交方法对比</h1>

    <form id="myForm">
      <div class="input-group">
        <label>用户名</label>
        <input type="text" name="username" value="李雷" required minlength="2">
      </div>

      <div class="input-group">
        <label>留言</label>
        <textarea name="message" placeholder="输入少于5个字符测试区别..." required minlength="5"></textarea>
      </div>

      <div class="buttons">
        <button class="btn-danger" onclick="useSubmit()">
          form.submit()
        </button>
        <button class="btn-success" onclick="useRequestSubmit()">
          form.requestSubmit()
        </button>
      </div>
    </form>

    <!-- 结果弹窗 -->
    <div id="resultPopover" popover>
      <div id="resultContent"></div>
      <button popovertarget="resultPopover">关闭</button>
    </div>
  </div>

  <script src="./js/index.js"></script>
</body>

</html>

示例3:submitter 属性的使用

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>submitter 属性的使用</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <div class="container">
    <h1>submitter 属性演示</h1>
    <p class="subtitle">点击不同按钮,观察 submitter 如何标识提交来源</p>

    <form id="myForm">
      <input type="text" name="username" placeholder="用户名" required>

      <div class="btns">
        <!-- 不同功能的提交按钮 -->
        <button type="submit" name="btn" value="save" class="btn-save">保存草稿</button>
        <button type="submit" name="btn" value="publish" class="btn-publish">立即发布</button>
        <button type="submit" name="btn" value="preview" class="btn-preview">预览效果</button>
      </div>
    </form>

    <!-- 结果展示 -->
    <div id="result" popover>
      <div class="result-header" id="resultHeader"></div>
      <div class="result-body">
        <p><b>触发按钮:</b><code id="submitterInfo"></code></p>
        <p><b>按钮名称:</b><span id="submitterName"></span></p>
        <p><b>按钮值:</b><span id="submitterValue"></span></p>
      </div>
      <button popovertarget="result">关闭</button>
    </div>
  </div>

  <script src="./js/main.js"></script>
</body>

</html>

示例4:formdata 事件的使用

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>formdata 事件的使用</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <div class="container">
    <h1>文章发布</h1>

    <form id="articleForm">
      <div class="input-group">
        <label for="title">标题 *</label>
        <input type="text" id="title" name="title" placeholder="请输入文章标题" required>
      </div>

      <div class="input-group">
        <label for="category">分类</label>
        <select name="category" id="category">
          <option value="tech">技术</option>
          <option value="life">生活</option>
          <option value="news">资讯</option>
        </select>
      </div>

      <div class="input-group">
        <label for="content">内容 *</label>
        <textarea id="content" name="content" rows="6" placeholder="请输入文章内容..." required></textarea>
      </div>

      <div class="input-group">
        <label>
          <input type="checkbox" name="isTop"> 置顶文章
        </label>
      </div>

      <button type="submit" id="submitBtn">发布文章</button>
      <button type="button" id="cancelBtn" class="hidden" onclick="resetForm()">取消</button>
    </form>

    <!-- 文章列表 -->
    <div class="list">
      <h3>已发布文章</h3>
      <div id="articleList"></div>
    </div>

    <!-- 数据预览弹窗 -->
    <div id="previewPopover" popover>
      <h4>即将提交的数据</h4>
      <pre id="previewData"></pre>
      <button popovertarget="previewPopover">关闭</button>
    </div>
  </div>

  <script src="./js/main.js"></script>
</body>

</html>

示例5:reset 事件不能触发 change 事件

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>reset 事件不能触发 change 事件</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <form>
    <p>单价:¥40</p>
    <p>数量:<input type="number" id="quantity" value="1">件</p>
    <p>总价:<output id="price">40</output>元</p>
    <button type="reset">重置</button>
  </form>

  <script src="./js/main.js"></script>
</body>

</html>
注意事项
  • submit()requestSubmit() 方法的区别:
    • submit() 方法:
      • 直接提交表单:submit() 方法直接提交表单数据,触发表单的原生提交动作。通常会刷新页面或者触发页面跳转。
      • 跳过验证:submit() 方法不会执行 HTML5 表单的验证。
      • 没有事件触发:submit() 不会触发表单的 submit 事件。
    • requestSubmit() 方法:
      • 触发表单验证:requestSubmit() 会触发浏览器的内置表单验证机制。
      • 触发 submit 事件:requestSubmit() 会触发开发者自定义的 submit 事件。
      • 不会直接刷新或跳转:requestSubmit() 方法通常不会直接引发页面刷新或跳转,而是通过执行 submit 事件处理程序来决定是否提交表单。

<label> 元素

描述

<label> 元素表示用户界面中的一段说明文字。这段说明可以通过 for 属性与特定的表单控件建立关联(该控件称为 <label> 元素所标记的控件),也可以将表单控件直接放置在 <label> 元素内部来实现关联。

技术摘要
  • 类别

    • 流内容。

    • 短语内容。

    • 交互式内容。

    • 可感知内容。

  • 此元素可使用的上下文:在需要短语内容的地方。

  • 内容模型 :短语内容,但不得包含可标注元素的后代,除非该后代元素本身就是该元素的被标注控件;同时也不得包含 <label> 元素的后代。

属性
  • for:该属性的值是与 <label> 关联的表单控件的 id,且该控件需位于同一文档中。
    • 其对应的 JavaScript 反射属性为 htmlFor
使用示例

示例1:将标签与表单控件关联

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>标签与表单控件关联</title>
  <link rel="stylesheet" href="./css/style1.css">
</head>

<body>
  <form id="myForm">
    <h1>用户登录</h1>
    
    <!-- 显式关联:通过表单控件的 id 与 label 元素的 for 属性关联 -->
    <div class="form-group">
      <label for="uname">用户名:</label>
      <input type="text" id="uname" name="uname" placeholder="请输入用户名" required>
    </div>

    <div class="form-group">
      <label for="upwd">密码:</label>
      <input type="password" id="upwd" name="upwd" placeholder="请输入密码" required>
    </div>

    <!-- 隐式关联:直接将表单控件放置在 label 元素内 -->
    <div class="form-group">
      <label class="implicit-label">
        <input type="checkbox" name="remember" checked>
        <span>记住我(30天内自动登录)</span>
      </label>
    </div>

    <button type="submit" class="submit-btn">登录</button>
  </form>
</body>

</html>
注意事项
  • <label> 与表单控件关联起来,具有以下几个重要优势:
    • 标签文本不仅在视觉上与对应的文本输入框相关联,在程序层面上也同样关联。这意味着,当用户聚焦到表单输入框时,屏幕阅读器等辅助技术会读出标签文本,让使用辅助技术的用户更清楚应输入什么内容。
    • 当用户点击或触碰标签时,浏览器会将焦点传递到其关联的输入框。这种更大的点击区域为所有用户带来了操作上的便利。
  • 可以与 <label> 元素关联的控件包括:<button><input>(不包括 type="hidden")、<meter><output><progress><select> 以及 <textarea>

<input> 元素

描述

<input> 元素表示一个类型化的数据字段,通常带有表单控件,供用户编辑数据。

技术摘要
  • 类别

    • 流内容。

    • 短语内容。

    • type 属性状态不为隐藏:交互式内容。

    • type 属性状态不为隐藏:列出的、可标记的、可提交的、可重置的、且继承 autocapitalizeautocorrect 特性的表单关联元素。

    • type 属性状态为隐藏:列出的、可提交的、可重置的、且继承 autocapitalizeautocorrect 特性的表单关联元素。

    • type 属性状态不为隐藏:可感知内容。

  • 此元素可使用的上下文:在需要短语内容的地方。

  • 内容模型:不可包含任何内容。

属性
  • accept:仅对 file 输入类型有效。定义文件上传控件中可选的文件类型。

  • alpha:仅对 color 输入类型有效。允许用户设置所选颜色的不透明度。

  • autocomplete:一个空格分隔的字符串,描述输入框应提供何种类型的自动补全功能。

    • autocomplete 属性适用于 hiddentextsearchurltelemaildatemonthweektimedatetime-localnumberrangecolorpassword 类型。
  • checked:布尔属性,仅对 radiocheckbox 类型有效。

    • 若存在于 radio 类型上,表示该单选按钮是同名按钮组中当前被选中的那个。
    • 若存在于 checkbox 类型上,表示该复选框在页面加载时默认处于选中状态。
    • 复选框和单选按钮的值仅在其处于选中状态时才会被包含在提交的数据中。如果被选中,则提交已选中控件的 name 和对应的 value 值。
  • disabled:布尔属性,若存在,则表示用户不应能够与该输入控件交互。

    • 禁用状态的输入控件不会接收 click 事件,也不会随表单一起提交。
  • form:一个字符串,指定该输入框所关联的 <form> 元素。

    • 其值必须与同一文档中某个 <form> 元素的 id 相匹配。
    • 一个输入框只能关联到一个表单。
  • formaction:仅对 imagesubmit 输入类型有效。指定提交数据的 URL。

    • 该属性优先于所属 <form> 元素上的 action 属性。
  • formenctype:仅对 imagesubmit 输入类型有效。指定将表单数据提交到服务器时使用的编码方式。

    • 可选值:

      • application/x-www-form-urlencoded:默认值,使用类似 encodeURI() 的算法对文本进行百分号编码后,将表单数据作为字符串发送。
      • multipart/form-data:使用 FormData API 管理数据,支持将文件提交到服务器。如果表单包含 file 类型输入控件,则必须使用此编码类型。
      • text/plain:纯文本。主要用于调试,便于查看将要提交的数据。
    • 如果指定了此属性,formenctype 的值会覆盖所属表单的 enctype 属性。

  • formmethod:仅对 imagesubmit 输入类型有效。指定提交表单数据时使用的 HTTP 方法。

    • 可选值:

      • get:默认值,以 formactionaction 属性给出的 URL 开头,附加一个 ?,然后附加按 formenctype 或表单的 enctype 属性编码后的表单数据。随后使用 HTTP get 请求将该 URL 发送到服务器。此方法适用于仅包含 ASCII 字符且无副作用的表单。
      • post:表单数据包含在请求体中,通过 HTTP post 方法发送到 formactionaction 属性指定的 URL。此方法支持复杂数据和文件附件。
      • dialog:此方法用于表示该按钮会关闭输入框所关联的对话框,并且完全不发送表单数据。
    • 如果指定了此属性,formmethod 的值会覆盖所属表单的 method 属性。

  • formnovalidate:布尔属性,仅对 imagesubmit 输入类型有效。若存在,则表示在提交到服务器之前不应验证表单。

    • 该值会覆盖元素所属表单上的 novalidate 属性。
  • formtarget:仅对 imagesubmit 输入类型有效。指定提交表单后显示响应的位置。

    • 具体的取值和 <a> 元素的 target 属性保持一致。
    • 此处指定的值会覆盖所属 <form> 元素上的 target 属性。
  • list:其值应为同一文档中 <datalist> 元素的 id

    • 该属性适用于以下类型:textsearchurltelemaildatemonthweektimedatetime-localnumberrangecolor
  • max:定义允许值范围内的最大值。

    • 适用于 datemonthweektimedatetime-localnumberrange 类型。
  • maxlength:定义用户可输入的最大字符串长度。

    • 适用于 textsearchurltelemailpassword 类型。
  • min:定义允许值范围内的最小值。

    • 适用于 datemonthweektimedatetime-localnumberrange 类型。
  • minlength:定义用户可输入的最小字符串长度。

    • 适用于 textsearchurltelemailpassword 类型。
  • multiple:布尔属性,若设置,表示用户可以在电子邮件输入框中输入逗号分隔的多个邮箱地址,或者可以在文件输入框中选择多个文件。

  • name:必选,指定输入控件的名称。该名称在表单数据提交时会与控件的值一同发送。

    • 如果输入框未指定 name 属性,或 name 的值为空,则该输入框的值不会随表单提交。
    • 禁用控件、未选中的单选按钮、未选中的复选框以及重置按钮也不会被提交。
    • name 属性为单选按钮带来了独特的行为:
      • 同一 name 的单选按钮组中,一次只能选中一个单选按钮。
      • 选中该组中的任意单选按钮,会自动取消同组中当前已选中的其他单选按钮。
      • 提交表单时,被选中的那个单选按钮的值会随 name 一同发送。
  • pattern:编译一个正则表达式,输入框的值必须与之匹配才能通过约束验证。

    • 该值必须是一个有效的 JavaScript 正则表达式。
    • 编译正则表达式时:
      • 模式会被隐式包装为 ^(?:)$,即要求对整个输入值进行匹配,实际为 ^(?:<pattern>)$
    • 适用于 textsearchurltelemailpassword 类型。
  • placeholder:向用户提供关于字段预期输入内容的简短提示。

    • 适用于 textsearchurltelemailpasswordnumber 类型。
  • popovertarget:将 <input type="button"> 元素转换为弹出框的控制按钮。

    • 其值为要控制的弹出框元素的 ID。
  • popovertargetaction:指定要对由 <input type="button"> 控件控制的弹出框元素执行的操作。

    • 可选值:
      • hide:按钮将隐藏已显示的弹出框。
      • show:按钮将显示已隐藏的弹出框。
      • toggle:默认值,按钮将切换弹出框的显示与隐藏状态。
  • readonly:布尔属性,若存在,则表示用户不应能够编辑输入框的值。

    • 支持以下输入类型:textsearchurltelemaildatemonthweektimedatetime-localnumberpassword
  • required:布尔属性,若存在,则表示用户在所属表单提交之前必须为该输入框指定一个值。

    • 支持以下输入类型:textsearchurltelemaildatemonthweektimedatetime-localnumberpasswordcheckboxradiofile
  • step:指定输入字段的数值间隔或步长,它决定了用户通过微调按钮增减数值时的跳跃幅度。

    • 适用于 datemonthweektimedatetime-localnumberrange 类型。
  • type:指定要渲染的控件类型。

    • 可选值:
      • button:一个没有默认行为的按钮,显示 value 属性的值,默认为空。
      • checkbox:复选框,用于选择或取消选择单个值。
      • color:用于指定颜色的控件。
      • date:用于输入日期的控件。
      • datetime-local:用于输入本地日期和时间。
      • email:用于编辑电子邮件地址的字段。
      • file:允许用户选择文件的控件。可使用 accept 属性定义该控件可选择的文件类型。
      • hidden:不显示在页面上的控件,但其值会被提交到服务器。
      • month:用于输入月份和年份的控件。
      • number:用于输入数字的控件。显示微调按钮,并提供默认校验。
      • password:单行文本字段,其输入值会被遮蔽;如果站点不安全,会向用户发出提示。
      • radio:单选按钮,在具有相同 name 值的多个选项中仅允许选择一个。
      • range:用于输入一个不要求精确值的数字;默认显示为范围控件,初始值为中间值。
      • reset:将表单内容重置为默认值的按钮。不推荐使用。
      • search:用于输入搜索字符串的单行文本字段;输入值中的换行符会被自动移除。
      • submit:用于提交表单的按钮。
      • tel:用于输入电话号码的控件;在某些具备动态键盘的设备上会显示电话键盘。
      • text:默认,单行文本字段;输入值中的换行符会被自动移除。
      • time:用于输入时间值的控件。
      • url:用于输入 URL 的字段。
      • week:用于输入由周所属年份 + 周序号组成的日期值的控件。
  • value:输入控件的值。

    • 当在 HTML 中指定时,这是初始值。
    • value 属性始终是可选的,但对于 checkboxradiohidden 类型应视为必需。
  • title:解释匹配模式的要求(与 pattern 属性一起使用)。

使用示例

示例1:订阅套餐选择

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>订阅套餐选择</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <section class="container">
    <h1>选择您的订阅方案</h1>

    <form>
      <fieldset class="plans">
        <!-- 基础版 -->
        <label class="plan-card">
          <input type="radio" name="plan" value="basic" checked>
          <strong class="plan-name">基础版</strong>
          <p class="plan-price">
            <data value="29">¥29</data>
            <small>/月</small>
          </p>
          <ul class="plan-features">
            <li>5GB 存储空间</li>
            <li>基础功能访问</li>
            <li>邮件支持</li>
          </ul>
        </label>

        <!-- 专业版 -->
        <label class="plan-card">
          <input type="radio" name="plan" value="pro">
          <em class="plan-badge">推荐</em>
          <strong class="plan-name">专业版</strong>
          <p class="plan-price">
            <data value="79">¥79</data>
            <small>/月</small>
          </p>
          <ul class="plan-features">
            <li>50GB 存储空间</li>
            <li>全部高级功能</li>
            <li>7×24 在线支持</li>
            <li>API 接口访问</li>
          </ul>
        </label>

        <!-- 企业版 -->
        <label class="plan-card">
          <input type="radio" name="plan" value="enterprise">
          <strong class="plan-name">企业版</strong>
          <p class="plan-price">
            <data value="199">¥199</data>
            <small>/月</small>
          </p>
          <ul class="plan-features">
            <li>无限存储空间</li>
            <li>定制化解决方案</li>
            <li>专属客户经理</li>
            <li>SLA 服务保障</li>
          </ul>
        </label>
      </fieldset>

      <button type="submit">立即订阅</button>
    </form>
  </section>
</body>

</html>

示例2:模拟开关效果

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>模拟开关效果</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <section class="container">
    <h1>设置中心</h1>

    <ul class="settings-list">
      <li class="settings-item">
        <label class="switch">
          <input type="checkbox" class="switch-input" checked>
          <span class="switch-control" aria-hidden="true"></span>
          <span class="switch-label">深色模式</span>
        </label>
      </li>

      <li class="settings-item">
        <label class="switch">
          <input type="checkbox" class="switch-input">
          <span class="switch-control" aria-hidden="true"></span>
          <span class="switch-label">消息通知</span>
        </label>
      </li>

      <li class="settings-item">
        <label class="switch">
          <input type="checkbox" class="switch-input" checked>
          <span class="switch-control" aria-hidden="true"></span>
          <span class="switch-label">自动保存</span>
        </label>
      </li>

      <li class="settings-item">
        <label class="switch">
          <input type="checkbox" class="switch-input">
          <span class="switch-control" aria-hidden="true"></span>
          <span class="switch-label">定位服务</span>
        </label>
      </li>
    </ul>
  </section>
</body>

</html>

示例3:兴趣选择

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>兴趣选择</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <section class="container">
    <hgroup>
      <h1>选择你的兴趣</h1>
      <p>挑选至少 3 个感兴趣的领域</p>
    </hgroup>

    <form>
      <fieldset class="interests">
        <label class="interest-card">
          <input type="checkbox" name="interest" value="tech">
          <span class="interest-icon">💻</span>
          <data class="interest-name" value="tech">科技数码</data>
        </label>

        <label class="interest-card">
          <input type="checkbox" name="interest" value="design" checked>
          <span class="interest-icon">🎨</span>
          <data class="interest-name" value="design">设计创意</data>
        </label>

        <label class="interest-card">
          <input type="checkbox" name="interest" value="music">
          <span class="interest-icon">🎵</span>
          <data class="interest-name" value="entertainment">音乐影视</data>
        </label>

        <label class="interest-card">
          <input type="checkbox" name="interest" value="travel" checked>
          <span class="interest-icon">✈️</span>
          <data class="interest-name" value="travel">旅行探索</data>
        </label>

        <label class="interest-card">
          <input type="checkbox" name="interest" value="food">
          <span class="interest-icon">🍜</span>
          <data class="interest-name" value="food">美食烹饪</data>
        </label>

        <label class="interest-card">
          <input type="checkbox" name="interest" value="sports">
          <span class="interest-icon">⚽</span>
          <data class="interest-name" value="sports">运动健身</data>
        </label>

        <label class="interest-card">
          <input type="checkbox" name="interest" value="reading">
          <span class="interest-icon">📚</span>
          <data class="interest-name" value="reading">阅读写作</data>
        </label>

        <label class="interest-card">
          <input type="checkbox" name="interest" value="game">
          <span class="interest-icon">🎮</span>
          <data class="interest-name" value="gaming">游戏电竞</data>
        </label>
      </fieldset>

      <button type="submit">确认选择</button>
    </form>
  </section>
</body>

</html>

示例4:文件上传控件

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>文件上传控件</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <section class="container">
    <h1>上传文件</h1>

    <form>
      <!-- 拖拽上传区域 -->
      <label class="upload-zone">
        <input type="file" name="files" multiple accept="image/*,.pdf,.doc,.docx">
        <svg class="upload-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
          <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
          <polyline points="17 8 12 3 7 8"></polyline>
          <line x1="12" y1="3" x2="12" y2="15"></line>
        </svg>
        <p class="upload-text">点击或拖拽文件到此处上传</p>
        <small class="upload-hint">支持图片、PDF、Word 文档,单个文件不超过 10MB</small>
      </label>

      <button type="submit">开始上传</button>
    </form>
  </section>
</body>

</html>

示例5:滑块综合示例

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>滑块综合示例</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <section class="container">
    <h1>设置中心</h1>

    <form>
      <!-- 1. 基础滑块 - 音量控制 -->
      <fieldset class="slider-group">
        <label for="volume">音量控制</label>
        <div class="slider-wrap">
          <span class="slider-icon">🔇</span>
          <input type="range" id="volume" min="0" max="100" value="60">
          <span class="slider-icon">🔊</span>
        </div>
        <output for="volume">60%</output>
      </fieldset>

      <!-- 2. 星星评分 - 0.5步长(修复版) -->
      <fieldset class="slider-group rating-group">
        <label for="rating">服务评分</label>
        <div class="rating-wrap">
          <div class="stars-display" id="starsDisplay">
            <span class="star full">★</span>
            <span class="star full">★</span>
            <span class="star full">★</span>
            <span class="star half">★</span>
            <span class="star empty">★</span>
          </div>
          <input type="range" id="rating" min="0" max="5" step="0.5" value="3.5">
        </div>
        <output for="rating">3.5 分</output>
      </fieldset>

      <!-- 3. 字体大小调整 -->
      <fieldset class="slider-group">
        <label for="fontsize">字体大小</label>
        <div class="slider-wrap font-slider">
          <span class="font-small">A</span>
          <input type="range" id="fontsize" min="12" max="24" step="1" value="16">
          <span class="font-large">A</span>
        </div>
        <output for="fontsize">16px</output>
        <p class="preview-text" id="previewText">预览文字:这是一段示例文本</p>
      </fieldset>

      <button type="submit">保存设置</button>
    </form>
  </section>

  <script>
    // 音量滑块
    const volume = document.getElementById('volume');
    const volumeOut = document.querySelector('output[for="volume"]');
    volume.addEventListener('input', () => {
      volumeOut.textContent = volume.value + '%';
    });

    // 星星评分 - 修复版
    const rating = document.getElementById('rating');
    const ratingOut = document.querySelector('output[for="rating"]');
    const starsDisplay = document.getElementById('starsDisplay');

    function updateStars(value) {
      const num = parseFloat(value);
      const fullStars = Math.floor(num);
      const hasHalf = num % 1 === 0.5;

      let html = '';

      // 满星
      for (let i = 0; i < fullStars; i++) {
        html += '<span class="star full">★</span>';
      }

      // 半星
      if (hasHalf) {
        html += '<span class="star half">★</span>';
      }

      // 空星
      const emptyCount = 5 - fullStars - (hasHalf ? 1 : 0);
      for (let i = 0; i < emptyCount; i++) {
        html += '<span class="star empty">★</span>';
      }

      starsDisplay.innerHTML = html;
      ratingOut.textContent = num.toFixed(1) + ' 分';
    }

    rating.addEventListener('input', () => updateStars(rating.value));
    updateStars(rating.value);

    // 字体大小
    const fontsize = document.getElementById('fontsize');
    const fontsizeOut = document.querySelector('output[for="fontsize"]');
    const previewText = document.getElementById('previewText');

    fontsize.addEventListener('input', () => {
      fontsizeOut.textContent = fontsize.value + 'px';
      previewText.style.fontSize = fontsize.value + 'px';
    });
  </script>
</body>

</html>

示例6:datalist 综合示例

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>datalist 综合示例</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <section class="container">
    <h1>个人信息登记</h1>

    <form>
      <!-- 1. 邮箱动态匹配(JS生成选项) -->
      <fieldset>
        <label for="email">电子邮箱</label>
        <input type="email" id="email" name="email" placeholder="请输入邮箱账号" list="email-suffixes" autocomplete="off">
        <datalist id="email-suffixes">
          <!-- 选项由 JS 动态生成 -->
        </datalist>
      </fieldset>

      <!-- 2. 日期选择 -->
      <fieldset>
        <label for="birthday">出生日期</label>
        <input type="date" id="birthday" name="birthday" list="special-dates" min="1950-01-01" max="2026-12-31">
        <datalist id="special-dates">
          <option value="1990-01-01" label="90后典型">
          <option value="2000-01-01" label="千禧一代">
          <option value="1995-01-01" label="95后典型">
          <option value="1985-01-01" label="85后典型">
        </datalist>
        <small>可选择常用参考日期,或点击日历自选</small>
      </fieldset>

      <!-- 3. 国家/地区选择 -->
      <fieldset>
        <label for="country">国家/地区</label>
        <input type="text" id="country" name="country" placeholder="输入国家名称" list="countries" autocomplete="off">
        <datalist id="countries">
          <option value="中国" label="China">
          <option value="美国" label="United States">
          <option value="日本" label="Japan">
          <option value="韩国" label="South Korea">
          <option value="英国" label="United Kingdom">
          <option value="法国" label="France">
          <option value="德国" label="Germany">
          <option value="澳大利亚" label="Australia">
          <option value="加拿大" label="Canada">
          <option value="新加坡" label="Singapore">
          <option value="泰国" label="Thailand">
          <option value="马来西亚" label="Malaysia">
        </datalist>
      </fieldset>

      <button type="submit">提交信息</button>
    </form>
  </main>

  <script>
    // 邮箱动态匹配
    const email = document.querySelector("[type='email']")
    email.addEventListener("input", function () {
      const value = this.value.split("@")[0]
      const datalist = this.list
      const arr = ["qq.com", "gmail.com", "126.com", "163.com", "outlook.com", "icloud.com", "foxmail.com"]
      let html = ""
      arr.forEach(suffix => {
        html += `<option value="${value}@${suffix}">`
      })
      datalist.innerHTML = html
    })
  </script>
</body>

</html>

示例7:name 属性的重要性

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>name 属性的重要性</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <form id="feedbackForm">
    <h2>用户反馈</h2>

    <!-- 有 name 属性:数据会被提交 -->
    <div class="form-group">
      <label for="username">用户名(有 name)</label>
      <input type="text" id="username" name="username" value="张三">
    </div>

    <div class="form-group">
      <label for="email">邮箱(有 name)</label>
      <input type="email" id="email" name="email" value="zhangsan@example.com">
    </div>

    <!-- 无 name 属性:数据不会被提交! -->
    <div class="form-group">
      <label for="phone">电话(无 name)</label>
      <input type="text" id="phone" value="13800138000">
    </div>
    
    <div class="form-group">
      <label for="comment">留言内容(有 name)</label>
      <textarea id="comment" name="comment">产品很好用!</textarea>
    </div>

    <div class="hint">
      <strong>💡 关键知识点:</strong><br>
      只有带有 <code>name</code> 属性的表单控件,其值才会在表单提交时被发送到服务器。<br><br>
      上方"电话"字段没有 <code>name</code> 属性,所以即使用户填写了,数据也不会被提交!
    </div>

    <button type="submit">提交表单</button>
  </form>

  <script src="./js/main.js"></script>
</body>

</html>

示例8:复选框值的处理

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>复选框值的处理</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <form id="hobbyForm">
    <h2>您的兴趣爱好</h2>

    <fieldset>
      <legend>请选择(可多选):</legend>

      <label class="checkbox-card">
        <input type="checkbox" name="hobby" value="reading">
        <data value="read">📚 阅读</data>
      </label>

      <label class="checkbox-card">
        <input type="checkbox" name="hobby" value="music">
        <data value="music">🎵 音乐</data>
      </label>

      <label class="checkbox-card">
        <input type="checkbox" name="hobby" value="sports">
        <data value="sport">⚽ 运动</data>
      </label>

      <label class="checkbox-card">
        <input type="checkbox" name="hobby" value="travel">
        <data value="travel">✈️ 旅行</data>
      </label>

      <label class="checkbox-card">
        <input type="checkbox" name="hobby" value="gaming">
        <data value="game">🎮 游戏</data>
      </label>
    </fieldset>

    <!-- 结果显示区域 -->
    <div class="result-box">
      <h3>提交结果(控制台同步输出)</h3>
      <pre id="result">点击"提交"查看选中的 value 值...</pre>
    </div>

    <button type="submit">提交</button>
  </form>

  <script src="./js/main.js"></script>
</body>

</html>

示例9:表单验证与相关伪类

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>表单验证与相关伪类</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <form id="myForm">
    <h2>用户注册</h2>

    <!-- 必填:用户名 -->
    <div class="form-group">
      <label for="username">用户名</label>
      <input type="text" id="username" name="username" required minlength="2" maxlength="18" placeholder="张三">
      <p class="helper-text">支持字母、数字、下划线</p>
    </div>

    <!-- 必填:邮箱 -->
    <div class="form-group">
      <label for="email">邮箱</label>
      <input type="email" id="email" name="email" required placeholder="example@mail.com">
    </div>

    <!-- 必填:密码 -->
    <div class="form-group">
      <label for="password">密码</label>
      <input type="password" id="password" name="password" required minlength="6" placeholder="至少6位字符">
    </div>

    <!-- 可选:年龄(范围验证) -->
    <div class="form-group">
      <label for="age">年龄</label>
      <input type="number" id="age" name="age" min="18" max="120" placeholder="18-120">
      <p class="helper-text">必须年满18周岁</p>
    </div>

    <!-- 可选:网站 -->
    <div class="form-group">
      <label for="website">个人网站</label>
      <input type="url" id="website" name="website" placeholder="https://example.com">
    </div>

    <!-- 必填:下拉选择 -->
    <div class="form-group">
      <label for="country">国家/地区</label>
      <select id="country" name="country" required>
        <option value="" disabled selected>请选择</option>
        <option value="cn">中国</option>
        <option value="us">美国</option>
        <option value="uk">英国</option>
        <option value="jp">日本</option>
      </select>
    </div>

    <!-- 必填:文本域 -->
    <div class="form-group">
      <label for="bio">个人简介</label>
      <textarea id="bio" name="bio" required minlength="10" maxlength="200" placeholder="至少10个字符,最多200字"></textarea>
    </div>

    <!-- 可选:同意条款 -->
    <div class="checkbox-group">
      <input type="checkbox" id="newsletter" name="newsletter">
      <label for="newsletter">订阅邮件通知(可选)</label>
    </div>

    <button type="submit">提交注册</button>
  </form>

  <script src="./js/main.js"></script>
</body>

</html>

<button> 元素

描述

<button> 元素表示一个以其内容作为标签的按钮。

技术摘要
  • 类别

    • 流内容。

    • 短语内容。

    • 交互式内容。

    • 列出的、可标记的、可提交的、且继承 autocapitalizeautocorrect 特性的表单关联元素。

    • 可感知内容。

  • 此元素可使用的上下文

    • 在需要短语内容的地方。
    • 作为 <select> 元素的第一个子元素。
  • 内容模型

    • 短语内容,但不得包含交互式内容的后代,也不得包含带有 tabindex 属性的后代。
    • 如果该元素是 select 元素的第一个子元素,则还可以包含零个或一个 selectedcontent 元素作为后代。
属性
  • command:指定通过 commandfor 属性关联的 <button> 控件对所控制元素执行的操作。可选值:

    • show-modal:按钮将以模态方式显示 <dialog>
    • close:按钮将关闭 <dialog> 元素。与 value 属性配合使用时,按钮的值将作为对话框的 returnValue 属性传递。
    • request-close:按钮将在 <dialog> 元素上触发 cancel 事件以请求浏览器关闭对话框,随后触发 close 事件。与按钮的 value 属性配合使用时,该值将作为对话框的 returnValue 属性传递。
    • show-popover:按钮将显示隐藏的弹出框。
    • hide-popover:按钮将隐藏已显示的弹出框。
    • toggle-popover:按钮将切换弹出框的显示与隐藏状态。
  • commandfor:将 <button> 元素转换为命令按钮,通过按钮的 command 属性中指定的命令来控制给定的交互式元素。

  • disabled:布尔属性,如果存在,将阻止用户与按钮交互:按钮无法被按下或获得焦点。

  • form:与按钮关联的 <form> 元素。该属性的值必须是同一文档中某个 <form> 元素的 id

  • formaction:处理按钮提交信息的 URL。该值会覆盖按钮表单所有者的 action 属性。

  • formenctype:如果按钮是提交按钮,则指定提交表单数据时的编码方式。

    • 具体属性值请参考 form 元素的 enctype 属性。
    • 如果指定了此属性,它会覆盖按钮表单所有者的 enctype 属性。
  • formmethod:如果按钮是提交按钮,则指定提交表单时使用的 HTTP 方法。

    • 具体属性值请参考 form 元素的 method 属性。
    • 如果指定了此属性,它会覆盖按钮表单所有者的 method 属性。
  • formnovalidate:布尔属性,如果按钮是提交按钮,如果存在,表单在提交时不进行验证。

    • 如果指定了此属性,它会覆盖按钮表单所有者的 novalidate 属性。
  • formtarget:如果按钮是提交按钮,指定提交表单后响应的显示位置。

    • 具体属性值请参考 form 元素的 target 属性。
    • 如果指定了此属性,它会覆盖按钮表单所有者的 target 属性。
  • name:按钮的名称。当使用该按钮提交表单时,该名称会与按钮的 value 值作为一对数据随表单数据一起提交。

  • popovertarget:将 <button> 元素转换为弹出框的控制按钮。该属性的值为要控制的弹出框元素的 ID。

  • popovertargetaction:指定要对由 <button> 控件控制的弹出框元素执行的操作。可选值:

    • hide:按钮将隐藏已显示的弹出框。
    • show:按钮将显示已隐藏的弹出框。
    • toggle:默认,按钮将切换弹出框的显示与隐藏状态。
  • type:按钮的默认行为。可选值:

    • submit:按钮将表单数据提交到服务器。

      • 对于与 <form> 关联的按钮,如果未指定此属性,或属性值为空或无效,则此为默认行为。
    • reset:按钮将所有控件重置为其初始值。

    • button:按钮没有默认行为,按下时默认不执行任何操作。

  • value:定义按钮的 name 在随表单数据提交时所关联的值。

使用示例

示例1:command 属性的使用

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>command 属性的使用</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <div class="container">
    <h1>Command 属性演示</h1>

    <!-- 目标元素:被 commandfor 指向 -->
    <div id="targetBox">
      <p>测试文本</p>
    </div>

    <!-- 按钮组 -->
    <div class="buttons">
      <button type="button" command="toggle" commandfor="targetBox">切换显示</button>
      <button type="button" command="hide-popover" commandfor="targetBox">隐藏</button>
      <button type="button" command="show-popover" commandfor="targetBox">显示</button>
      <button type="button" command="show-modal" commandfor="infoDialog">打开对话框</button>
    </div>
  </div>

  <!-- 对话框目标元素 -->
  <dialog id="infoDialog">
    <p>对话框显示的内容</p>
    <button type="button" command="close" commandfor="infoDialog">关闭</button>
  </dialog>

  <script src="./js/main.js"></script>
</body>

</html>

示例2:图片弹窗效果

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>图片弹窗效果</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <!-- 触发按钮:popovertarget 指向目标元素 id -->
  <button popovertarget="imgPopover">
    🔍 查看图片
  </button>

  <!-- 弹窗容器:popover 属性使其成为弹出层 -->
  <div popover id="imgPopover">
    <span class="close-hint">点击任意处关闭</span>
    <img src="https://picsum.photos/800/600" alt="示例图片">
  </div>
</body>

</html>

示例3:手机验证码登录

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>手机验证码登录</title>
  <link rel="stylesheet" href="./index.css">
</head>

<body>
  <div class="container">
    <form action="/login" method="post" id="loginForm">
      <div class="form-group">
        <div class="input-wrapper">
          <input type="tel" name="tel" id="tel" placeholder="请输入手机号码" pattern="^1[3-9]\d{9}$" title="请输入11位手机号"
            required>
        </div>
      </div>

      <div class="form-group">
        <div class="code-wrapper">
          <input type="text" name="code" id="code" placeholder="请输入验证码" maxlength="6" pattern="^\d{6}$"
            title="请输入6位数字验证码" required>
          <button type="button" class="code-btn" id="getCodeBtn" formaction="/validity">获取验证码</button>
        </div>
        <div class="countdown" id="countdown"></div>
      </div>

      <button type="submit" class="login-btn" id="loginBtn">登录</button>
    </form>

    <div class="message" id="message"></div>
  </div>

  <script src="index.js"></script>
</body>

</html>

<select> 元素

描述

<select> 元素表示一个用于从一组选项中进行选择的控件。

技术摘要
  • 类别

    • 流内容。

    • 短语内容。

    • 交互式内容。

    • 列出的、可标记的、可提交的、可重置的、且继承 autocapitalizeautocorrect 特性的表单关联元素。

    • 可感知内容。

  • 此元素可使用的上下文:在需要短语内容的地方。

  • 内容模型 :如果下拉框为下拉列表形式,则可包含零个或一个 <button> 元素,其后跟随零个或多个 <select> 元素内部内容元素。

属性
  • autocomplete:一个字符串,为用户代理的自动补全功能提供提示。

  • disabled:布尔属性,如果存在,用户无法与该控件交互。

    • 如果未指定此属性,控件会从包含它的元素继承设置。
  • form:与 <select> 关联的 <form> 元素。该属性的值必须是同一文档中某个 <form> 元素的 id

  • multiple:布尔属性,如果存在,列表中可以同时选择多个选项。

  • name:指定控件的名称。

  • required:布尔属性,必须选中一个具有非空字符串值的选项。

  • size:列表中应同时可见的行数。只有出现 multiple 属性,此属性才有价值。

使用示例

示例1:占位选项功能

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>占位选项功能</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <div class="container">
    <hgroup>
      <h2>占位选项功能演示</h2>
      <p class="subtitle">请选择您的职业以继续</p>
    </hgroup>

    <form id="demoForm">
      <div class="form-group">
        <label for="job">您的职业</label>

        <select name="job" id="job" required>
          <!-- 占位选项 -->
          <option value="" disabled selected>请选择您的职业</option>

          <!-- 有效选项 -->
          <option value="frontend">前端工程师</option>
          <option value="backend">后端工程师</option>
          <option value="fullstack">全栈工程师</option>
          <option value="designer">UI/UX 设计师</option>
          <option value="pm">产品经理</option>
          <option value="student">学生</option>
          <option value="other">其他</option>
        </select>

        <!-- 状态提示 -->
        <small class="status pending" id="status">
          未选择:表单无法提交
        </small>
      </div>

      <button type="submit" id="submitBtn" disabled>确认提交</button>
    </form>
  </div>

  <script src="./js/main.js"></script>
</body>

</html>

示例2:optgroup 分组

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>optgroup 分组</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <div class="container">
    <hgroup>
      <h2>📂 产品分类选择</h2>
      <p class="subtitle">使用 optgroup 对选项进行分组展示</p>
    </hgroup>

    <form>
      <div class="form-group">
        <label for="product">选择产品类型</label>

        <select name="product" id="product" required>
          <!-- 占位选项 -->
          <option value="" disabled selected>请选择产品类型</option>

          <!-- 第一组:电子产品 -->
          <optgroup label="电子产品">
            <option value="smartphone">智能手机</option>
            <option value="laptop">笔记本电脑</option>
            <option value="tablet">平板电脑</option>
            <option value="headphone">耳机音响</option>
          </optgroup>

          <!-- 第二组:家用电器 -->
          <optgroup label="家用电器">
            <option value="tv">电视</option>
            <option value="fridge">冰箱</option>
            <option value="washer">洗衣机</option>
            <option value="ac">空调</option>
          </optgroup>
        </select>
      </div>

      <button type="submit">确认选择</button>
    </form>
  </div>

  <script src="./js/main.js"></script>
</body>

</html>

<datalist> 元素

描述

<datalist> 元素用于表示一组 <option> 元素,这些元素为其他控件提供预定义的选项。

技术摘要
  • 类别

    • 流内容。

    • 短语内容。

  • 此元素可使用的上下文:在需要短语内容的地方。

  • 内容模型 :短语内容或零个或多个 <option> 元素以及脚本支持元素。

使用示例

示例1:预定义的选项

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>预定义的选项</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <div class="container">
    <hgroup>
      <h2>datalist 经典示例</h2>
      <p class="subtitle">输入时自动提示,可自由选择或输入新值</p>
    </hgroup>

    <form id="searchForm">
      <!-- 示例1:搜索建议 -->
      <div class="form-group">
        <label for="search">搜索关键词</label>
        <input type="text" id="search" name="search" placeholder="输入或选择搜索词..." list="search-suggestions"
          autocomplete="off">
        <datalist id="search-suggestions">
          <option value="HTML5 新特性">
          <option value="CSS Flexbox 布局">
          <option value="JavaScript ES6">
          <option value="React 入门教程">
          <option value="Vue.js 组件开发">
          <option value="Node.js 后端开发">
          <option value="TypeScript 基础">
          <option value="Webpack 配置指南">
        </datalist>
      </div>

      <!-- 示例2:城市选择 -->
      <div class="form-group">
        <label for="city">所在城市</label>
        <input type="text" id="city" name="city" placeholder="输入或选择城市..." list="cities">
        <datalist id="cities">
          <option value="北京">
          <option value="上海">
          <option value="广州">
          <option value="深圳">
          <option value="杭州">
          <option value="成都">
          <option value="武汉">
          <option value="西安">
          <option value="南京">
          <option value="重庆">
        </datalist>
      </div>

      <!-- 示例3:颜色选择(带 value) -->
      <div class="form-group">
        <label for="color">主题颜色</label>
        <input type="text" id="color" name="color" placeholder="选择或输入颜色..." list="colors">
        <datalist id="colors">
          <option value="#6366f1" label="靛蓝">
          <option value="#10b981" label="翠绿">
          <option value="#f59e0b" label="琥珀">
          <option value="#ef4444" label="红色">
          <option value="#8b5cf6" label="紫色">
          <option value="#ec4899" label="粉色">
        </datalist>
      </div>

      <button type="submit">提交</button>
    </form>
  </div>

  <script src="./js/main.js"></script>
</body>

</html>

<optgroup> 元素

描述

<optgroup> 元素用于表示一组具有共同标签的 <option> 元素。

技术摘要
  • 类别<select> 元素的内部内容元素。

  • 此元素可使用的上下文 :作为 <select> 元素的后代元素。

  • 内容模型 :零个或一个 <legend> 元素,其后是零个或多个 <optgroup> 元素的内部内容元素。

属性
  • disabled:布尔属性,若存在,则该选项组中的所有选项都不可被选择。
  • label:必选,选项组的名称,浏览器可在用户界面中使用该名称对组选项进行标注。

<option> 元素

描述

<option> 元素用于表示 <select> 元素中的一个选项,或作为 <datalist> 元素中建议列表的一部分。

技术摘要
  • 类别

    • <select> 元素的内部内容元素。

    • <optgroup> 元素的内部内容元素。

  • 此元素可使用的上下文

    • 作为 <select> 元素的后代元素。
    • 作为 <datalist> 元素的后代元素。
    • 作为 <optgroup> 元素的后代元素。
  • 内容模型

    • 如果元素同时包含 label 属性和 value 属性: 无内容。
    • 如果元素包含 label 属性但没有 value 属性: 文本内容。
    • 如果元素没有 label 属性且不是 <datalist> 元素的后代:零个或多个 option 元素内部内容元素。
    • 如果元素没有 label 属性且是 <datalist> 元素的后代: 文本内容。
属性
  • disabled:布尔属性,如果存在,则该选项不可被选中。
  • label:说明选项含义的标签文本。如果未定义 label 属性,其值则为元素内的文本内容。
  • selected:布尔属性,如果存在,表示该选项在初始状态下处于选中状态。
  • value:此属性的内容表示选中该选项时随表单提交的值。
    • 如果省略此属性,则取值自 <option> 元素的文本内容。

<textarea> 元素

描述

<textarea> 元素表示一个多行纯文本编辑控件,用于编辑该元素的原始值。

技术摘要
  • 类别

    • 流内容。

    • 短语内容。

    • 交互式内容。

    • 列出的、可标记的、可提交的、可重置的、且继承 autocapitalizeautocorrect 特性的表单关联元素。

    • 可感知内容。

  • 此元素可使用的上下文:在需要短语内容的地方。

  • 内容模型:文本。

属性
  • autocomplete:控制浏览器是否可自动补全输入的文本。可选值:

    • off:浏览器不会自动补全条目。
    • on:浏览器可以根据用户之前使用中输入的值自动补全。
  • disabled:布尔属性,如果存在,表示用户无法与该控件交互。

  • form:与 <textarea> 元素关联的表单元素。该属性的值必须是同一文档中某个表单元素的 id

  • maxlength:用户可输入的最大字符串长度。如果未指定此值,用户可以输入无限数量的字符。

  • minlength:用户应输入的最小字符串长度。

  • name:控件的名称。

  • placeholder:向用户提示控件中可输入内容的示例。

  • readonly:布尔属性,若存在,表示用户无法修改控件的值。

    • readonly 属性不会阻止用户点击或选择控件。只读控件的值仍会随表单提交。
  • required:布尔属性,若存在,用户在提交表单之前必须填写一个值。

使用示例

示例1:多行文本输入框

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>多行文本输入框</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <div class="container">
    <h2>Textarea 元素示例</h2>
    <p class="subtitle">多行文本输入控件</p>

    <form id="commentForm">
      <!-- 基础文本域 -->
      <div class="form-group">
        <label for="comment">发表评论</label>
        <textarea id="comment" name="comment" class="basic" placeholder="请输入您的评论..." minlength="10" maxlength="500"
          required></textarea>
        <div class="char-counter" id="counter">
          <span>最少10字</span>
          <span id="charCount">0 / 500</span>
        </div>
      </div>

      <!-- 固定尺寸文本域 -->
      <div class="form-group">
        <label for="signature">个性签名(固定高度)</label>
        <textarea id="signature" name="signature" class="fixed" placeholder="一句话介绍自己..." maxlength="50"></textarea>
      </div>

      <!-- 只读文本域 -->
      <div class="form-group">
        <label for="template">模板内容(只读)</label>
        <textarea id="template" name="template" class="basic" readonly>尊敬的用户:

感谢您的反馈,我们会尽快处理。

客服团队</textarea>
      </div>

      <button type="submit">提交</button>
    </form>
  </div>

  <script src="./js/main.js"></script>
</body>

</html>

<output> 元素

描述

<output> 元素表示应用程序执行计算的结果,或用户操作的结果。

技术摘要
  • 类别

    • 流内容。

    • 短语内容。

    • 列出的、可标记的、可重置的、且继承 autocapitalize 和 autocorrect 特性的表单关联元素。

    • 可感知内容。

  • 此元素可使用的上下文:在需要短语内容的地方。

  • 内容模型:短语内容。

属性
  • for:一个空格分隔的其他元素的 id 列表,表示这些元素为计算提供了输入值。
  • from:与 <output> 关联的 <form> 元素。该属性的值必须是同一文档中某个 <form> 元素的 id
  • name:元素的名称。
    • <output> 的值、名称和内容在表单提交时不会被提交。
使用示例

示例1:实时汇率转换

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>实时汇率转换</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <div class="container">
    <hgroup>
      <h2>实时汇率转换</h2>
      <p class="subtitle">使用 output 元素展示计算结果</p>
    </hgroup>

    <form id="converter" oninput="calculate()">

      <!-- 输入金额 -->
      <div class="form-group">
        <label for="amount">输入金额</label>
        <input type="number" id="amount" name="amount" value="100" min="0" step="0.01" placeholder="10">
      </div>

      <!-- 源货币 -->
      <div class="form-group">
        <label for="fromCurrency">从</label>
        <select id="fromCurrency" name="fromCurrency">
          <option value="CNY" selected>🇨🇳 人民币 CNY</option>
          <option value="USD">🇺🇸 美元 USD</option>
          <option value="EUR">🇪🇺 欧元 EUR</option>
          <option value="JPY">🇯🇵 日元 JPY</option>
          <option value="GBP">🇬🇧 英镑 GBP</option>
        </select>
      </div>

      <!-- 交换按钮 -->
      <button type="button" class="swap-btn" onclick="swapCurrencies()">⇅</button>

      <!-- 目标货币 -->
      <div class="form-group">
        <label for="toCurrency">转换为</label>
        <select id="toCurrency" name="toCurrency">
          <option value="CNY">🇨🇳 人民币 CNY</option>
          <option value="USD" selected>🇺🇸 美元 USD</option>
          <option value="EUR">🇪🇺 欧元 EUR</option>
          <option value="JPY">🇯🇵 日元 JPY</option>
          <option value="GBP">🇬🇧 英镑 GBP</option>
        </select>
      </div>

      <!-- 汇率信息 -->
      <div class="rate-info">
        <span>当前汇率</span>
        <output name="rate" id="rateDisplay">1 CNY = 0.138 USD</output>
      </div>

      <!-- 转换结果 -->
      <div class="form-group">
        <label for="result">转换结果</label>
        <output id="result" name="result" for="amount fromCurrency toCurrency">
          13.80
        </output>
      </div>

      <button type="submit">提交记录</button>
    </form>
  </div>

  <script src="./js/main.js"></script>
</body>

</html>

<progress> 元素

描述

<progress> 元素用于表示某项任务的完成进度。

技术摘要
  • 类别

    • 流内容。

    • 短语内容。

    • 可标注元素。

    • 可感知内容。

  • 此元素可使用的上下文:在需要短语内容的地方。

  • 内容模型 :短语内容,但不得包含 <progress> 元素的后代。

属性
  • value:指定已完成的任务量。

    • 其值必须是介于 0max 之间的有效浮点数;
    • 如果省略 max,则介于 01 之间。
    • 如果没有 value 属性,则进度条处于不确定状态,表示活动正在进行中,无法预计还需多长时间完成。
  • max:描述 progress 元素所表示的任务总量。

    • 如果存在 max 属性,其值必须大于 0 且为有效的浮点数。默认值为 1。
使用示例

示例1:文件上传

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>文件上传</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <div class="container">
    <!-- 上传区域 -->
    <div class="upload-area" id="uploadArea">
      <div class="upload-icon">📁</div>
      <p class="upload-text">选择文件开始上传</p>
      <input type="file" id="fileInput" accept="*/*">
      <button class="upload-btn" onclick="document.getElementById('fileInput').click()">
        选择文件
      </button>
    </div>

    <!-- 文件信息和进度 -->
    <div class="file-info" id="fileInfo">
      <div class="file-name" id="fileName">example.pdf</div>
      <div class="file-size" id="fileSize">2.5 MB</div>
      <progress id="uploadProgress" max="100" value="0"></progress>

      <div class="progress-info">
        <span id="uploadedSize">0 MB / 2.5 MB</span>
        <span class="progress-percent" id="percentText">0%</span>
      </div>
    </div>

    <!-- 状态提示 -->
    <div class="status" id="status"></div>
  </div>

  <script src="./js/main.js"></script>
</body>

</html>
注意事项
  • 可以使用 :indeterminate 伪类来匹配不确定型进度条。

<meter> 元素

描述

<meter> 元素表示已知范围内的标量测量值或分数值。

技术摘要
  • 类别

    • 流内容。

    • 短语内容。

    • 可标注元素。

    • 可感知内容。

  • 此元素可使用的上下文:在需要短语内容的地方。

  • 内容模型 :短语内容,但不得包含 <meter> 元素的后代。

属性
  • value:当前的数值。

    • 如果指定了最小值和最大值,则该值必须介于两者之间。
    • 如果未指定或格式错误,则值为 0
    • 如果指定了值但不在 minmax 定义的范围内,则该值等于范围中较近的端点。
  • min:测量范围的下限数值。

    • 如果指定了最大值,则此值必须小于最大值。如果未指定,最小值为 0。
  • max:测量范围的上限数值。

    • 如果指定了最小值,则此值必须大于最小值。如果未指定,最大值为 1。
  • low:测量范围中低区间的上限数值。

    • 此值必须大于最小值,并且如果指定了高值和最大值,则必须分别小于这两者。
    • 如果未指定,或小于最小值,则 low 值等于最小值。
  • high:测量范围中高区间的下限数值。

    • 此值必须小于最大值,并且如果指定了低值和最小值,则必须分别大于这两者。
    • 如果未指定,或大于最大值,则 high 值等于最大值。
  • optimum:最优数值。

    • 它必须落在范围内(由 min 属性和 max 属性定义)。
    • low 属性和 high 属性配合使用时,用于指示范围内哪一段被认为是更优的。
使用示例

示例1:不同场景的使用

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>不同场景的使用</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <div class="container">
    <!-- 场景1:磁盘使用率(值越小越好) -->
    <div class="scenario">
      <div class="scenario-title">💾 磁盘使用率(值越小越好)</div>
      <meter min="0" max="100" low="60" high="80" optimum="0" value="85"></meter>
    </div>

    <!-- 场景2:电池电量(值越大越好) -->
    <div class="scenario">
      <div class="scenario-title">🔋 电池电量(值越大越好)</div>
      <meter min="0" max="100" low="20" high="50" optimum="100" value="30"></meter>
    </div>

    <!-- 场景3:成绩评分(中间值最好) -->
    <div class="scenario">
      <div class="scenario-title">🎯 成绩评分(80分最理想)</div>
      <meter min="0" max="100" low="60" high="85" optimum="80" value="80"></meter>
    </div>
  </div>
</body>

</html>

示例2:密码强度验证

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8">
    <title>密码强度验证</title>
    <link rel="stylesheet" href="./css/main.css">
  </head>
  <body>
    <div class="card">
      <form id="form">
        <div class="field">
          <label for="username">用户名:</label>
          <input id="username" name="username" type="text" autocomplete="username" />
        </div>

        <div class="field">
          <label for="pwd">密码:</label>
          <input id="pwd" name="password" type="password" autocomplete="new-password" />
        </div>

        <div class="meterBox">
          <meter id="meter" min="0" max="12" low="4" high="8" optimum="10" value="0"></meter>
          <output></output>
          <div class="scale" id="scale">
            <span class="weak">弱</span>
            <span class="mid">中</span>
            <span class="strong">强</span>
          </div>
        </div>

        <button type="submit">提交</button>
      </form>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/zxcvbn@4.4.2/dist/zxcvbn.js"></script>
    <script src="./js/script.js"></script>
  </body>
</html>

<fieldset> 元素

描述

<fieldset> 元素表示一组被归类在一起的表单控件,并且可以选择性地带有说明文字。

技术摘要
  • 类别

    • 流内容。

    • 列出的、且继承 autocapitalize 和 autocorrect 特性的表单关联元素。

    • 可感知内容。

  • 此元素可使用的上下文:在需要流内容的地方。

  • 内容模型 :可选地包含一个 legend 元素,后接流内容。

属性
  • disabled:布尔属性,若存在,则 <fieldset> 后代中的所有表单控件都将被禁用。

    • <legend> 元素内的表单元素不会被禁用。
  • form:将 <fieldset><form> 元素进行关联,该属性的值必须是同一文档中某个 <form> 元素的 id

  • name:与该分组关联的名称。

使用示例

示例1:控件分组

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8">
    <title>控件分组</title>
    <link rel="stylesheet" href="./css/style1.css">
  </head>

  <body>
    <form>
      <fieldset>
        <legend>你有台胞证吗?</legend>
        <input type="radio" id="yes" name="papers">
        <label for="yes">有</label>
        <input type="radio" id="no" name="papers" checked>
        <label for="no">没有</label>
      </fieldset>
    </form>
  </body>
</html>

示例2:批量禁用

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>Fieldset 批量禁用</title>
  <link rel="stylesheet" href="./css/style2.css">
</head>

<body>
  <form>
    <h2>收货地址</h2>

    <!-- 开关控制 -->
    <label class="toggle">
      <input type="checkbox" id="sameAddress" checked onchange="toggleAddress()">
      <span>使用默认地址</span>
    </label>

    <!-- 批量禁用的 fieldset -->
    <fieldset id="addressForm">
      <legend>新建地址</legend>

      <div class="form-group">
        <label for="name">收货人</label>
        <input type="text" id="name" placeholder="请输入姓名">
      </div>

      <div class="form-group">
        <label for="phone">手机号</label>
        <input type="tel" id="phone" placeholder="请输入手机号">
      </div>

      <div class="form-group">
        <label for="city">城市</label>
        <select id="city">
          <option value="">请选择</option>
          <option value="beijing">北京</option>
          <option value="shanghai">上海</option>
          <option value="guangzhou">广州</option>
        </select>
      </div>

      <div class="form-group">
        <label for="detail">详细地址</label>
        <input type="text" id="detail" placeholder="街道、门牌号">
      </div>
    </fieldset>

    <button type="submit">保存</button>
  </form>

  <script src="./js/main.js"></script>
</body>

</html>

<legend> 元素

描述

<legend> 元素表示其父级 <fieldset> 元素其余内容的标题。否则,如果 <legend> 的父元素是 <optgroup>,则该 <legend> 表示 <optgroup> 的标签。

技术摘要
  • 类别:无。

  • 此元素可使用的上下文

    • 作为 <fieldset> 元素的第一个子元素。
    • 作为 <optgroup> 元素的第一个子元素。
  • 内容模型

    • 如果该元素是 <optgroup> 元素的子元素:短语内容,但不得包含交互式内容,也不得包含带有 tabindex 属性的后代元素。
    • 其他情况:短语内容,可选择性地与标题内容混合出现。

交互式元素

<details> 元素

描述

<details> 元素表示一个交互式展开组件,用户可通过它获取额外信息或控件。

技术摘要
  • 类别

    • 流内容。

    • 交互式内容。

    • 可感知内容。

  • 此元素可使用的上下文:在需要流内容的地方。

  • 内容模型 :一个 <summary> 元素,后跟流内容。

属性
  • name:指定组名,为多个 <details> 元素赋予相同的 name 值即可将它们归为一组。同一组中一次只能展开一个 <details> 元素,展开其中一个会导致另一个关闭。

    • 如果同一组中有多个 <details> 元素被赋予 open 属性,只有源顺序中的第一个会以展开状态呈现。
  • open:布尔属性,若存在,展开详细信息。

使用示例

示例1:展开更多/收起

html 复制代码
<!DOCTYPE html>
<html lang="zh">

<head>
  <meta charset="UTF-8">
  <title>文章展开收起</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <article class="card">
    <header>
      <p class="meta">
        <mark>设计思维</mark>
        <time>8 分钟阅读</time>
      </p>
      <h1>留白与呼吸:现代网页设计中的负空间艺术</h1>
      <address>
        <img src="./img/avatar.jpg" alt="图像" class="author-avatar">
        <div class="author-details">
          <span class="author-name">林清风</span>
          <time class="publish-date" datetime="2026-03-28">2026年3月28日</time>
        </div>
      </address>
    </header>
    <hr>
    <!-- 展开收起区域 -->
    <details id="article-details">
      <summary>
        <p class="lead">在信息过载的数字时代,优秀的设计往往不在于添加多少元素,而在于懂得何时不做任何事。留白------这个被误解为"空白浪费"的设计要素,实则是引导视线、建立层次、创造优雅体验的关键力量。</p>
        <button type="button" class="expand-btn">阅读全文</button>
      </summary>

      <!-- 使用 section 标记主要内容区域 -->
      <section class="content">
        <p>当我们浏览一个网页时,眼睛会本能地寻找休息的地方。这些休息点,就是设计师精心布置的留白。它们不是设计的缺席,而是设计本身------是内容之间的呼吸空间,是视觉节奏的休止符。</p>

        <h2>留白的科学</h2>

        <p>
          研究表明,适当的留白可以<strong>提高20%的阅读理解率</strong>。当文字周围有足够的空间时,读者的眼睛可以更轻松地追踪行距,大脑也能更好地处理信息。这就是为什么高端杂志总是看起来比廉价传单更易读------不是因为字体更贵,而是因为<em>空间更奢侈</em>。
        </p>

        <blockquote>
          <p>完美不是加无可加,而是减无可减。</p>
          <cite>------ 安托万·德·圣埃克苏佩里</cite>
        </blockquote>

        <h2>层次与节奏</h2>

        <p>留白创造了视觉层次。通过调整元素之间的距离,我们可以暗示它们之间的关系:相近的元素被视为一组,远离的元素则形成区隔。这种<strong>"邻近性原则"</strong>是格式塔心理学的核心,也是所有排版设计的基础。
        </p>

        <p>在网页设计中,我们使用不同权重的留白来建立节奏。大段之间的空白(宏观留白)让内容模块化,行距和字间距(微观留白)则确保阅读的舒适性。一个经验丰富的设计师会像作曲家安排音符一样安排这些空间。</p>

        <h2>少即是多的美学</h2>

        <p>苹果公司的设计哲学深刻影响了整个行业。他们的产品页面往往是大面积的留白配合精炼的文案和一张产品图。这种<em>少即是多</em>的美学不是偷懒,而是对自信的表达------当品牌足够强大时,它不需要用噪音来证明自己的存在。
        </p>

        <p>然而,留白的使用需要克制和平衡。过多的留白会让页面显得空洞,过少则会造成压迫感。找到那个平衡点,是设计师经验与直觉的体现。</p>

        <button type="button" class="collapse-btn"
          onclick="document.getElementById('article-details').removeAttribute('open')">收起内容</button>
      </section>
    </details>

    <footer>
      <div class="tags">
        <span class="tag">UI设计</span>
        <span class="tag">排版</span>
        <span class="tag">用户体验</span>
      </div>
      <small>© 2026 设计周刊</small>
    </footer>
  </article>
</body>

</html>

示例2:悬浮菜单

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>悬浮菜单</title>
  <link rel="stylesheet" href="./css/style.css">
</head>
<body>
  <nav class="nav">
    <div class="nav-brand">管理系统</div>

    <div class="tools">
      <details name="nav-item">
        <summary>消息中心</summary>
        <menu>
          <li><a href="#">评论回复 <span class="badge">3</span></a></li>
          <li><a href="#">系统通知 <span class="badge">12</span></a></li>
          <li><a href="#">私信</a></li>
          <hr>
          <li><a href="#">全部已读</a></li>
        </menu>
      </details>

      <details name="nav-item">
        <summary>用户管理</summary>
        <menu>
          <li><a href="#">用户列表</a></li>
          <li><a href="#">权限设置</a></li>
          <li><a href="#">操作日志</a></li>
        </menu>
      </details>
    </div>

    <div class="role">
      <details name="nav-item">
        <summary>管理员</summary>
        <menu>
          <li><a href="#">个人资料</a></li>
          <li><a href="#">修改密码</a></li>
          <hr>
          <li><a href="#">退出登录</a></li>
        </menu>
      </details>
    </div>
  </nav>
</body>
</html>

示例3:折叠菜单

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>折叠菜单</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <nav class="sidebar">
    <details name="accordion" open>
      <summary>
        <span class="title">订单中心</span>
      </summary>
      <div class="content">
        <ul>
          <li><a href="#" class="active">我的订单</a></li>
          <li><a href="#">我的活动</a></li>
          <li><a href="#">评价晒单</a></li>
          <li><a href="#">购物助手</a></li>
        </ul>
      </div>
    </details>

    <details name="accordion">
      <summary>
        <span class="title">关注中心</span>
      </summary>
      <div class="content">
        <ul>
          <li><a href="#">关注的商品</a></li>
          <li><a href="#">关注的店铺</a></li>
          <li><a href="#">关注的专辑</a></li>
          <li><a href="#">收藏的内容</a></li>
        </ul>
      </div>
    </details>

    <details name="accordion">
      <summary>
        <span class="title">资产中心</span>
      </summary>
      <div class="content">
        <ul>
          <li><a href="#">余额</a></li>
          <li><a href="#">优惠券</a></li>
          <li><a href="#">礼品卡</a></li>
        </ul>
      </div>
    </details>
  </nav>
</body>

</html>

示例4:Q&A 问答

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>Q&A 问答</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <div class="container">
    <h1>常见问题</h1>
    <div class="faq-list">
      <details name="faq" open>
        <summary>
          <span class="question">如何重置我的密码?</span>
        </summary>
        <p class="answer">
          您可以在登录页面点击"忘记密码"链接,输入注册邮箱后,我们会发送重置链接到您的邮箱。点击链接即可设置新密码。如果您没有收到邮件,请检查垃圾邮件文件夹或联系客服。
        </p>
      </details>

      <details name="faq">
        <summary>
          <span class="question">支持哪些支付方式?</span>
        </summary>
        <p class="answer">
          我们目前支持支付宝、微信支付、银联卡以及主流信用卡(Visa、MasterCard)。企业用户还可以选择对公转账方式,具体请联系商务团队获取付款账户信息。
        </p>
      </details>

      <details name="faq">
        <summary>
          <span class="question">如何申请退款?</span>
        </summary>
        <p class="answer">
          购买后 7 天内且服务未使用的情况下,您可以在"订单中心"提交退款申请。审核通过后,款项将在 3-5 个工作日内原路退回。已使用的服务或超过 7 天的订单不支持退款。
        </p>
      </details>

      <details name="faq">
        <summary>
          <span class="question">如何联系客服支持?</span>
        </summary>
        <p class="answer">
          您可以通过以下方式联系我们:在线客服(工作日 9:00-18:00)、客服邮箱 support@example.com(24 小时内回复)、或拨打客服热线 400-123-4567。紧急问题建议优先使用在线客服。
        </p>
      </details>

      <details name="faq">
        <summary>
          <span class="question">是否提供发票?</span>
        </summary>
        <p class="answer">
          是的,我们提供增值税普通发票和专用发票。您可以在支付完成后进入"发票管理"页面提交开票申请,填写正确的企业税号等信息。电子发票将在 1-3 个工作日内发送至您的邮箱。
        </p>
      </details>
    </div>
  </div>
</body>

</html>

示例5:::details-content 动画

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>::details-content 动画</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <div class="container">
    <h1>常见问题</h1>

    <details open name="q&a">
      <summary>如何修改账户信息?</summary>
      <div class="content">
        进入"个人中心" > "账户设置",您可以修改昵称、头像、绑定手机等信息。
      </div>
    </details>

    <details name="q&a">
      <summary>退款需要多久到账?</summary>
      <div class="content">
        <p>退款到账时间取决于您的支付方式:</p>
        <p>• 支付宝/微信:1-3个工作日</p>
        <p>• 银行卡:3-7个工作日</p>
        <p>• 信用卡:5-15个工作日</p>
        <p>具体以银行实际处理时间为准,节假日可能顺延。</p>
      </div>
    </details>

    <details name="q&a">
      <summary>如何联系客服?</summary>
      <div class="content">
        <p>我们提供多种客服渠道:</p>
        <p>在线客服:工作日 9:00-18:00</p>
        <p>客服热线:400-123-4567</p>
        <p>邮件支持:support@example.com(24小时内回复)</p>
        <p>紧急问题建议优先使用在线客服,可获得即时响应。</p>
      </div>
    </details>
  </div>

</body>

</html>

<summary> 元素

描述

<summary> 元素用于表示其父 <details> 元素其余内容的摘要、标题或图例说明。

技术摘要
  • 类别:无。

  • 此元素可使用的上下文 :作为 <details> 元素的第一个子元素。

  • 内容模型:短语内容,可选择性地与标题内容混合出现。

<dialog> 元素

描述

<dialog> 元素表示应用程序中的一个临时部分,通常以小窗口(对话框)的形式呈现,供用户进行交互以完成某项任务或获取信息。当用户完成操作后,对话框可以由应用程序自动关闭,也可以由用户手动关闭。

技术摘要
  • 类别:流内容。

  • 此元素可使用的上下文:在需要流内容的地方。

  • 内容模型:流内容。

属性
  • closedby:指定可用于关闭 <dialog> 元素的用户操作类型。

    • 对话框可能被关闭的三种方式:

      • 轻触关闭:用户点击或轻触对话框外部区域时关闭 <dialog>
      • 平台特定操作:例如桌面平台上的 Esc 键,或移动平台上的"返回"或"关闭"手势。
      • 开发者指定的机制:例如包含调用 HTMLDialogElement.close() 的点击处理程序的 <button> 按钮,或 <form> 提交。
    • 可选值:

      • any:对话框可以通过上述三种方式中的任意一种关闭。
      • closerequest:对话框可以通过平台特定操作或开发者指定的机制关闭。
      • none:对话框只能通过开发者指定的机制关闭。
    • 如果 <dialog> 元素未指定有效的 closedby 值,则:

      • 若通过 showModal() 打开,其行为如同该值为 "closerequest"
      • 否则,其行为如同该值为 "none"
  • open:布尔属性,表示对话框处于活动状态且可供交互。

    • 如果通过 open 属性打开 <dialog>,则该对话框是非模态的。
使用示例

示例1:关闭对话框

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>关闭对话框</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <button class="btn" onclick="document.getElementById('demoDialog').showModal()">
    打开弹窗
  </button>

  <dialog id="demoDialog">
    <div class="dialog-header">提示</div>
    <div class="dialog-body">
      操作已成功完成。
    </div>
    <div class="dialog-footer">
      <form method="dialog">
        <button class="btn">我知道了</button>
      </form>
    </div>
  </dialog>
</body>

</html>

示例2:关闭来源的判断

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>关闭来源的判断</title>
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <button class="btn">打开对话框</button>
  <dialog>
    <div class="dialog-body">
      <form id="myForm">
        <p><input type="text" placeholder="请输入姓名" required></p>
      </form>
    </div>
    <div class="dialog-footer">
      <form>
        <button type="submit" form="myForm" class="btn-primary">确定</button>
        <button formmethod="dialog" value="cancel" class="btn-default">取消</button>
      </form>
    </div>
  </dialog>

  <script src="./js/main.js"></script>
</body>
</html>
注意事项
  • 如果 <form> 元素设置了 method="dialog" 属性,或用于提交该表单的按钮设置了 formmethod="dialog",则可以用于关闭对话框。
  • <dialog> 内部的 <form> 通过 dialog 方式提交时,对话框会被关闭;表单控件的状态会被保留,但不会实际提交;同时,returnValue 属性会被设置为被触发按钮的值。
  • 弹窗显示后,浏览器的焦点会自动聚焦到弹窗内(第一个能够聚焦的元素)。
  • 如果一个页面中有多个弹窗通过 showModal() 方法显示,后显示的弹窗层级最高。

popover 属性

描述

popover 全局属性用于将元素指定为弹出框元素。

取值
  • auto:默认值,支持轻触关闭,可以通过点击弹出框外部或按 Esc 键来隐藏它。
    • 显示一个 auto 弹出框通常会关闭其他已显示的 auto 弹出框。
  • hint:在显示时不会关闭 auto 弹出框,但会关闭其他 hint 弹出框。
    • 它们支持轻触关闭,并且会响应关闭请求。
  • manual:不支持轻触关闭,也不会自动关闭。
    • 弹出框必须通过声明式的显示/隐藏/切换按钮或 JavaScript 来显式显示和关闭。
    • 多个独立的 manual 弹出框可以同时显示。
使用示例

示例1:模拟下拉框

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <title>使用 popover 实现下拉菜单</title>
  <link rel="stylesheet" href="font/iconfont.css">
  <link rel="stylesheet" href="./css/style.css">
</head>

<body>
  <div class="dropdown">
    <button id="dropdown-button" class="button" popovertarget="dropdown-panel">
      <span class="text">请选择</span>
      <abbr class="arrow iconfont icon-arrow-down" title="展开更多"></abbr>
    </button>
    <menu id="dropdown-panel" class="panel" popover>
      <li class="item"><input type="radio" name="option" value="">请选择</li>
      <li class="item"><input type="radio" name="option" value="chrome">Google Chrome</li>
      <li class="item"><input type="radio" name="option" value="firefox">Mozilla Firefox</li>
      <li class="item"><input type="radio" name="option" value="edge">Microsoft Edge</li>
      <li class="item"><input type="radio" name="option" value="safari">Safari</li>
      <li class="item"><input type="radio" name="option" value="opera">Opera</li>
      <li class="item"><input type="radio" name="option" value="ie" disabled>Microsoft Internet Explorer</li>
    </menu>
  </div>

  <script src="./js/main.js"></script>
</body>

</html>

示例2:自定义下拉框

html 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8">
    <title>自定义下拉菜单</title>
    <link rel="stylesheet" href="font/iconfont.css">
    <link rel="stylesheet" href="./css/style.css">
  </head>

  <body>
    <select name="browsers" id="browsers" class="dropdown">
      <option value="Google Chrome">谷歌浏览器</option>
      <option value="Microsoft Edge">微软 Edge 浏览器</option>
      <option value="Mozilla Firefox">火狐浏览器</option>
      <option value="Apple Safari">Safari 浏览器</option>
      <option value="Opera">Opera 浏览器</option>
      <option value="QQ Browser">QQ 浏览器</option>
      <option value="360 Browser">360 浏览器</option>
      <option value="Sogou Browser">搜狗浏览器</option>
      <option value="UC Browser">UC 浏览器</option>
      <option value="Huawei Browser">华为浏览器</option>
      <option value="Mi Browser">小米浏览器</option>
      <option value="Internet Explorer">微软 Internet Explorer</option>
    </select>
  </body>
</html>
相关推荐
果粒蹬i2 小时前
自用超半年的免费 OCR 工具分享:告别付费,本地搭建更安心
前端·网络·ocr
朝阳5812 小时前
M3U8 下载助手油猴脚本 - 完全使用指南
前端·javascript·windows
kadog2 小时前
GraphX:基于 WebGL 区间算术的 GPU 加速隐函数绘图器
前端·javascript·数学建模·webgl
utmhikari2 小时前
【DIY小记】解决MacOS上Edge浏览器bilibili全屏卡顿的问题
前端·macos·性能优化·edge·bilibili
上单带刀不带妹2 小时前
UniApp 页面跳转完全指南:5 种路由方式详解与实战对比
前端·javascript·vue.js·uni-app·跨端开发
大阿明2 小时前
Node.js npm 安装过程中 EBUSY 错误的分析与解决方案
前端·npm·node.js
Cxiaomu2 小时前
Web 项目的开发/生产环境请求接口配置治理实战
前端·react.js·typescript
Можно2 小时前
深入理解 UniApp 生命周期钩子:从页面到组件的全流程掌控
前端·javascript·vue.js
橙色日落2 小时前
Vue2 + LogicFlow 实现可视化流程图编辑功能+常用属性大全
前端·vue·流程图·logicflow