HTML全局属性必须写在开始标签内且用英文双引号包裹,多个属性空格分隔;布尔属性存在即生效,contenteditable和spellcheck除外;data-*属性JS读取需驼峰转换;id查找为O(1),class匹配需遍历。

全局属性必须写在开始标签里,不能放结束标签
HTML全局属性只在开始标签中生效,写在结束标签里完全被忽略。比如<p class="intro">文字</p>有效,但<p>文字</p>class="intro">里的class根本不起作用。
多个属性之间用空格分隔,不是逗号、分号或换行。引号必须是英文双引号("),中文引号、单引号(哪怕HTML5允许)或不加引号都容易出问题——尤其当值含空格或特殊字符时。
-
id="header"✅ 正确 -
id='header'⚠️ 部分场景可行,但新手统一用双引号更稳 -
id=header❌ 值不含空格时可能“碰巧”解析,但class="btn primary"这种会直接断成两个属性 -
class="btn" primary❌primary被当成文本节点,不是属性
布尔属性不靠值判断,存在即生效
像hidden、autofocus、draggable这类布尔属性,浏览器只看它“有没有出现”,不看你写了什么值。
立即学习“前端免费学习笔记(深入)”;
例如:<div hidden="false">依然隐藏;<code><input autofocus="no">照样自动聚焦;<img draggable="0" alt="HTML全局属性的基本语法介绍" >图片仍可拖拽。因为它们的逻辑是:有这个属性名,就启用对应行为。
唯一例外是contenteditable和spellcheck,它们是枚举属性,只认"true"或"false"字符串值,其他值(包括空值)等效于false。
data-* 属性命名和 JS 读取有固定映射规则
data-开头的属性看似自由,但 JS 中读取时必须遵守驼峰转换规则:连字符-后首字母大写,且去掉data-前缀。
比如:data-user-id="123" → dataset.userId;data-api-key="abc" → dataset.apiKey。写成dataset.userid或dataset.APIKey都拿不到值。
数字开头的属性名(如data-1st-place)无法通过点号访问,只能用方括号:dataset["1st-place"]。另外,属性值永远是字符串,哪怕写data-count="0",取出来也是"0",需要手动转类型。
id 和 class 看似简单,但 DOM 查找和 CSS 匹配机制完全不同
id是浏览器内部哈希索引,document.getElementById("x")是 O(1) 查找;而class依赖 CSS 选择器引擎,document.querySelector(".x")要遍历匹配,节点多时有明显延迟。
一个页面里id重复,getElementById只返回第一个,JS 不报错但逻辑会错;class支持多值但空格敏感:class="btn primary"(两个空格)会被解析成三个类名:["btn", "", "primary"],导致classList.contains("primary")返回false。
动态操作类名,优先用classList.add()、classList.toggle(),别直接拼className += " active"——容易引入多余空格或重复类名。



















