小程序中获取元素节点

💡 前言

在 Web 环境中,我们常用以下方式获取 DOM 元素:

复制代码
document.querySelector()
document.getElementById()
this.$refs.xxx

但在 小程序uni-app 环境中,这些方法统统失效!

因为小程序中没有浏览器 DOM,也不存在 documentwindow 这类全局对象。

👉 换句话说:
小程序没有 DOM 概念,只有"节点信息"或"组件实例"。

✅ 一句话总结

uni-app(包括微信小程序端) 中,要想获取页面元素或组件引用,必须使用 官方提供的节点查询 API:

复制代码
uni.createSelectorQuery()

或者:

复制代码
this.$refs + uni.createSelectorQuery().in(this)

🧩 一、使用 uni.createSelectorQuery() 获取节点信息

这是最通用、跨平台(H5 / App / 小程序)都能使用的方式。

📘 示例

复制代码
<template>
  <view>
    <view id="box" class="my-box">Hello Box</view>
  </view>
</template>

<script>
export default {
  mounted() {
    // 必须在节点渲染完成后(mounted / onReady)执行
    const query = uni.createSelectorQuery().in(this)
    query.select('#box').boundingClientRect(data => {
      console.log('节点信息:', data)
      /*
        data = {
          id: "box",
          dataset: {},
          left: 0,
          right: 375,
          top: 50,
          bottom: 150,
          width: 375,
          height: 100
        }
      */
    }).exec()
  }
}
</script>

<style>
.my-box {
  width: 200rpx;
  height: 100rpx;
  background-color: pink;
}
</style>

📌 说明

  • uni.createSelectorQuery() 类似于浏览器的 document.querySelector()

  • 但它返回的不是 DOM 节点,而是 节点的布局信息(宽度、高度、坐标等);

  • 查询必须在 节点渲染完成 后执行,否则会返回 null

🧩 二、获取组件实例(类似 Vue 的 $refs

在 uni-app 中,同样支持 Vue 的 ref 属性,但用法略有区别。

📘 示例

复制代码
<template>
  <view>
    <custom-child ref="childRef"></custom-child>
    <view ref="myView">我是 view 元素</view>
  </view>
</template>

<script>
export default {
  mounted() {
    // ✅ 获取自定义组件实例
    console.log(this.$refs.childRef) // 输出组件实例

    // ⚠️ 获取原生节点(view 等)信息,不能直接 this.$refs.myView
    const query = uni.createSelectorQuery().in(this)
    query.select('#myView').boundingClientRect(res => {
      console.log('view 节点信息:', res)
    }).exec()
  }
}
</script>

📌 要点总结

类型 获取方式 可否用 $refs 说明
自定义组件 <custom-child> this.$refs.xxx ✅ 可以 返回组件实例
原生节点 <view> / <scroll-view> uni.createSelectorQuery() ❌ 不行 返回节点信息对象

🧩 三、常见场景示例

1️⃣ 获取滚动条位置

复制代码
const query = uni.createSelectorQuery().in(this)
query.select('.scroll-view').scrollOffset(res => {
  console.log('滚动位置:', res.scrollTop)
}).exec()

2️⃣ 获取节点尺寸、坐标

复制代码
query.select('.item').boundingClientRect(res => {
  console.log('节点宽高:', res.width, res.height)
}).exec()

🧩 四、常见 API 对比表

功能 Web 写法 uni-app 对应写法
获取元素 document.querySelector() uni.createSelectorQuery()
获取元素尺寸 element.getBoundingClientRect() .boundingClientRect()
获取滚动偏移 element.scrollTop .scrollOffset()
获取组件实例 this.$refs.xxx 同样可用(仅限自定义组件)
不存在的对象 windowdocumentHTMLElement ❌ 无法使用

🧩 五、实战示例:滚动到指定元素

复制代码
<template>
  <scroll-view scroll-y :scroll-top="scrollTop">
    <view id="target" style="height: 800rpx; background: skyblue;">
      我是目标区域
    </view>
    <view style="height: 800rpx; background: pink;"></view>
  </scroll-view>
  <button @click="goToTarget">滚动到目标</button>
</template>

<script>
export default {
  data() {
    return {
      scrollTop: 0
    }
  },
  methods: {
    goToTarget() {
      const query = uni.createSelectorQuery().in(this)
      query.select('#target').boundingClientRect(res => {
        this.scrollTop = res.top
      }).exec()
    }
  }
}
</script>

🧩 六、封装一个通用工具函数

为了简化开发,可以封装一个通用的 getElementRect() 函数:

复制代码
// utils/dom.js
export function getElementRect(ctx, selector) {
  return new Promise(resolve => {
    const query = uni.createSelectorQuery().in(ctx)
    query.select(selector).boundingClientRect(res => {
      resolve(res)
    }).exec()
  })
}

使用示例:

复制代码
import { getElementRect } from '@/utils/dom.js'

export default {
  async mounted() {
    const rect = await getElementRect(this, '#myBox')
    console.log('元素位置与尺寸:', rect)
  }
}

⚡ 注意事项

  1. 必须等待渲染完成后调用mountedonReady);

  2. 查询链式调用最后必须执行 .exec()

  3. 如果使用 Vue 3 的 <script setup> 语法,可通过 getCurrentInstance() 获取实例:

    import { getCurrentInstance } from 'vue'
    const { proxy } = getCurrentInstance()
    const query = uni.createSelectorQuery().in(proxy)

uni.createSelectorQuery() 在 H5、App、小程序多端兼容。

🎯 总结

场景 推荐方法
获取节点宽高、坐标 uni.createSelectorQuery().boundingClientRect()
获取滚动位置 .scrollOffset()
获取自定义组件实例 this.$refs.xxx
组合使用(复杂页面) uni.createSelectorQuery().in(this)

🔁 结语:

在小程序环境中,不能直接操作 DOM。

学会使用 uni.createSelectorQuery() 才是真正理解小程序渲染机制的关键。

它既安全、性能稳定,又能跨多端使用,是替代 Web DOM 操作的核心手段。

相关推荐
Pedantic15 小时前
SwiftUI 手势层级(Gesture Hierarchy)详解
前端
飘尘16 小时前
前端转型全栈(Java后端)的快速上手指引
前端·后端·全栈
一颗烂土豆16 小时前
Meshopt 压缩深度解析,为什么它比 Draco 更快
前端·javascript·webgl
浏览器工程师17 小时前
AI Agent 接浏览器任务,先别让它一路点到底
前端·后端
雨季mo浅忆17 小时前
VSCode自动格式化三要素
前端
爱勇宝18 小时前
深扒 Anthropic 1680 位工程师简历:应届生几乎没机会,AI 公司最缺的不是博士
前端·后端·程序员
kyriewen18 小时前
同事每天催我 Code Review,我写了个脚本让 AI 替我 review PR——现在他反过来催 AI 了
前端·javascript·ai编程
user205855615181321 小时前
Windows 项目安装时报 `node-sass` 错误,如何快速处理
前端
LiaCode21 小时前
Redis 在生产项目的使用
前端·后端