【问题标题】:Dynamically sizing elements based on row in flexbox根据 flexbox 中的行动态调整元素大小
【发布时间】:2017-01-08 18:02:58
【问题描述】:

我正在尝试根据每个元素在 flexbox 容器中的哪一行来动态更改按钮大小,类似于:

Internet Radio Genre example

我正在使用 ReactJS 并创建了一个包含各种类型的数组,我希望调整它的大小。我正在映射数组以创建每个按钮,如下所示:

class ButtonContainer extends React.Component {
  constructor(props) {
    super(props);
  };
  render() {
    let items = this.props.data;
    let anItem = items.map((item, i) => {
      return (
      <button className='singleButton'>{item}</button>
    )
    });
    return (<div className='buttonContainer'>{anItem}</div>)
  }
}

和 CSS:

.buttonContainer {
  display:flex;
  flex-flow: row wrap;
  justify-content: space-around;
  margin-top:1.5rem;
}

我想知道是否有办法使用 JS 或 CSS 选择位于特定断点之后的项目?可能有一种完全不同的方式来解决这个问题,我也没有想到。

JSFiddle example

谢谢!

【问题讨论】:

  • 您链接到的 JSFiddle 似乎与您的代码不匹配。它似乎是一个通用的 ReactJS “Hello World”。
  • @Makyen - 链接已更正。感谢您的提醒:)
  • 这在 JavaScript 中当然是可行的。你有你定义的具体尺寸吗?例如,可以根据其行应用于每个按钮的类?
  • @Makyen 我还没有定义具体的尺寸,因为我似乎找不到任何关于如何判断每个元素在哪一行结束的信息

标签: javascript css reactjs flexbox


【解决方案1】:

在 JavaScript 中,您可以通过多种方式获取元素的当前位置。其中之一是element.getBoundingClientRect()。一旦您可以在页面上获得元素的 Y 位置(在这种情况下为 &lt;button&gt; 元素),您就可以确定换行符的位置。

在下面的代码中,当 Y 位置值从一个被更改到下一个元素的变化超过 slopY 时,将确定换行符。我们知道我们从第一行开始,然后从右到左,从上到下。它也适用于从左到右的显示。只有从上到下的遍历很重要。关键是我们知道我们在遇到第二行中的任何按钮之前处理了第一行中的所有按钮,等等。

代码将不同的类应用于每行中的元素 (&lt;buttons&gt;)。此外,为了进行测试,它会更改高度并为每行中的按钮应用不同的背景颜色。

当布局更改时,按钮不会自动保持正确的类(或用于测试的大小和颜色)。因此,如果按钮更改布局(例如,它们所在的容器被调整大小),您将需要重新运行 applyRowClassesMultipleTimes()。这可以通过添加适当的事件处理程序来处理。

在短暂的尝试中,我没有让 ReactJS 在 Stack Overflow sn-p 中运行您的代码。因此,对于下面的 sn-p,我只是复制了您的代码在您链接的 JSFiddle 中生成的 DOM。

下面的代码也是available as a JSFiddle,其中包括你的ReactJS代码。

function applyRowClasses(buttonSelector,rowClassBase){
  //The selector passed as the first argument should select all elements for which
  //  it is desired to have the class applied.
  //The second argument is the text portion of the class to be applied. The row
  //  number (0 at the top) will be appended to that text for the class of each row.
  //  (e.g. 'row' will result in classes 'row0', 'row1', 'row2', etc.)

  var children = document.querySelectorAll(buttonSelector);
  var replaceRowRegExp = new RegExp('\\s*' + rowClassBase + '\\d+(\\b|$)','g');
  var child;
  var testColor = ['red','orange','yellow','green','blue','purple','crimson'
                   ,'cyan','lightgreen','lightblue','Fuchsia'];
  var row = -1;
  var rowY = 0;
  var slopY = 5;
  var newHeight = 120;
  var newHeightDelta = -10;
  for(var i=0,numChildren=children.length;i<numChildren;i++) {
    child = children[i];
    var rect = child.getBoundingClientRect();
    if(rect.top > rowY+slopY){
      //New row
      row++;
      rowY = rect.top;
      newHeight += newHeightDelta;
    }
    var childClass = child.className;
    //Remove any old row class.  Need to do this because we would need to re-apply
    //  these classes when the window size changes, or if the layout changes
    //  in response to the changes we are making here.
    childClass = childClass.replace(replaceRowRegExp,'');
    childClass += ' ' + rowClassBase + row;
    child.className = childClass;
    //For testing change background color and height
    child.style.backgroundColor = testColor[(row % testColor.length)];
    child.style.height = newHeight + 'px';
  }
}

function applyRowClassesMultipleTimes(buttonSelector,rowClassBase,count){
  //Our changes may affect the button layout. Change
  //  multiple times giving the browser a chance to re-draw.
  //  We could calculate what our changes will be, but it's just as
  //  easy to iterate a few times.
  if(count<=1){
    return;
  }
  applyRowClasses(buttonSelector,rowClassBase);
  count--;
  setTimeout(applyRowClassesMultipleTimes,0,buttonSelector,rowClassBase,count);
}

