React,offsetTop,offsetLeft和getBoundingClientRect()不起作用

时间:2016-12-07 13:46:28

标签: javascript reactjs

我正在做反应,我正在创建一个带有工具提示的按钮,但我无法放置它。我的意思是我无法读取按钮与顶部和左侧的距离。

我尝试了offsetTop和offsetLeft,我得到了这个错误:“Uncaught TypeError:无法读取未定义的属性'offsetWidth'”所以我尝试了getBoundingClientRect()并且我得到的是另一个错误:“Uncaught TypeError:elem.getBoundingClientRect不是函数”

我将信息从组件传递到第二个组件,方法是将距离分配给全局变量,并在需要放置时在第二个组件中读取它。

这是我的代码(在舞台上,当我尝试使用getBoundingClientRect时):

import React from 'react';
import ReactDOM from 'react-dom';
import Style from 'style-it'; 
var Ink = require('react-ink');
import FontIcon from '../FontIcon/FontIcon';

var options;

var Tooltip = React.createClass({
  render(){

    var _props = this.props,
      style = {
          top: options.y,
          left: options.x,
      };

    return(
      <div className="tooltip" style={style}>{_props.text}</div>
    );
  }
});

var IconButton = React.createClass({ 

  getInitialState() {
      return {
          iconStyle: "",
          style: "",
          cursorPos: {},
      };
  },

  extend(obj, src) {
      Object.keys(src).forEach(function(key) { obj[key] = src[key]; });
      return obj;
  },

  render() {

    var _props = this.props,
      opts = {},
      disabled = false,
      rippleOpacity,
        outterStyleMy = {
        border: "none",
            outline: "none",
            padding: "8px 10px",
        "background-color": "red",
        "border-radius": 100 + "%",
        cursor: "pointer",
        },
        iconStyleMy = {
            "font-size": 12 + "px",
            "text-decoration": "none",
            "text-align": "center",
            display: 'flex',
            'justify-content': 'center',
            'align-items': 'center',
        },
      rippleStyle = {
        color: "rgba(0,0,0,0.5)",
      };

    if (_props.disabled || _props.disableTouchRipple) {
      rippleStyle.opacity = 0;
    };

    this.setState({
      iconStyle: _props.iconStyle
    });

    this.setState({
      style: _props.style
    });

    if (_props.disabled) {
       disabled = true;
    };

    if (this.state.labelStyle) {
        iconStyleMy = this.state.iconStyle;
    };

    if (this.state.style) {
      outterStyleMy = this.state.style;
    };

    if (_props.href) {
      opts.href = _props.href;
    };

    function showTooltip(elem){
      // Here I tried to use offset methods, it's how it looked like:
      // options = {
      //   w: this.refs.button.offsetWidth,
      //   x: this.refs.button.offsetLeft,
      //   y: this.refs.button.offsetTop
      // };

      var rect = elem.getBoundingClientRect();
      options = {
        x: rect.left,
        y: rect.top
      };

    };

    function removeTooltip(elem){
      options = null;
    };

        var buttonStyle = this.extend(outterStyleMy, iconStyleMy);

        return(
        <Style>
        {`
          .IconButton{
            position: relative;
          }
          .IconButton:disabled{
            color: ${_props.disabledColor};
          }
          .btnhref{
            text-decoration: none;
          }
        `}
         <a {...opts} className="btnhref" > 
          <Tooltip text={_props.tooltip} position={this.options} />
          <button ref="button" className={"IconButton" + _props.className} disabled={disabled} style={buttonStyle}
          onMouseEnter={showTooltip(this)} onMouseLeave={removeTooltip(this)} >
            <Ink background={true} style={rippleStyle} opacity={rippleOpacity} />
            <FontIcon className={_props.iconClassName}/>
          </button>
        </a>
        </Style>
        );

  }
});

ReactDOM.render(
 <IconButton href="" className="" iconStyle="" style="" iconClassName="face" disabled="" disableTouchRipple="" tooltip="aaaaa" />,
 document.getElementById('app')
);

我不知道出了什么问题:/感谢您的帮助:)

1 个答案:

答案 0 :(得分:0)

functions showTooltip(elem) and removeTooltip(elem)

应该在render()方法之外并绑定到IconButton上下文。否则,this.refs将不确定。

<button ref="button" 
className={"IconButton" + _props.className} 
disabled={disabled} 
style={buttonStyle}
onMouseEnter={this.showTooltip.bind(this)} 
onMouseLeave={this.removeTooltip.bind(this)} >

另外,我认为showTooltip和removeTooltip函数是错误的。他们应该将事件作为参数,例如::

function showTooltip(event){
  var elem = event.target
  var rect = elem.getBoundingClientRect();
  options = {
    x: rect.left,
    y: rect.top
  };

};
  

但现在我收到了这个错误:&#34; Uncaught TypeError:无法读取   财产&#39; y&#39;未定义&#34;。 Meybe有问题   传递信息的过程?

由于这种结构,你会得到这个错误:

render(){
   var _props = this.props,
         style = {
            top: options.y,
            left: options.x,
         };

         return(
            <div className="tooltip" style={style}>{_props.text}</div>
         );
  }

即使您声明var options之类的内容,您仍然无法保证在Tooltip渲染方法中定义和访问选项。

一般来说 - 你的代码很糟糕。我强烈建议你做一些反应教程,了解状态,道具和反应组件生命周期。 ES6知识也不会受到伤害。