Javascript React Native:获取元素的位置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30096038/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 04:39:04  来源:igfitidea点击:

React Native: Getting the position of an element

javascriptiosreactjsreact-native

提问by Johannes Stein

I am styling an Imagecomponent with flexbox to be in the center of the screen which works pretty well. Now I want a second Imagecomponent to be displayed directly on the top of the first one. The second image is using absolute positioning. Currently I'm just guessing pixels so that it fits, but of course this is not accurate and way too much maintainability effort.

我正在Image使用 flexbox设计一个组件,使其位于屏幕中央,效果很好。现在我希望第二个Image组件直接显示在第一个组件的顶部。第二张图片使用绝对定位。目前我只是在猜测像素以使其适合,但这当然不准确,而且维护性工作太多。

I am pretty much looking for the React Native equivalent of jQuery's .offset(). Is there such a thing and if there isn't what's the best way to achieve this?

我几乎在寻找 jQuery 的 React Native 等价物.offset()。有没有这样的事情,如果没有什么是实现这一目标的最佳方法?

回答by tohster

React Native provides a .measure(...)method which takes a callback and calls it with the offsets and width/height of a component:

React Native 提供了一种.measure(...)方法,该方法接受回调并使用组件的偏移量和宽度/高度调用它:

myComponent.measure( (fx, fy, width, height, px, py) => {

    console.log('Component width is: ' + width)
    console.log('Component height is: ' + height)
    console.log('X offset to frame: ' + fx)
    console.log('Y offset to frame: ' + fy)
    console.log('X offset to page: ' + px)
    console.log('Y offset to page: ' + py)
})

Example...

例子...

The following calculates the layout of a custom component after it is rendered:

以下计算渲染后的自定义组件的布局:

class MyComponent extends React.Component {
    render() {
        return <View ref={view => { this.myComponent = view; }} />
    }
    componentDidMount() {
        // Print component dimensions to console
        this.myComponent.measure( (fx, fy, width, height, px, py) => {
            console.log('Component width is: ' + width)
            console.log('Component height is: ' + height)
            console.log('X offset to frame: ' + fx)
            console.log('Y offset to frame: ' + fy)
            console.log('X offset to page: ' + px)
            console.log('Y offset to page: ' + py)
        })        
    }
}


Bug notes

错误说明

  • Note that sometimes the component does not finish rendering before componentDidMount()is called. If you are getting zeros as a result from measure(...), then wrapping it in a setTimeoutshould solve the problem, i.e.:

    setTimeout( myComponent.measure(...), 0 )
    
  • 请注意,有时组件在componentDidMount()调用之前未完成渲染。如果您从 中得到零measure(...),那么将它包装在 a 中setTimeout应该可以解决问题,即:

    setTimeout( myComponent.measure(...), 0 )
    

回答by Mark Amery

You can use onLayoutto get the width, height, and relative-to-parentposition of a component at the earliest moment that they're available:

您可以使用它们在可用的最早时刻onLayout获取组件的宽度、高度和相对于父级的位置:

<View
  onLayout={event => {
    const layout = event.nativeEvent.layout;
    console.log('height:', layout.height);
    console.log('width:', layout.width);
    console.log('x:', layout.x);
    console.log('y:', layout.y);
  }}
>

Compared to using .measure()as shown in the accepted answer, this has the advantage that you'll never have to fiddle around deferring your .measure()calls with setTimeoutto make sure that the measurements are available, but the disadvantage that it doesn't give you offsets relative to the entire page, only ones relative to the element's parent.

使用.measure()已接受的答案中所示的方法相比,这样做的优点是您永远不必费力地推迟.measure()通话setTimeout以确保测量可用,但缺点是它不会为您提供相对于整个页面,只有与元素的父元素相关的页面。

回答by Mr Speaker

I needed to find the position of an element inside a ListView and used this snippet that works kind of like .offset:

我需要在 ListView 中找到一个元素的位置,并使用这个片段,它的工作原理类似于.offset

const UIManager = require('NativeModules').UIManager;
const handle = React.findNodeHandle(this.refs.myElement);
UIManager.measureLayoutRelativeToParent(
  handle, 
  (e) => {console.error(e)}, 
  (x, y, w, h) => {
    console.log('offset', x, y, w, h);
  });

This assumes I had a ref='myElement'on my component.

这假设ref='myElement'我的组件上有一个。

回答by Mislavoo7

I had a similar problem and solved it by combining the answers above

我有一个类似的问题并通过结合上面的答案解决了它

class FeedPost extends React.Component {
  constructor(props) {
    ...
    this.handleLayoutChange = this.handleLayoutChange.bind(this);
  }


handleLayoutChange() {
    this.feedPost.measure( (fx, fy, width, height, px, py) => {
      console.log('Component width is: ' + width)
      console.log('Component height is: ' + height)
      console.log('X offset to page: ' + px)
      console.log('Y offset to page: ' + py)
    })
  }

  render {
    return(
      <View onLayout={(event) => {this.handleLayoutChange(event) }} 
      ref={view => { this.feedPost = view; }} >
...

Now I can see the position of my feedPost element in the logs:

现在我可以在日志中看到我的 feedPost 元素的位置:

08-24 11:15:36.838  3727 27838 I ReactNativeJS: Component width is: 156
08-24 11:15:36.838  3727 27838 I ReactNativeJS: Component height is: 206
08-24 11:15:36.838  3727 27838 I ReactNativeJS: X offset to page: 188
08-24 11:15:36.838  3727 27838 I ReactNativeJS: Y offset to page: 870

回答by Brian F

This seems to have changed in the latest version of React Native when using refs to calculate.

当使用 refs 进行计算时,这似乎在最新版本的 React Native 中发生了变化。

Declare refs this way.

以这种方式声明引用。

  <View
    ref={(image) => {
    this._image = image
  }}>

And find the value this way.

并以这种方式找到价值。

  _measure = () => {
    this._image._component.measure((width, height, px, py, fx, fy) => {
      const location = {
        fx: fx,
        fy: fy,
        px: px,
        py: py,
        width: width,
        height: height
      }
      console.log(location)
    })
  }