【问题标题】:ReactJS - put overflown elements into a "..." dropdown buttonReactJS - 将溢出的元素放入“...”下拉按钮
【发布时间】:2016-03-19 03:15:55
【问题描述】:

我的页面顶部有以下 UI 元素:

|[Static1] [Dynamic1] [Dynamic2] [Dynamic3]                [Static2]|

所以Static1 是一些粘在左边的标志组件,Static2 是一些粘在右边的用户菜单组件。

现在在其中我有一个集合组件,它显示从数据库加载的几个动态元素。

一切都很好,如果这些组件不是太多,但如果有更多,我不想要任何换行符,只有一些“更多”菜单的堡垒,比如:

|[Static1] [Dynamic1] [Dynamic2] [Dynamic3] [Dynamic4][...][Static2]|

当我点击[...] 按钮时,我不需要动态组件的垂直列表。

动态项列表存储在ElementList 组件中,代码如下:

React.createClass({
    render() {
        return (
            <div ref="listparent">
                { this.props.elements.map((element) => {
                    return <Element
                        ref={"element-"+element.name}
                        key={element.name}
                    })}
            </div>
        )
    }
});

this.props.elements 是作为道具传递的集合。我在这些方面尝试了一些方法,但它要么不起作用,要么起作用,但不是在每次页面刷新时:

export default React.createClass({
        getInitialState(){
            return {
                visibleElements: this.props.elements,
                hiddenElements: []
            }
        },
        componentDidMount() {
            this.rearrange();
        },
        componentDidUpdate(){
            this.rearrange();
        },
        rearrange(){
            var element = ReactDOM.findDOMNode(this.refs.listparent);
            let visibleElements = [];
            let hiddenElements = [];
            for(var i=0; i< this.props.elements.length; i++)
            {
                var currentElement = this.props.elements[i];
                var domElement = ReactDOM.findDOMNode(this.refs["element-"+element.name]);
                if(domElement) {
                    if (domElement.offsetTop + domElement.offsetHeight >
                        element.offsetTop + element.offsetHeight ||
                        domElement.offsetLeft + domElement.offsetWidth >
                        element.offsetLeft + element.offsetWidth - 200) {
                        hiddenElements.push(currentElement);
                    }
                    else {
                        visibleElements.push(currentElement);
                    }
                }
            }
            if(this.state.visibleElements.length != visibleElements.length) {
                this.setState({
                    visibleElements: visibleElements,
                    hiddenElements: hiddenElements
                })
            }
        },
        render() {
            return (
                <div ref="listparent">
                    { this.state.visibleElements.map((element) => {
                        return <Element
                            ref={"element-"+element.name}
                            key={element.name} />
                        })}
                    { this.state.hiddenElements.length >0 &&
                            <DropdownMenu
                                Header="..."
                            >
                                { this.state.hiddenElements.map((element) => {
                                    return <Element
                                        ref={"element-"+element.name}
                                        key={element.name} />
                                    })}
                            </DropdownMenu>
                    }
                </div>
            )
        }
    });

这是一个粗略的 jsFiddle 我想做的事:https://jsfiddle.net/3uf9r8ne/

