阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > DOM查询方法

DOM查询方法

作者:陈川 阅读数:10558人阅读 分类: JavaScript

DOM查询方法概述

DOM查询是JavaScript操作网页元素的基础,通过选择器或遍历方式获取文档中的节点对象。浏览器提供了多种原生API,现代开发中常结合CSS选择器语法进行高效定位。

document.getElementById()

通过元素ID属性获取单个节点,返回第一个匹配的DOM对象。ID在文档中应当唯一,这是最快的查询方式之一。

const header = document.getElementById('main-header');
header.style.color = '#ff0000';

注意:该方法区分大小写,且只从document对象开始搜索。

document.getElementsByClassName()

返回包含所有指定类名的元素集合(HTMLCollection),该集合是动态的会随DOM变化自动更新。

const buttons = document.getElementsByClassName('action-btn');
for (let btn of buttons) {
  btn.addEventListener('click', handleClick);
}

当文档结构变化时,HTMLCollection会自动反映这些变化,但转换为数组可避免性能问题:

const btnArray = Array.from(buttons);

document.getElementsByTagName()

通过标签名获取元素集合,支持通配符"*"获取所有元素。返回的同样是动态HTMLCollection。

const images = document.getElementsByTagName('img');
console.log(`页面包含${images.length}张图片`);

document.querySelector()

使用CSS选择器语法返回第一个匹配元素,支持复杂选择器组合:

// 获取第一个类名为active的li元素
const item = document.querySelector('li.active');

// 获取data-target属性的元素
const target = document.querySelector('[data-target]');

document.querySelectorAll()

返回匹配的所有元素的静态NodeList,支持完整CSS选择器语法:

// 获取所有偶数行的表格行
const rows = document.querySelectorAll('tr:nth-child(even)');

// 复合选择器示例
const elements = document.querySelectorAll('.panel > .header, .tooltip');

与HTMLCollection不同,NodeList不会自动更新,但可以使用forEach方法遍历。

特殊集合访问

文档提供预定义集合快速访问常见元素:

document.links    // 所有<a>和<area>元素
document.forms    // 所有<form>元素
document.images   // 所有<img>元素
document.scripts  // 所有<script>元素

节点关系查询

通过现有节点进行相对查询:

const parent = element.parentNode;
const children = element.childNodes;
const firstChild = element.firstChild;
const lastChild = element.lastChild;

// 仅元素节点遍历
const prevElement = element.previousElementSibling;
const nextElement = element.nextElementSibling;

属性选择器查询

结合属性选择器进行精确匹配:

// 精确匹配属性值
const exactMatch = document.querySelector('[type="submit"]');

// 包含特定字符串
const containsMatch = document.querySelector('[class*="btn-"]');

// 开头匹配
const startsWith = document.querySelector('[href^="https"]');

// 结尾匹配
const endsWith = document.querySelector('[src$=".png"]');

表单元素查询

表单控件有专用查询方式:

const form = document.forms['login-form'];
const emailInput = form.elements.email;
const radioButtons = form.elements['newsletter'];

性能优化建议

  1. 缓存查询结果避免重复查询:
// 不佳做法
for(let i=0; i<100; i++) {
  document.querySelector('.item').style.color = 'red';
}

// 推荐做法
const item = document.querySelector('.item');
for(let i=0; i<100; i++) {
  item.style.color = 'red';
}
  1. 缩小查询范围:
// 在整个文档中查询
document.querySelectorAll('.item');

// 在特定容器中查询效率更高
const container = document.getElementById('app');
container.querySelectorAll('.item');
  1. 优先使用ID选择器,其次是类选择器

动态过滤技术

结合数组方法对查询结果进行二次处理:

// 获取所有可见的输入框
const inputs = Array.from(document.querySelectorAll('input'))
  .filter(input => input.offsetParent !== null);

// 获取有data-属性的元素
const dataElements = [...document.querySelectorAll('[data-]')];

实时观察技术

使用MutationObserver监控DOM变化:

const observer = new MutationObserver(mutations => {
  mutations.forEach(mutation => {
    if (mutation.addedNodes.length) {
      console.log('新增节点:', mutation.addedNodes);
    }
  });
});

observer.observe(document.body, {
  childList: true,
  subtree: true
});

浏览器兼容方案

处理旧版浏览器兼容问题:

// 兼容IE8的查询函数
function query(selector) {
  return document.querySelectorAll ? 
    document.querySelectorAll(selector) :
    document.getElementById(selector.slice(1));
}

// 类名查询兼容方案
function byClass(className, context) {
  context = context || document;
  if (context.getElementsByClassName) {
    return context.getElementsByClassName(className);
  }
  var elements = context.getElementsByTagName('*'),
      result = [];
  for (var i=0; i<elements.length; i++) {
    if (elements[i].className.indexOf(className) != -1) {
      result.push(elements[i]);
    }
  }
  return result;
}

复杂选择器示例

展示CSS3选择器的强大功能:

// 获取属性包含特定值的元素
const langs = document.querySelectorAll('[lang|="en"]');

// 结构伪类选择器
const thirdItem = document.querySelector('ul.items li:nth-child(3)');

// 否定伪类
const nonHidden = document.querySelectorAll('div:not(.hidden)');

// 状态伪类
const checkedItems = document.querySelectorAll('input[type="checkbox"]:checked');

自定义数据属性查询

利用data-*属性进行组件查询:

// 获取所有轮播图项
const slides = document.querySelectorAll('[data-carousel="slide"]');

// 获取特定数据值的元素
const currentSlide = document.querySelector('[data-index="3"]');

阴影DOM查询

在Web组件中查询阴影DOM内容:

const host = document.querySelector('custom-element');
const shadowInput = host.shadowRoot.querySelector('input');

动态加载内容处理

处理异步加载内容的查询策略:

// 使用事件委托处理动态内容
document.addEventListener('click', function(e) {
  if (e.target.matches('.dynamic-item')) {
    console.log('点击了动态加载的项目');
  }
});

// 检查元素是否存在
function waitForElement(selector) {
  return new Promise(resolve => {
    if (document.querySelector(selector)) {
      return resolve(document.querySelector(selector));
    }

    const observer = new MutationObserver(() => {
      if (document.querySelector(selector)) {
        observer.disconnect();
        resolve(document.querySelector(selector));
      }
    });

    observer.observe(document.body, {
      childList: true,
      subtree: true
    });
  });
}

选择器性能比较

不同选择器的执行效率差异:

// 较快的选择器
document.getElementById('content');
document.getElementsByClassName('active')[0];

// 较慢的复杂选择器
document.querySelector('div#content ul li.active > a[href^="#"]');

错误处理机制

健壮的查询错误处理:

function safeQuery(selector, parent = document) {
  try {
    const el = parent.querySelector(selector);
    if (!el) throw new Error(`元素未找到: ${selector}`);
    return el;
  } catch (error) {
    console.error('查询错误:', error);
    return null;
  }
}

const element = safeQuery('.missing-element') || document.createElement('div');

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

上一篇:节点类型与属性

下一篇:DOM节点操作

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