applyRowClassesMultipleTimes('#root button','row',4);
#root {
  display:flex;
  color:#444;
}

.buttonContainer {
  display:flex;
  flex-flow: row wrap;
  justify-content: space-around;
  margin-top:1.5rem;
}
<body>
<div xmlns="http://www.w3.org/1999/xhtml" id="root"><div data-reactroot=""><div>Popular Genres</div><div class="buttonContainer"><button class="singleButton">Jazz</button><button class="singleButton">Top 40</button><button class="singleButton">Country</button><button class="singleButton">Blues</button><button class="singleButton">Easy Listening</button><button class="singleButton">Rock</button><button class="singleButton">Classical</button><button class="singleButton">Chillout</button><button class="singleButton">80s</button><button class="singleButton">Oldies</button><button class="singleButton">Dance</button><button class="singleButton">Ambient</button><button class="singleButton">Reggae</button><button class="singleButton">Trance</button><button class="singleButton">Hip Hop</button><button class="singleButton">Smooth Jazz</button><button class="singleButton">70s</button><button class="singleButton">House</button><button class="singleButton">Lounge</button><button class="singleButton">Drum and Bass</button><button class="singleButton">Metal</button><button class="singleButton">Meditation</button><button class="singleButton">Heavy Metal</button><button class="singleButton">60s</button><button class="singleButton">Techno</button><button class="singleButton">Pop</button><button class="singleButton">Soul</button><button class="singleButton">90s</button><button class="singleButton">Psytrance</button><button class="singleButton">Latin</button><button class="singleButton">Funk</button><button class="singleButton">Rap</button><button class="singleButton">Bollywood</button><button class="singleButton">50s</button><button class="singleButton">Hindi</button><button class="singleButton">Rockabilly</button><button class="singleButton">Minimal</button><button class="singleButton">Greek</button><button class="singleButton">Comedy</button><button class="singleButton">Alternative</button><button class="singleButton">Reggaeton</button><button class="singleButton">New Age</button><button class="singleButton">Salsa</button><button class="singleButton">Bluegrass</button><button class="singleButton">edm</button><button class="singleButton">Manele</button><button class="singleButton">Indie</button><button class="singleButton">Japanese</button><button class="singleButton">Dancehall</button><button class="singleButton">Classic Rock</button><button class="singleButton">Disco</button><button class="singleButton">Dubstep</button><button class="singleButton">Folk</button><button class="singleButton">goth</button><button class="singleButton">Punk</button><button class="singleButton">Garage</button><button class="singleButton">New Wave</button></div></div></div>
</body>

以下是未应用颜色和大小的按钮的外观:

#root {
  display:flex;
  color:#444;
}

.buttonContainer {
  display:flex;
  flex-flow: row wrap;
  justify-content: space-around;
  margin-top:1.5rem;
}
<body>
<div xmlns="http://www.w3.org/1999/xhtml" id="root"><div data-reactroot=""><div>Popular Genres</div><div class="buttonContainer"><button class="singleButton">Jazz</button><button class="singleButton">Top 40</button><button class="singleButton">Country</button><button class="singleButton">Blues</button><button class="singleButton">Easy Listening</button><button class="singleButton">Rock</button><button class="singleButton">Classical</button><button class="singleButton">Chillout</button><button class="singleButton">80s</button><button class="singleButton">Oldies</button><button class="singleButton">Dance</button><button class="singleButton">Ambient</button><button class="singleButton">Reggae</button><button class="singleButton">Trance</button><button class="singleButton">Hip Hop</button><button class="singleButton">Smooth Jazz</button><button class="singleButton">70s</button><button class="singleButton">House</button><button class="singleButton">Lounge</button><button class="singleButton">Drum and Bass</button><button class="singleButton">Metal</button><button class="singleButton">Meditation</button><button class="singleButton">Heavy Metal</button><button class="singleButton">60s</button><button class="singleButton">Techno</button><button class="singleButton">Pop</button><button class="singleButton">Soul</button><button class="singleButton">90s</button><button class="singleButton">Psytrance</button><button class="singleButton">Latin</button><button class="singleButton">Funk</button><button class="singleButton">Rap</button><button class="singleButton">Bollywood</button><button class="singleButton">50s</button><button class="singleButton">Hindi</button><button class="singleButton">Rockabilly</button><button class="singleButton">Minimal</button><button class="singleButton">Greek</button><button class="singleButton">Comedy</button><button class="singleButton">Alternative</button><button class="singleButton">Reggaeton</button><button class="singleButton">New Age</button><button class="singleButton">Salsa</button><button class="singleButton">Bluegrass</button><button class="singleButton">edm</button><button class="singleButton">Manele</button><button class="singleButton">Indie</button><button class="singleButton">Japanese</button><button class="singleButton">Dancehall</button><button class="singleButton">Classic Rock</button><button class="singleButton">Disco</button><button class="singleButton">Dubstep</button><button class="singleButton">Folk</button><button class="singleButton">goth</button><button class="singleButton">Punk</button><button class="singleButton">Garage</button><button class="singleButton">New Wave</button></div></div></div>
</body>

【讨论】:

    猜你喜欢
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    • 2013-05-19
    • 1970-01-01
    相关资源
    最近更新 更多