【问题讨论】:

    标签: javascript html dom reactjs


    【解决方案1】:

    得到它的工作,我不知道这是否是最好的解决方案,或者它有多强大,但至少现在对我有用。

    JsFiddle:https://jsfiddle.net/1w6m1n6h/

    var Dropdown = React.createClass({
        getInitialState(){
          return {
              isOpen: false
          }
        },
        componentWillMount() {
            document.addEventListener('click', this.handleClick, false);
        },
        componentWillUnmount() {
            document.removeEventListener('click', this.handleClick, false);
        },
        handleClick: function (e) {
            var component = ReactDOM.findDOMNode(this.refs.component);
            if (e.target == component || $(component).has(e.target).length) {
                // Inside the component
            }
            else{
                // Outide
                this.setState({ isOpen: false});
            }
        },
        render()
        {
            return (
              <div ref="component" className="dropdown">
                  <div className="dropdown-button" onClick={() => this.setState({ isOpen : !this.state.isOpen})}>{this.props.Header}</div>
                  {
                        this.state.isOpen && (
                            <div className="dropdown-menu"  onClick={() => this.setState({ isOpen : false})}>
                                {React.Children.map(this.props.children, (item) => item)}
                            </div>
                            )
                  }
              </div>
            );
        }
    });
    
    var Card = React.createClass({
      render() {
        let className = "card";
        if(this.props.isHidden)
           className += " is-hidden";
        return (
          <div className={className}>{this.props.name}</div>
        )
      }
    });
    
    var Cards = React.createClass({
     getInitialState() {
     		return {
        		vCards: [],
            hCards: [],
            lastSetCards: [],
            preMounted: false,
            laidOut: false
        };
     },
     rearrange() {
     		_.throttle(this.setState({laidOut: false, preMounted: false}), 100);
     },
       componentDidMount() {
        window.addEventListener('resize', this.rearrange);
      },
      componentWillUnmount() {
        window.removeEventListener('resize', this.rearrange);
      },
     componentDidUpdate() {
        if(this.props.cards.length != this.state.lastSetCards || !this.state.preMounted) {
        	
        	this.setState({
                    lastSetCards: this.props.cards.length,
                    vCards: this.props.cards,
                    preMounted: true,
                    laidOut: false
                    });
        }
        if(this.state.preMounted && !this.state.laidOut) {
             var element = ReactDOM.findDOMNode(this.refs.listparent);
            let visibleCards = [];
            let hiddenCards = [];
            for(var i=0; i< this.props.cards.length; i++)
            {
                var card = this.props.cards[i];
                var cardElement = ReactDOM.findDOMNode(this.refs["card-"+card]);
                if(cardElement) {
                    if (cardElement.offsetTop + cardElement.offsetHeight >
                        element.offsetTop + element.offsetHeight ||
                        cardElement.offsetLeft + cardElement.offsetWidth >
                        element.offsetLeft + element.offsetWidth - 160) {
                        hiddenCards.push(card);
                    }
                    else {
                        visibleCards.push(card);
                    }
                }
            }
            this.setState({
            		vCards: visibleCards,
                hCards: hiddenCards,
                laidOut: true
            });
        }
     },
     render() {
         return (<div className="cards-top" ref="listparent">
         				<div className="cards" >
                {this.state.vCards.map((c)=> <Card ref={"card-"+c} key={c} name={c} />)}
                </div>
                <Dropdown Header="MORE">
                {this.state.hCards.map((c)=> <Card isHidden={true} key={c} name={c} />)}
                </Dropdown>
                </div>
                )
     }
    });
    
    var Hello = React.createClass({
    		getInitialState() {
        		return {
        		cards: ["one", "two" ]
                    };
        },
        componentDidMount() {
        		this.setState({
            		cards: ["one", "two", "three", "four", "five", "six", "seven", "eight",
            				"nine", "ten", "eleven", "twelve", "thirteen", "fourteen"]
            });
        },
        render: function() {
        		let addNew = () => { 
            			this.state.cards.push("additional_"+this.state.cards.length);
                  this.setState({
                  		cards: this.state.cards
                  })
    			  };
            return (
            <div>
            <div className="header">
            		<div className="logo">Logo</div>
                <div className="user">User</div>
                <Cards cards={this.state.cards} />
                <div className="clear"></div>
            </div>
            <br/><br/>
            <button onClick={addNew}>Add</button>
            </div>);
        }
    });
     
    ReactDOM.render(
    	<Hello name="World" />,
        document.getElementById('container')
    );
    .logo
    {
      float: left;
        margin: 5px;
      padding: 5px;
      border: solid 1px blue;
    }
    
    .user
    {
      float: right;
        margin: 5px;
      padding: 5px;
      border: solid 1px blue;
    }
    
    .header{
      position: relative;
      max-height: 10px;
      height: 10px;
      width: 100%;
    }
    
    .cards
    {
      position: relative;
      display: inline-block;
      vertical-align: top;
      white-space: nowrap;
    }
    
    .clear
    {
      clear: both;
    }
    
    .card
    {
      display: inline-block;
      margin: 5px;
      padding: 5px;
      border: solid 1px blue;
    }
    
    .cards-top
    {
       display: block;  
        white-space: nowrap;
        vertical-align: top;
        width: 100%;
        border: green 1px solid;
    }
    
    .dropdown
    {
      display: inline-block;
    }
    
    .is-hidden
    {
      display: block;
    }
    
    .dropdown-button
    {
      margin: 5px;
      padding: 5px;
      border: solid 1px blue;
    }
    <script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>
    
    <div id="container">
        <!-- This element's contents will be replaced with your component. -->
    </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-21
      • 2019-04-12
      • 1970-01-01
      • 2019-10-05
      • 2012-06-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多