Javascript 在 ReactJS 中获取视口/窗口高度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36862334/
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
Get viewport/window height in ReactJS
提问by Jabran Saeed
How do I get the viewport height in ReactJS? In normal JavaScript I use
如何在 ReactJS 中获取视口高度?在普通的 JavaScript 中,我使用
window.innerHeight()
but using ReactJS, I'm not sure how to get this information. My understanding is that
但是使用 ReactJS,我不确定如何获取此信息。我的理解是
ReactDOM.findDomNode()
only works for components created. However this is not the case for the document
or body
element, which could give me height of the window.
仅适用于创建的组件。然而,这不是document
orbody
元素的情况,它可以给我窗口的高度。
采纳答案by Jabran Saeed
class AppComponent extends React.Component {
constructor(props) {
super(props);
this.state = {height: props.height};
}
componentWillMount(){
this.setState({height: window.innerHeight + 'px'});
}
render() {
// render your component...
}
}
Set the props
设置道具
AppComponent.propTypes = {
height:React.PropTypes.string
};
AppComponent.defaultProps = {
height:'500px'
};
viewport height is now available as {this.state.height} in rendering template
视口高度现在可用作渲染模板中的 {this.state.height}
回答by speckledcarp
This answer is similar to Jabran Saeed's, except it handles window resizing as well. I got it from here.
这个答案类似于 Jabran Saeed 的,除了它也处理窗口大小调整。我从这里得到的。
constructor(props) {
super(props);
this.state = { width: 0, height: 0 };
this.updateWindowDimensions = this.updateWindowDimensions.bind(this);
}
componentDidMount() {
this.updateWindowDimensions();
window.addEventListener('resize', this.updateWindowDimensions);
}
componentWillUnmount() {
window.removeEventListener('resize', this.updateWindowDimensions);
}
updateWindowDimensions() {
this.setState({ width: window.innerWidth, height: window.innerHeight });
}
回答by QoP
Using Hooks (React 16.8.0+
)
使用钩子 (React 16.8.0+
)
Create a useWindowDimensions
hook.
创建一个useWindowDimensions
钩子。
import { useState, useEffect } from 'react';
function getWindowDimensions() {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height
};
}
export default function useWindowDimensions() {
const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
useEffect(() => {
function handleResize() {
setWindowDimensions(getWindowDimensions());
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, []);
return windowDimensions;
}
And after that you'll be able to use it in your components like this
之后你就可以像这样在你的组件中使用它
const Component = () => {
const { height, width } = useWindowDimensions();
return (
<div>
width: {width} ~ height: {height}
</div>
);
}
Original answer
原答案
It's the same in React, you can use window.innerHeight
to get the current viewport's height.
在 React 中也是如此,您可以使用它window.innerHeight
来获取当前视口的高度。
As you can see here
正如你在这里看到的
回答by giovannipds
I've just edited QoP's current answerto support SSRand use it with Next.js(React 16.8.0+):
我刚刚编辑了QoP的当前答案以支持SSR并将其与Next.js(React 16.8.0+) 一起使用:
/hooks/useWindowDimensions.js:
/hooks/useWindowDimensions.js:
import { useState, useEffect } from 'react';
export default function useWindowDimensions() {
const hasWindow = typeof window !== 'undefined';
function getWindowDimensions() {
const width = hasWindow ? window.innerWidth : null;
const height = hasWindow ? window.innerHeight : null;
return {
width,
height,
};
}
const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
useEffect(() => {
if (hasWindow) {
function handleResize() {
setWindowDimensions(getWindowDimensions());
}
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}
}, [hasWindow]);
return windowDimensions;
}
/yourComponent.js:
/你的组件.js:
import useWindowDimensions from './hooks/useWindowDimensions';
const Component = () => {
const { height, width } = useWindowDimensions();
/* you can also use default values or alias to use only one prop: */
// const { height: windowHeight = 480 } useWindowDimensions();
return (
<div>
width: {width} ~ height: {height}
</div>
);
}
回答by James L.
@speckledcarp 's answer is great, but can be tedious if you need this logic in multiple components. You can refactor it as an HOC (higher order component)to make this logic easier to reuse.
@speckledcarp 的回答很好,但如果您需要在多个组件中使用此逻辑,则可能会很乏味。您可以将其重构为HOC(高阶组件),以使此逻辑更易于重用。
withWindowDimensions.jsx
withWindowDimensions.jsx
import React, { Component } from "react";
export default function withWindowDimensions(WrappedComponent) {
return class extends Component {
state = { width: 0, height: 0 };
componentDidMount() {
this.updateWindowDimensions();
window.addEventListener("resize", this.updateWindowDimensions);
}
componentWillUnmount() {
window.removeEventListener("resize", this.updateWindowDimensions);
}
updateWindowDimensions = () => {
this.setState({ width: window.innerWidth, height: window.innerHeight });
};
render() {
return (
<WrappedComponent
{...this.props}
windowWidth={this.state.width}
windowHeight={this.state.height}
isMobileSized={this.state.width < 700}
/>
);
}
};
}
Then in your main component:
然后在您的主要组件中:
import withWindowDimensions from './withWindowDimensions.jsx';
class MyComponent extends Component {
render(){
if(this.props.isMobileSized) return <p>It's short</p>;
else return <p>It's not short</p>;
}
export default withWindowDimensions(MyComponent);
You can also "stack" HOCs if you have another you need to use, e.g. withRouter(withWindowDimensions(MyComponent))
如果您需要使用另一个 HOC,您也可以“堆叠” HOC,例如 withRouter(withWindowDimensions(MyComponent))
Edit: I would go with a React hook nowadays (example above here), as they solve some of the advanced issues with HOCs and classes
回答by thielr7
I just spent some serious time figuring some things out with React and scrolling events / positions - so for those still looking, here's what I found:
我只是花了一些时间用 React 和滚动事件/位置来解决一些问题 - 所以对于那些仍在寻找的人,这是我发现的:
The viewport height can be found by using window.innerHeight or by using document.documentElement.clientHeight. (Current viewport height)
可以使用 window.innerHeight 或使用 document.documentElement.clientHeight 找到视口高度。(当前视口高度)
The height of the entire document (body) can be found using window.document.body.offsetHeight.
可以使用 window.document.body.offsetHeight 找到整个文档(正文)的高度。
If you're attempting to find the height of the document and know when you've hit the bottom - here's what I came up with:
如果您试图找到文档的高度并知道何时到达底部 - 这就是我想出的:
if (window.pageYOffset >= this.myRefII.current.clientHeight && Math.round((document.documentElement.scrollTop + window.innerHeight)) < document.documentElement.scrollHeight - 72) {
this.setState({
trueOrNot: true
});
} else {
this.setState({
trueOrNot: false
});
}
}
(My navbar was 72px in fixed position, thus the -72 to get a better scroll-event trigger)
(我的导航栏在固定位置是 72px,因此 -72 以获得更好的滚动事件触发器)
Lastly, here are a number of scroll commands to console.log(), which helped me figure out my math actively.
最后,这里有一些 console.log() 的滚动命令,它们帮助我积极地计算出我的数学。
console.log('window inner height: ', window.innerHeight);
console.log('document Element client hieght: ', document.documentElement.clientHeight);
console.log('document Element scroll hieght: ', document.documentElement.scrollHeight);
console.log('document Element offset height: ', document.documentElement.offsetHeight);
console.log('document element scrolltop: ', document.documentElement.scrollTop);
console.log('window page Y Offset: ', window.pageYOffset);
console.log('window document body offsetheight: ', window.document.body.offsetHeight);
Whew! Hope it helps someone!
哇!希望它可以帮助某人!
回答by thclark
Answers by @speckledcarp and @Jamesl are both brilliant. In my case, however, I needed a component whose height could extend the full window height, conditional at render time.... but calling a HOC within render()
re-renders the entire subtree. BAAAD.
@speckledcarp 和 @Jamesl 的回答都很精彩。然而,在我的情况下,我需要一个组件,其高度可以扩展整个窗口的高度,在渲染时有条件......但是在内部调用 HOC 会render()
重新渲染整个子树。巴阿德。
Plus, I wasn't interested in getting the values as props but simply wanted a parent div
that would occupy the entire screen height (or width, or both).
另外,我对将值作为道具不感兴趣,只是想要一个div
占据整个屏幕高度(或宽度,或两者)的父级。
So I wrote a Parent component providing a full height (and/or width) div. Boom.
所以我写了一个提供全高(和/或宽度)div 的父组件。繁荣。
A use case:
一个用例:
class MyPage extends React.Component {
render() {
const { data, ...rest } = this.props
return data ? (
// My app uses templates which misbehave badly if you manually mess around with the container height, so leave the height alone here.
<div>Yay! render a page with some data. </div>
) : (
<FullArea vertical>
// You're now in a full height div, so containers will vertically justify properly
<GridContainer justify="center" alignItems="center" style={{ height: "inherit" }}>
<GridItem xs={12} sm={6}>
Page loading!
</GridItem>
</GridContainer>
</FullArea>
)
Here's the component:
这是组件:
import React, { Component } from 'react'
import PropTypes from 'prop-types'
class FullArea extends Component {
constructor(props) {
super(props)
this.state = {
width: 0,
height: 0,
}
this.getStyles = this.getStyles.bind(this)
this.updateWindowDimensions = this.updateWindowDimensions.bind(this)
}
componentDidMount() {
this.updateWindowDimensions()
window.addEventListener('resize', this.updateWindowDimensions)
}
componentWillUnmount() {
window.removeEventListener('resize', this.updateWindowDimensions)
}
getStyles(vertical, horizontal) {
const styles = {}
if (vertical) {
styles.height = `${this.state.height}px`
}
if (horizontal) {
styles.width = `${this.state.width}px`
}
return styles
}
updateWindowDimensions() {
this.setState({ width: window.innerWidth, height: window.innerHeight })
}
render() {
const { vertical, horizontal } = this.props
return (
<div style={this.getStyles(vertical, horizontal)} >
{this.props.children}
</div>
)
}
}
FullArea.defaultProps = {
horizontal: false,
vertical: false,
}
FullArea.propTypes = {
horizontal: PropTypes.bool,
vertical: PropTypes.bool,
}
export default FullArea
回答by Joabe
// just use (useEffect). every change will be logged with current value
import React, { useEffect } from "react";
export function () {
useEffect(() => {
window.addEventListener('resize', () => {
const myWidth = window.innerWidth;
console.log('my width :::', myWidth)
})
},[window])
return (
<>
enter code here
</>
)
}
回答by Shubham Verma
You can also try this:
你也可以试试这个:
constructor(props) {
super(props);
this.state = {height: props.height, width:props.width};
}
componentWillMount(){
console.log("WINDOW : ",window);
this.setState({height: window.innerHeight + 'px',width:window.innerWidth+'px'});
}
render() {
console.log("VIEW : ",this.state);
}