DOM 元素的属性(Attributes)与特性(Properties)的区别与操作

好嘞!各位观众老爷,晚上好!欢迎来到今晚的“前端奇妙夜”,我是你们的老朋友,bug终结者,代码诗人——阿杰。今天咱们不聊框架,不谈架构,就来聊聊前端开发中一对让人头疼的“双胞胎”:DOM元素的属性(Attributes)特性(Properties)

这对“双胞胎”长得贼像,用起来也经常混淆,但实际上,它们可是性格迥异,有着不同的生活轨迹。搞不清它们,轻则页面显示异常,重则代码逻辑混乱,最终只能被迫加班,对着屏幕哀嚎:“苍天啊,大地啊,谁来救救我!”

所以,今天阿杰就带大家拨开云雾,认清这对“双胞胎”的真面目,掌握它们的使用技巧,让你的代码如行云流水,再也不用担心被它们“坑”啦!

一、开场白:一场关于“脸”和“内在”的哲学讨论

想象一下,你走在大街上,看到一位穿着时尚、打扮精致的美女,你可能会说:“哇,她真漂亮!” 这就是你看到的属性(Attributes),是外在的、静态的、写在脸上的东西。

但是,你并不知道她是不是内心善良、充满智慧,或者是个逗比段子手。这些内在的品质,就是特性(Properties),需要深入了解才能发现。

DOM元素的属性和特性,也是同样的道理。属性是写在HTML标签上的,是静态的、初始的;而特性是DOM对象上的,是动态的、可以修改的。

二、属性(Attributes):HTML标签上的“名片”

属性,就像是DOM元素的名片,在HTML标签中定义,用于描述元素的初始状态和行为。它们是静态的,一旦写在HTML上,就基本固定下来了。

举个栗子:

<input type="text" value="Hello World" id="myInput" class="form-control">
<img src="images/cat.jpg" alt="一只可爱的猫咪">

在这个例子中,typevalueidclasssrcalt 都是属性。它们在页面加载时,就被写进了HTML元素中,定义了输入框的类型、初始值、ID和样式,以及图片的来源和替代文本。

属性的特点:

  • 静态性: 属性值在HTML中定义后,除非手动修改HTML代码,否则不会改变。
  • 字符串类型: 所有的属性值都是字符串类型,即使你写的是数字,也会被当做字符串处理。
  • 大小写不敏感: 大部分属性名不区分大小写,例如 idID 效果一样。
  • 使用方法: 可以通过 element.getAttribute(attributeName)element.setAttribute(attributeName, attributeValue) 来获取和设置属性值。

举个栗子🌰:

const myInput = document.getElementById('myInput');

// 获取属性值
const type = myInput.getAttribute('type'); // type = "text"
const value = myInput.getAttribute('value'); // value = "Hello World"

// 设置属性值
myInput.setAttribute('value', 'Goodbye World'); // 修改了input框的value属性

三、特性(Properties):DOM对象的“内在”

特性,是DOM对象上的属性,是JavaScript对象的一部分。它们是动态的,可以随时修改,反映了元素的当前状态。

继续上面的例子,当页面加载后,浏览器会将HTML解析成DOM树,input 元素会对应一个 HTMLInputElement 对象。这个对象就拥有了特性,例如 valueid 等。

特性的特点:

  • 动态性: 特性值可以随时通过JavaScript修改,反映元素最新的状态。
  • 数据类型: 特性可以拥有各种数据类型,例如字符串、数字、布尔值、对象、函数等。
  • 大小写敏感: 特性名区分大小写,例如 valueValue 是不同的。
  • 使用方法: 可以通过 element.propertyName 来直接访问和修改特性值。

举个栗子🌰:

const myInput = document.getElementById('myInput');

// 获取特性值
const type = myInput.type; // type = "text"
const value = myInput.value; // value = "Hello World"

// 设置特性值
myInput.value = 'Goodbye World'; // 修改了input框的value特性

四、属性 vs 特性:一场“整容”与“气质”的较量

现在,让我们来深入对比一下属性和特性,看看它们到底有什么区别:

特性 属性
动态的,可以修改 静态的,初始值
数据类型多样 字符串类型
反映元素当前状态 定义元素初始状态
通过 element.propertyName 访问 通过 element.getAttribute(attributeName) 访问

想象一下:

  • 属性就像是你的“身份证”,上面记录了你的出生日期、性别等信息,这些信息是固定的,很难改变。
  • 特性就像是你的“个人状态”,你可以通过努力学习、改变发型、锻炼身体来改变自己的状态,变得更加优秀。

