DOM属性与样式

HTML属性操作

HTML属性是定义在HTML标签上的属性。

getAttribute

const link = document.querySelector("a");

// 获取属性值
const href = link.getAttribute("href");
const title = link.getAttribute("title");

// 属性不存在返回null
const notExist = link.getAttribute("not-exist");  // null

// 自定义属性
const dataId = link.getAttribute("data-id");

setAttribute

const link = document.querySelector("a");

// 设置属性
link.setAttribute("href", "https://db-w.cn");
link.setAttribute("target", "_blank");
link.setAttribute("title", "东巴文");

// 设置自定义属性
link.setAttribute("data-id", "123");

removeAttribute

const input = document.querySelector("input");

// 移除属性
input.removeAttribute("disabled");
input.removeAttribute("required");

// 移除后属性不存在
console.log(input.hasAttribute("disabled"));  // false

hasAttribute

const input = document.querySelector("input");

// 检查属性是否存在
if (input.hasAttribute("disabled")) {
    console.log("输入框已禁用");
}

// 检查多个属性
const hasRequired = input.hasAttribute("required");
const hasPlaceholder = input.hasAttribute("placeholder");

attributes

const element = document.querySelector("div");

// 获取所有属性
const attrs = element.attributes;

// 遍历属性
for (const attr of attrs) {
    console.log(attr.name, attr.value);
}

// 通过索引访问
console.log(attrs[0].name, attrs[0].value);

// 通过名称访问
console.log(attrs.getNamedItem("id").value);

DOM属性操作

DOM属性是JavaScript对象的属性。

直接访问

const input = document.querySelector("input");

// 读取DOM属性
console.log(input.id);         // ID
console.log(input.name);       // name属性
console.log(input.type);       // type属性
console.log(input.value);      // 当前值
console.log(input.checked);    // 是否选中
console.log(input.disabled);   // 是否禁用

// 设置DOM属性
input.id = "new-id";
input.value = "东巴文";
input.disabled = true;
input.checked = true;

HTML属性 vs DOM属性

const input = document.querySelector("input");

// HTML属性:初始值
console.log(input.getAttribute("value"));  // 初始值

// DOM属性:当前值
console.log(input.value);  // 当前值

// 用户输入后
input.value = "新值";
console.log(input.getAttribute("value"));  // 初始值(不变)
console.log(input.value);  // "新值"

// 设置DOM属性不会改变HTML属性
input.value = "东巴文";
input.getAttribute("value");  // 仍然是初始值

// 设置HTML属性会同步DOM属性
input.setAttribute("value", "新值");
console.log(input.value);  // "新值"

常见属性差异

HTML属性 DOM属性 说明
class className 类名
for htmlFor label的for属性
tabindex tabIndex Tab顺序
readonly readOnly 只读
maxlength maxLength 最大长度
const input = document.querySelector("input");

// class → className
input.className = "active highlight";

// for → htmlFor
const label = document.querySelector("label");
label.htmlFor = "username";

// readonly → readOnly
input.readOnly = true;

data-*属性

自定义数据属性用于存储额外信息。

dataset属性

// HTML: <div id="user" data-id="123" data-user-name="东巴文"></div>
const element = document.querySelector("#user");

// 读取data属性
console.log(element.dataset.id);        // "123"
console.log(element.dataset.userName);  // "东巴文"(驼峰命名)

// 设置data属性
element.dataset.age = "1";
element.dataset.role = "admin";

// 删除data属性
delete element.dataset.age;

// 检查是否存在
console.log("id" in element.dataset);  // true

getAttribute/setAttribute

const element = document.querySelector("#user");

// 使用getAttribute
console.log(element.getAttribute("data-id"));  // "123"

// 使用setAttribute
element.setAttribute("data-name", "东巴文");

// 区别:dataset自动转换命名
// data-user-name → dataset.userName
// data-userName → dataset.username

应用场景

// 存储元素关联数据
const items = document.querySelectorAll(".item");
items.forEach((item, index) => {
    item.dataset.index = index;
});

// 点击时获取数据
items.forEach(item => {
    item.addEventListener("click", () => {
        const index = item.dataset.index;
        console.log(`点击了第${index}项`);
    });
});

// 存储API数据
const userElement = document.querySelector("#user");
userElement.dataset.userId = "123";
userElement.dataset.userRole = "admin";

classList

classList提供了操作类名的便捷方法。

基本方法

const element = document.querySelector("#target");

// 添加类
element.classList.add("active");
element.classList.add("highlight", "selected");  // 添加多个

// 移除类
element.classList.remove("active");
element.classList.remove("highlight", "selected");  // 移除多个

// 切换类
element.classList.toggle("active");  // 有则移除,无则添加
element.classList.toggle("active", true);  // 强制添加
element.classList.toggle("active", false);  // 强制移除

// 检查类
console.log(element.classList.contains("active"));  // true/false

// 替换类
element.classList.replace("old-class", "new-class");

classList属性

const element = document.querySelector("#target");

// 获取类名数量
console.log(element.classList.length);  // 类名数量

// 通过索引访问
console.log(element.classList[0]);      // 第一个类名
console.log(element.classList.item(0)); // 第一个类名

// 遍历类名
for (const className of element.classList) {
    console.log(className);
}

// 转为数组
const classes = [...element.classList];

className

const element = document.querySelector("#target");

