小程序中获取元素节点

💡 前言

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

相关推荐
by__csdn2 分钟前
JavaScript性能优化实战:异步与延迟加载全方位攻略
开发语言·前端·javascript·vue.js·react.js·typescript·ecmascript
牛三金3 分钟前
魔改-隐语PSI通信,支持外部通信自定义
服务器·前端·算法
杨超越luckly4 分钟前
HTML应用指南:利用GET请求获取全国瑞思教育门店位置信息
前端·python·arcgis·html·门店数据
尘缘浮梦6 分钟前
chrome英文翻译插件
前端·chrome
HIT_Weston7 分钟前
58、【Ubuntu】【Gitlab】拉出内网 Web 服务:Gitlab 配置审视(二)
前端·ubuntu·gitlab
这是个栗子12 分钟前
【问题解决】Vue2 与 Vue3项目中 Node.js 版本选择
前端·node.js·nvm
222you13 分钟前
SpringBeanFactory
java·服务器·前端
苏打水com14 分钟前
第十一篇:Day31-33 前端安全与性能监控——从“能用”到“安全可靠”(对标职场“系统稳定性”需求)
前端·javascript·css·vue.js·html
fpl111615 分钟前
npm :无法加载文件 D:\...\nodejs\npm.ps1,因为在此系统上禁止运行脚本
前端·vscode·npm·node.js·命令模式
LYFlied19 分钟前
LeetCode热题Top100:核心算法思想与前端实战套路
前端·算法·leetcode·面试·算法思想·算法套路·解题公式