【taro react】---- Get the position, width and height of the element and other information

1. Demand Analysis

  1. Add a query request for the layout position of the node. Relative to the display area, in pixels. Its function is similar to DOM's getBoundingClientRect. Return the SelectorQuery corresponding to NodesRef.
  2. Distinguish between the environment of the applet and H5, and call getBoundingClientRect to obtain the corresponding information.

2. H5 implementation

  1. Determine whether the incoming element is a window window, and if it is a window window, directly obtain the width and height of the window;
  2. element, and at the same time, information such as the width and height of the element can be obtained;
  3. If none are satisfied, return to the default value.
function isWindow(val){
  return val === window
}

export const getRect = (elementRef) => {
  const element = elementRef
  // 判断传入元素是否是window窗口,是window窗口,直接获取窗口的宽高
  if (isWindow(element)) {
    const width = element.innerWidth
    const height = element.innerHeight

    return {
      top: 0,
      left: 0,
      right: width,
      bottom: height,
      width,
      height,
    }
  }
  // 是元素,同时可以获取元素的宽高等信息
  if (element && element.getBoundingClientRect) {
    return element.getBoundingClientRect()
  }
  // 都不满足,返回默认值
  return {
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    width: 0,
    height: 0,
  }
}

3. Implementation of Taro

  1. If the element exists, judge to use the corresponding environment to obtain element information;
  2. The method for obtaining element information of elements used in the H5 environment;
  3. The WeChat applet environment calls boundingClientRect to obtain element information;
  4. Return to the default value.
export const getRectByTaro = async (element) => {
  // 元素存在,判断使用对应环境获取元素信息
  if (element) {
    if(process.env.TARO_ENV === "h5"){
      // H5环境使用元素的获取元素信息方法
      return Promise.resolve(getRect(element))
    } else if(process.env.TARO_ENV === "weapp"){
      // 微信小程序环境调用 boundingClientRect 获取元素信息
      return new Promise((resolve) => {
        createSelectorQuery()
          .select(`.${element.props.class.split(' ').filter(item => item).join('.')}`)
          .boundingClientRect(resolve).exec()
      })
    }
  }
  // 返回默认值
  return Promise.resolve({
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    width: 0,
    height: 0,
  })
}

4. Use cases

1. Import

import React, { Component } from 'react';
import { getRectByTaro } from '@utils/use-client-rect';

2. Obtain the getBoundingClientRect information of dom

class page extends Component {
  constructor(props) {
    this.navbarRef = React.createRef()
  }
  componentDidShow(){
    // 如果元素内有动态信息,需要将获取信息的方法放到请求数据完成,设置数据后边
    this.getElementInfo()
  }
  getElementInfo(){
    let _this = this;
    let timer = setTimeout(async () => {
      clearTimeout(timer)
      console.log('_this.navbarRef',_this.navbarRef.current)
      let info = await getRectByTaro(_this.navbarRef.current)
      console.log('navbarRef', info)
    },0)
  }
  render() {
    return (<View className='rui-navbar-current-content' ref={this.navbarRef}></View>)
  }
}

5. WeChat applet return sample

Enter a picture description

6. H5 return sample

Enter a picture description

7. Complete code

import { createSelectorQuery } from '@tarojs/taro';
function isWindow(val){
  return val === window
}

export const getRect = (elementRef) => {
  const element = elementRef
  // 判断传入元素是否是window窗口,是window窗口,直接获取窗口的宽高
  if (isWindow(element)) {
    const width = element.innerWidth
    const height = element.innerHeight

    return {
      top: 0,
      left: 0,
      right: width,
      bottom: height,
      width,
      height,
    }
  }
  // 是元素,同时可以获取元素的宽高等信息
  if (element && element.getBoundingClientRect) {
    return element.getBoundingClientRect()
  }
  // 都不满足,返回默认值
  return {
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    width: 0,
    height: 0,
  }
}

export const getRectByTaro = async (element) => {
  // 元素存在,判断使用对应环境获取元素信息
  if (element) {
    if(process.env.TARO_ENV === "h5"){
      // H5环境使用元素的获取元素信息方法
      return Promise.resolve(getRect(element))
    } else if(process.env.TARO_ENV === "weapp"){
      // 微信小程序环境调用 boundingClientRect 获取元素信息
      return new Promise((resolve) => {
        createSelectorQuery()
          .select(`.${element.props.class.split(' ').filter(item => item).join('.')}`)
          .boundingClientRect(resolve).exec()
      })
    }
  }
  // 返回默认值
  return Promise.resolve({
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    width: 0,
    height: 0,
  })
}

Guess you like

Origin blog.csdn.net/m0_38082783/article/details/132034815