【问题标题】:Draggable split-pane windows in flexbox can't get past child elements [duplicate]flexbox中的可拖动拆分窗格窗口无法越过子元素[重复]
【发布时间】:2016-09-29 08:22:18
【问题描述】:

我用 HTML/JS/CSS Flexbox 实现了我自己的拆分窗格。

在以下情况下,我遇到了拆分器的问题 - 其中一个面板具有固定大小(以 px 为单位),而另一个面板设置为增长 (flex-grow: 1)。

如果另一个面板有大小的子级,它不会滚动到最后。它卡在孩子的大小上。

能否在拆分窗格面板上使用 CSS 解决此问题,但在子面板上却不能?

使用 flex 对我来说非常重要,因为我想保持应用程序的响应能力,并希望尽可能避免固定大小。

这是JSFiddle sample 我的问题。

下面给出的代码 sn-p。谢谢!

function startDrag() {
  glass.style = 'display: block;';
  glass.addEventListener('mousemove', drag, false);
}

function endDrag() {
  glass.removeEventListener('mousemove', drag, false);
  glass.style = '';
}

function drag(event) {
  var splitter = getSplitter();
  var panel = document.getElementById('c2');
  var currentWidth = panel.offsetWidth;
  var currentLeft = panel.offsetLeft;
  panel.style.width = (currentWidth - (event.clientX - currentLeft)) + "px";
}

function getSplitter() {
  return document.getElementById('splitter');
}

var con = document.getElementById('container');
var splitter = document.createElement('div');
var glass = document.getElementById('glass');
splitter.className = 'splitter';
splitter.id = 'splitter';
con.insertBefore(splitter, con.lastElementChild);
splitter.addEventListener('mousedown', startDrag, false);
glass.addEventListener('mouseup', endDrag, false);
.container {
  display: flex;
  border: 1px solid;
  width: 500px;
  height: 300px;
  position: absolute;
}
.c1 {
  background-color: blue;
  flex: 1;
  height: 100%;
}
.c2 {
  background-color: green;
  width: 150px;
}
.splitter {
  width: 20px;
  cursor: col-resize;
}
.glass {
  height: 100%;
  width: 100%;
  cursor: col-resize;
  display: none;
  position: absolute;
}
.grandchild {
  background-color: red;
  width: 50px;
  height: 50px;
}
<div id="container" class="container">
  <div id="glass" class="glass"></div>
  <div class="c1">
    <div class="grandchild"></div>
  </div>
  <div id="c2" class="c2"></div>
</div>

