使用纯javascript获取元素的尺寸和位置

时间:2017-04-06 19:24:30

标签: javascript html css html5 reactjs

情况:我想获取元素的尺寸和位置

背景:我正在制作纸牌游戏。卡可以放在板上。我需要能够检查他们的目的地是否在板上。然后,我将相对于电路板的尺寸和位置存储它们的位置。这将有助于在可能使用不同屏幕尺寸的许多不同客户端上重现电路板。

当前样式:

电路板的尺寸宽度和高度定义如下:

width: 100%;
flex-grow:1;

它的容器具有以下属性:

display: flex;
flex-direction: column;

Image of Board

您应注意实际尺寸为[942.922x874]。我找不到位置信息,我假设因为默认div位置:静态而不是位置:绝对。

我的尝试:

let board = document.getElementById("gameboard");
if (board) {
  console.log("style.height", board.style.height);
  console.log("style.width", board.style.width);
  console.log("offsetHeight", board.offsetHeight);
  console.log("offsetWidth", board.offsetWidth);
  console.log("getBoundingClientRect" , board.getBoundingClientRect());
}

Output of my attempts

请注意,输出尺寸与实际尺寸不同。 [1137,920]而不是[942.922x874]。 [1137,920]实际上是整个身体的尺寸。无论我做什么来获得位置,它总是给我[0,0]。

修改-1

我们得出的结论是,这可能是一个时间问题。我需要确保在呈现元素之后运行检索维度和位置的代码。由于我正在使用react,我找到了这个帖子,ReactJS - Get Height of an element。这基本上说我需要挂钩React的组件生命周期方法componentDidMount(),它在渲染完成后立即运行。你可以在下面看到我的实现。但是,即使有了这个实现,我似乎仍然得到了body容器的尺寸而不是我正在访问的元素。

import React, {PureComponent, PropTypes} from 'react';
// import Card from '../../Components/Card/index.js';
// import Collection from '../../Components/Collection/index.js';
import {List} from 'immutable';
import Indicator from '../../Components/Indicator/index.js';
import Counter from '../../Components/Counter/index.js';
import {connect} from 'react-redux';
import * as actionCreators from './../../action_creators.js';
import './styles.scss';

export default class Game extends PureComponent {
  componentDidMount() {
    let board = document.getElementById("gameboard");
    console.log("getBoundingClientRect" , board.getBoundingClientRect());
  }
  render() {
    let playersById = this.props.playersById;
    let collections = this.props.collections;
    let counters = this.props.counters;

    let indic_list = [];
    let coll_list = [];

    //Indicators
    playersById.forEach(function(value, key, map){
      indic_list.push(<p className="section-name">{playersById.get(key).get('name')+"'s Indicators"}</p>)
      playersById.get(key).get('indicators').forEach(function(value, key2, map){
          indic_list.push(<Indicator playerId={key} action={this.props.modIndicator} label={key2}>{value}</Indicator>)
      }, this);
    },this);

    //Collections
    collections.forEach(function(value, key, map) {
      coll_list.push(<span>{key}: {collections.get(key).get("content").size}</span>);
      collections.get(key).get("control").forEach(function(value, key, map){
          coll_list.push(<span>Control: {value}</span>);
      });
    });

    return (
        <div className="frame">
          <div className="left-col">
            {indic_list}
          </div>
          <div className="center-col">
            <span className="collections">
              {coll_list}
            </span>
            <div id="gameboard"></div>
          </div>
          <div className="right-col">
            <div className="counters">
              {counters.map(function(type){
                return <Counter label={type}></Counter>
              })}
            </div>
          </div>
        </div>
      )
  }
}
Game.PropTypes = {
  playersById:  PropTypes.object.isRequired,
  collections: PropTypes.object.isRequired,
  counters: PropTypes.object.isRequired,
  modIndicator: PropTypes.func.isRequired
}
function mapStateToProps(state) {
  return {
    playersById: state.get('playersById') || new List(),
    collections: state.get('collections') || new List(),
    counters: state.get('counters') || new List()
  };
}
export const GameContainer = connect(mapStateToProps, actionCreators)(Game);

编辑-2解决方案 我的问题的解决方案来自这个线程。 Get the height of a Component in React

以下是我的代码中的实现。

import React, {PureComponent, PropTypes} from 'react';
// import Card from '../../Components/Card/index.js';
// import Collection from '../../Components/Collection/index.js';
import {List} from 'immutable';
import Indicator from '../../Components/Indicator/index.js';
import Counter from '../../Components/Counter/index.js';
import {connect} from 'react-redux';
import * as actionCreators from './../../action_creators.js';
import './styles.scss';

export default class Game extends PureComponent {
  render() {
    let playersById = this.props.playersById;
    let collections = this.props.collections;
    let counters = this.props.counters;

    let indic_list = [];
    let coll_list = [];

    //Indicators
    playersById.forEach(function(value, key, map){
      indic_list.push(<p className="section-name">{playersById.get(key).get('name')+"'s Indicators"}</p>)
      playersById.get(key).get('indicators').forEach(function(value, key2, map){
          indic_list.push(<Indicator playerId={key} action={this.props.modIndicator} label={key2}>{value}</Indicator>)
      }, this);
    },this);

    //Collections
    collections.forEach(function(value, key, map) {
      coll_list.push(<span>{key}: {collections.get(key).get("content").size}</span>);
      collections.get(key).get("control").forEach(function(value, key, map){
          coll_list.push(<span>Control: {value}</span>);
      });
    });

    return (
        <div className="frame">
          <div className="left-col">
            {indic_list}
          </div>
          <div className="center-col">
            <span className="collections">
              {coll_list}
            </span>
            <div id="gameboard" ref={(node) => this.calcHeight(node)}></div>
          </div>
          <div className="right-col">
            <div className="counters">
              {counters.map(function(type){
                return <Counter label={type}></Counter>
              })}
            </div>
          </div>
        </div>
      )
  }
  calcHeight(node){
    if (node) {
        console.log("calcHeight", node.getBoundingClientRect());
      }
  }
}
Game.PropTypes = {
  playersById:  PropTypes.object.isRequired,
  collections: PropTypes.object.isRequired,
  counters: PropTypes.object.isRequired,
  modIndicator: PropTypes.func.isRequired
}
function mapStateToProps(state) {
  return {
    playersById: state.get('playersById') || new List(),
    collections: state.get('collections') || new List(),
    counters: state.get('counters') || new List()
  };
}
export const GameContainer = connect(mapStateToProps, actionCreators)(Game);

2 个答案:

答案 0 :(得分:1)

正如我在最后的编辑中所述,此问题的解决方案来自此主题。 Get the height of a Component in React答案受到SmokeyPHP的评论的影响,我在尝试在实际呈现元素之前访问属性。我需要确保之后访问它们以获得准确的信息。

答案 1 :(得分:-1)

您应该使用.offsetWidth.offsetHeight属性。

注意它们属于元素,而非.style。

var width = document.getElementById('foo').offsetWidth;