// 获取完整类名字符串
console.log(element.className);  // "active highlight"

// 设置类名(覆盖)
element.className = "new-class";

// 添加类名
element.className += " another-class";

// 推荐使用classList
element.classList.add("active");  // 更方便

style属性

通过style属性操作内联样式。

基本用法

const element = document.querySelector("#target");

// 设置内联样式
element.style.color = "red";
element.style.backgroundColor = "blue";
element.style.fontSize = "16px";
element.style.marginTop = "10px";

// 注意:使用驼峰命名
// CSS: background-color → JS: backgroundColor
// CSS: font-size → JS: fontSize

// 获取内联样式
console.log(element.style.color);  // "red"

// 只能获取内联样式
console.log(element.style.display);  // ""(如果没有内联样式)

cssText

const element = document.querySelector("#target");

// 一次性设置多个样式
element.style.cssText = "color: red; background: blue; font-size: 16px;";

// 获取内联样式字符串
console.log(element.style.cssText);

// 追加样式
element.style.cssText += "; margin: 10px;";

移除样式

const element = document.querySelector("#target");

// 移除单个样式
element.style.color = "";  // 设为空字符串
element.style.removeProperty("color");

// 移除所有内联样式
element.style.cssText = "";
element.removeAttribute("style");

setProperty

const element = document.querySelector("#target");

// 设置CSS属性
element.style.setProperty("color", "red");
element.style.setProperty("background-color", "blue");
element.style.setProperty("--custom-color", "green");  // CSS变量

// 获取CSS属性
console.log(element.style.getPropertyValue("color"));

// 移除CSS属性
element.style.removeProperty("color");

计算样式

获取元素最终应用的样式。

getComputedStyle

const element = document.querySelector("#target");

// 获取计算样式
const styles = window.getComputedStyle(element);

// 读取样式值
console.log(styles.color);           // "rgb(255, 0, 0)"
console.log(styles.backgroundColor); // "rgb(0, 0, 255)"
console.log(styles.fontSize);        // "16px"
console.log(styles.display);         // "block"

// 获取伪元素样式
const beforeStyles = window.getComputedStyle(element, "::before");
console.log(beforeStyles.content);

注意事项

const element = document.querySelector("#target");

const styles = getComputedStyle(element);

// 1. 返回的是只读对象
// styles.color = "blue";  // 无效

// 2. 返回的是计算后的值
console.log(styles.fontSize);  // "16px"(不是"1em")

// 3. 颜色值会被转换
console.log(styles.color);  // "rgb(255, 0, 0)"(不是"red")

// 4. 复合属性返回空
console.log(styles.margin);     // ""(可能为空)
console.log(styles.marginTop);  // "10px"(使用具体属性)

实际应用

// 获取元素实际高度
function getHeight(element) {
    const styles = getComputedStyle(element);
    return parseFloat(styles.height);
}

// 检查元素是否可见
function isVisible(element) {
    const styles = getComputedStyle(element);
    return styles.display !== "none" && 
           styles.visibility !== "hidden" &&
           styles.opacity !== "0";
}

// 获取元素位置
function getPosition(element) {
    const styles = getComputedStyle(element);
    return {
        position: styles.position,
        top: styles.top,
        left: styles.left
    };
}

操作CSS类

条件添加类

const element = document.querySelector("#target");

// 根据条件添加类
function updateStatus(isActive, isSelected) {
    element.classList.toggle("active", isActive);
    element.classList.toggle("selected", isSelected);
}

// 状态切换
element.addEventListener("click", () => {
    element.classList.toggle("active");
});

主题切换

// 切换暗色主题
function toggleDarkMode() {
    document.body.classList.toggle("dark-mode");
}

// 检查当前主题
function isDarkMode() {
    return document.body.classList.contains("dark-mode");
}

// 保存主题偏好
function setTheme(theme) {
    document.body.className = "";  // 清除所有类
    document.body.classList.add(theme);
    localStorage.setItem("theme", theme);
}

// 加载保存的主题
const savedTheme = localStorage.getItem("theme") || "light";
setTheme(savedTheme);

操作CSS变量

读取和设置CSS变量

// CSS: :root { --primary-color: #007bff; }
const root = document.documentElement;

// 读取CSS变量
const primaryColor = getComputedStyle(root).getPropertyValue("--primary-color");
console.log(primaryColor);  // "#007bff"

// 设置CSS变量
root.style.setProperty("--primary-color", "#ff0000");

// 动态主题
function setThemeColor(color) {
    root.style.setProperty("--primary-color", color);
    root.style.setProperty("--secondary-color", adjustColor(color, 20));
}

组件级CSS变量

const component = document.querySelector(".component");

// 设置组件级CSS变量
component.style.setProperty("--component-color", "blue");
component.style.setProperty("--component-size", "100px");

// 在CSS中使用
// .component {
//     color: var(--component-color);
//     width: var(--component-size);
// }

下一步

掌握了DOM属性与样式后,让我们继续学习:

  1. 表单操作 - 学习表单操作
  2. 事件基础 - 学习事件处理
  3. 事件绑定 - 学习事件绑定

东巴文(db-w.cn) - 让编程学习更简单

🎨 东巴文寄语:DOM属性和样式操作是前端开发的基础技能,理解HTML属性与DOM属性的区别,掌握classList和style的使用方法,能让你灵活地控制页面外观。在 db-w.cn,我们帮你精通样式操作!