【问题讨论】:

    标签: javascript html css flexbox


    【解决方案1】:

    它卡在孩子的大小上

    这是使用 flexbox 时的预期行为。我想如果你想滚动到最后,那么你可以使用position: absolute 来表示相对于c1grandchild

    .grandchild {
      background-color: red;
      width: 50px;
      height: 50px;
      position: absolute;
      top: 0;
      left: 0;
    }
    

    overflow: hidden也给c1

    .c1 {
      background-color: blue;
      flex: 1;
      height: 100%;
      position: relative;
      overflow: hidden;
    }
    

    干杯!

    function startDrag() {
      glass.style = 'display: block;';
      glass.addEventListener('mousemove', drag, false);
    }
    
    function endDrag() {
      glass.removeEventListener('mousemove', drag, false);
      glass.style = '';
    }
    
    function drag(event) {
      var splitter = getSplitter();
      var panel = document.getElementById('c2');
      var currentWidth = panel.offsetWidth;
      var currentLeft = panel.offsetLeft;
      panel.style.width = (currentWidth - (event.clientX - currentLeft)) + "px";
    }
    
    function getSplitter() {
      return document.getElementById('splitter');
    }
    
    var con = document.getElementById('container');
    var splitter = document.createElement('div');
    var glass = document.getElementById('glass');
    splitter.className = 'splitter';
    splitter.id = 'splitter';
    con.insertBefore(splitter, con.lastElementChild);
    splitter.addEventListener('mousedown', startDrag, false);
    glass.addEventListener('mouseup', endDrag, false);
    .container {
      display: flex;
      border: 1px solid;
      width: 500px;
      height: 300px;
      position: absolute;
    }
    
    .c1 {
      background-color: blue;
      flex: 1;
      height: 100%;
      position: relative;
      overflow: hidden;
    }
    
    .c2 {
      background-color: green;
      width: 150px;
    }
    
    .splitter {
      width: 20px;
      cursor: col-resize;
    }
    
    .glass {
      height: 100%;
      width: 100%;
      cursor: col-resize;
      display: none;
      position: absolute;
    }
    
    .grandchild {
      background-color: red;
      width: 50px;
      height: 50px;
      position: absolute;
      top: 0;
      left: 0;
    }
    <div id="container" class="container">
      <div id="glass" class="glass"></div>
      <div class="c1">
        <div class="grandchild"></div>
      </div>
      <div id="c2" class="c2"></div>
    </div>

    解决方案

    所以我猜你的策略应该是使用一个绝对的grandchild 来填充整个侧面板,然后将content 放在里面:

    <div class="grandchild">
      <div class="content"></div>
    </div>
    

    并更改这些样式:

    .grandchild {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
    }
    .grandchild .content{
      background-color: red;
      width: 50px;
      height: 50px;
    }
    

    下面的例子

    function startDrag() {
      glass.style = 'display: block;';
      glass.addEventListener('mousemove', drag, false);
    }
    
    function endDrag() {
      glass.removeEventListener('mousemove', drag, false);
      glass.style = '';
    }
    
    function drag(event) {
      var splitter = getSplitter();
      var panel = document.getElementById('c2');
      var currentWidth = panel.offsetWidth;
      var currentLeft = panel.offsetLeft;
      panel.style.width = (currentWidth - (event.clientX - currentLeft)) + "px";
    }
    
    function getSplitter() {
      return document.getElementById('splitter');
    }
    
    var con = document.getElementById('container');
    var splitter = document.createElement('div');
    var glass = document.getElementById('glass');
    splitter.className = 'splitter';
    splitter.id = 'splitter';
    con.insertBefore(splitter, con.lastElementChild);
    splitter.addEventListener('mousedown', startDrag, false);
    glass.addEventListener('mouseup', endDrag, false);
    .container {
      display: flex;
      border: 1px solid;
      width: 500px;
      height: 300px;
      position: absolute;
    }
    
    .c1 {
      background-color: blue;
      flex: 1;
      height: 100%;
      position: relative;
      overflow: hidden;
    }
    
    .c2 {
      background-color: green;
      width: 150px;
    }
    
    .splitter {
      width: 20px;
      cursor: col-resize;
    }
    
    .glass {
      height: 100%;
      width: 100%;
      cursor: col-resize;
      display: none;
      position: absolute;
    }
    .grandchild {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
    }
    .grandchild .content{
      background-color: red;
      width: 50px;
      height: 50px;
    }
    <div id="container" class="container">
      <div id="glass" class="glass"></div>
      <div class="c1">
        <div class="grandchild">
          <div class="content"></div>
        </div>
      </div>
      <div id="c2" class="c2"></div>
    </div>

    【讨论】:

    • 完美运行。再次感谢。
    【解决方案2】:

    如果另一个面板有大小的子级,它不会滚动到最后。它卡在孩子的大小上。

    这是因为弹性容器的初始设置是弹性项目上的min-width: auto。这意味着默认情况下,弹性项目不能小于其内容的大小。

    能否在拆分窗格面板上使用 CSS 解决此问题,但在子面板上却不能?

    是的。用min-width: 0 或除visible 以外的任何overflow 覆盖默认值:

    .c1 {
      background-color: blue;
      flex: 1;
      height: 100%;
      overflow: hidden; /* or min-width: 0 */
    }
    

    revised fiddle

    function startDrag() {
      glass.style = 'display: block;';
      glass.addEventListener('mousemove', drag, false);
    }
    
    function endDrag() {
      glass.removeEventListener('mousemove', drag, false);
      glass.style = '';
    }
    
    function drag(event) {
      var splitter = getSplitter();
      var panel = document.getElementById('c2');
      var currentWidth = panel.offsetWidth;
      var currentLeft = panel.offsetLeft;
      panel.style.width = (currentWidth - (event.clientX - currentLeft)) + "px";
    }
    
    function getSplitter() {
      return document.getElementById('splitter');
    }
    
    var con = document.getElementById('container');
    var splitter = document.createElement('div');
    var glass = document.getElementById('glass');
    splitter.className = 'splitter';
    splitter.id = 'splitter';
    con.insertBefore(splitter, con.lastElementChild);
    splitter.addEventListener('mousedown', startDrag, false);
    glass.addEventListener('mouseup', endDrag, false);
    .container {
      display: flex;
      border: 1px solid;
      width: 500px;
      height: 300px;
      position: absolute;
    }
    .c1 {
      background-color: blue;
      flex: 1;
      height: 100%;
      overflow: hidden;  
    }
    .c2 {
      background-color: green;
      width: 150px;
    }
    .splitter {
      width: 20px;
      cursor: col-resize;
    }
    .glass {
      height: 100%;
      width: 100%;
      cursor: col-resize;
      display: none;
      position: absolute;
    }
    .grandchild {
      background-color: red;
      width: 50px;
      height: 50px;
    }
    <div id="container" class="container">
      <div id="glass" class="glass"></div>
      <div class="c1">
        <div class="grandchild"></div>
      </div>
      <div id="c2" class="c2"></div>
    </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-17
      • 2016-10-09
      • 1970-01-01
      • 2015-10-30
      • 2016-07-03
      • 2011-10-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多