一个重要的区别: 属性是HTML标签上的定义,而特性是DOM对象上的属性。当浏览器解析HTML时,会根据HTML标签上的属性来初始化DOM对象的特性。

五、坑爹的“同步”问题:一场关于“表里如一”的讨论

有时候,属性和特性会“同步”,也就是说,修改了特性,属性也会跟着改变;或者修改了属性,特性也会跟着改变。但并非所有情况都如此!

1. 属性影响特性:

当页面加载时,HTML标签上的属性会初始化DOM对象的特性。例如,input 元素的 value 属性会初始化 HTMLInputElement 对象的 value 特性。

2. 特性影响属性:

对于某些属性,例如 valuecheckedselected 等,修改了特性值,对应的属性值也会同步更新。这被称为“同步属性”。

3. 属性不影响特性:

但是,对于一些自定义的属性,修改了属性值,特性值并不会同步更新。例如:

<div id="myDiv" data-my-attribute="initialValue"></div>
const myDiv = document.getElementById('myDiv');

// 获取属性值
console.log(myDiv.getAttribute('data-my-attribute')); // 输出 "initialValue"

// 获取特性值(不存在)
console.log(myDiv.dataMyAttribute); // 输出 undefined

// 设置属性值
myDiv.setAttribute('data-my-attribute', 'newValue');

// 再次获取属性值
console.log(myDiv.getAttribute('data-my-attribute')); // 输出 "newValue"

// 再次获取特性值(仍然不存在)
console.log(myDiv.dataMyAttribute); // 输出 undefined

结论:

  • 同步属性: 修改特性,会同步更新属性 (例如 value, checked)。
  • 非同步属性: 修改属性,不会同步更新特性 (例如自定义属性 data-*)。

六、实战演练:用代码说话,证明你的实力

光说不练假把式,现在让我们来做几个小练习,巩固一下今天所学的知识:

练习一:修改输入框的 value

<input type="text" value="初始值" id="myInput">
const myInput = document.getElementById('myInput');

// 使用特性修改value值
myInput.value = '新值';

// 使用属性修改value值
myInput.setAttribute('value', '更新后的值');

// 观察页面上的输入框显示什么?
// 思考:为什么使用特性修改,会直接影响页面显示?
//      为什么使用属性修改,需要再次获取才能看到效果?

练习二:处理复选框的 checked 状态

<input type="checkbox" id="myCheckbox">
const myCheckbox = document.getElementById('myCheckbox');

// 使用特性设置checked状态
myCheckbox.checked = true;

// 使用属性设置checked状态 (不推荐)
myCheckbox.setAttribute('checked', 'checked'); // 虽然设置了属性,但页面上可能不会立即显示

// 思考:为什么使用特性设置checked状态,页面会立即显示?
//      为什么使用属性设置checked状态,效果可能不明显?

练习三:自定义属性的应用

<div id="myDiv" data-user-id="123"></div>
const myDiv = document.getElementById('myDiv');

// 使用getAttribute获取自定义属性值
const userId = myDiv.getAttribute('data-user-id');
console.log(userId); // 输出 "123"

// 使用dataset获取自定义属性值 (更简洁)
const userId2 = myDiv.dataset.userId;
console.log(userId2); // 输出 "123"

// 设置自定义属性值
myDiv.setAttribute('data-user-id', '456');
myDiv.dataset.userId = '789';

// 思考:使用dataset访问自定义属性的优势是什么?

七、总结:掌握“双胞胎”,走向前端巅峰

好了,各位观众老爷,今天的“前端奇妙夜”就到这里了。希望通过今天的讲解,大家能够彻底搞清楚DOM元素的属性和特性,不再被它们搞得晕头转向。

记住:

  • 属性是HTML标签上的“名片”,是静态的、初始的。
  • 特性是DOM对象上的“内在”,是动态的、可以修改的。
  • 某些属性和特性会“同步”,但并非所有情况都如此。

掌握了这对“双胞胎”,你就掌握了操作DOM元素的关键,就能写出更加健壮、高效的前端代码。加油吧,少年们!让我们一起在前端的道路上越走越远,最终登上技术巅峰!

最后,阿杰送大家一句箴言:

“代码虐我千百遍,我待代码如初恋!” ❤️

感谢大家的观看,我们下期再见!Bye-bye! 🥳

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注