小程序中获取元素节点

💡 前言

在 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 操作的核心手段。

相关推荐
PineappleCoder3 小时前
大模型也栽跟头的 Promise 题!来挑战一下?
前端·面试·promise
非凡ghost3 小时前
MousePlus(鼠标增强工具) 中文绿色版
前端·windows·计算机外设·软件需求
焚 城3 小时前
EXCEL(带图)转html【uni版】
前端·html·excel
我家媳妇儿萌哒哒3 小时前
Vue2 elementUI年份区间选择组件
前端·javascript·elementui
笨笨狗吞噬者3 小时前
【uniapp】小程序体积优化,分包异步化
前端·微信小程序·uni-app
00后程序员张3 小时前
iOS 26 开发者工具推荐,构建高效调试与性能优化工作流
android·ios·性能优化·小程序·uni-app·iphone·webview
该用户已不存在3 小时前
Golang 上传文件到 MinIO?别瞎折腾了,这 5 个库拿去用
前端·后端·go
snows_l3 小时前
JavaScript 性能优化实战大纲
前端
文心快码BaiduComate3 小时前
文心快码3.5S开发古风射覆小游戏,它帅到我了!
前端·后端·程序员