How do you allow a user to manually resize a

2020-04-07 18:56发布

I have 2 div elements inside another div, and they are displayed as a block each. So div1 ends up right above div2.

I want to add a "bar" of some kind that the user can click and drag which will end up resizing div2, and div1 will be automatically resized by the same amount.

The parent of div1 and div2 has style: display:flex;flex-direction:column; and div1 has flex-grow:1 so it automatically resizes.

I want the resize bar to be something like this:

resize Bar

How do I add something like this? Also is there any way I can change the look of it in CSS?

2条回答
对你真心纯属浪费
2楼-- · 2020-04-07 19:06

const resize = document.getElementById('resize');
const handle = document.getElementById('handle');

let yStart;
let height;

handle.addEventListener('mousedown', function($event) {
  yStart = $event.pageY;
  height = resize.offsetHeight;
  handle.addEventListener('mousemove', mousemove);
});

handle.addEventListener('mouseup', function() {
  handle.removeEventListener('mousemove', mousemove);
});

function mousemove($event) {
  resize.style.height = height + ($event.pageY - yStart) + 'px';
}
#resize {
  position: relative;
  border: 1px solid black;
  height: 100px;
  box-sizing: border-box;
}

#handle {
  position: absolute;
  height: 2px;
  width: 100%;
  background: black;
  bottom: 0;
  cursor: row-resize;
}
<div id="resize">
  <div id="handle"></div>
</div>

查看更多
疯言疯语
3楼-- · 2020-04-07 19:12

In your column flexbox you can use resize on one of the divs and adjust the other automatically using flex-grow set to one - the downside is that the slider is not very customizeable:

  • add resize: vertical to one of the flex items
  • add flex: 1 to the other flex item (so that this flex item will adjust automatically in response to the changing height of the other flex item as it is resized)

body {
  margin: 0;
}

.outer {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.block {
  height: 50%;
}

.block-1 {
  background-color: red;
  resize: vertical; /* resize vertical */
  overflow: auto; /* resize works for overflow other than visible */
}

.block-2 {
  background-color: green;
  flex: 1; /* adjust automatically */
}
<div class="outer">
  <div class="block block-1">
    Block 1
  </div>
  <div class="block block-2">
    Block 2
  </div>
</div>


Solution

Instead you can use a mousedown listener that registers a mousemove listener that updates the block-1 height (and reset the mouseup event) - see demo below:

let block = document.querySelector(".block-1"),
  slider = document.querySelector(".slider");

// on mouse down (drag start)
slider.onmousedown = function dragMouseDown(e) {
  // get position of mouse
  let dragX = e.clientY;
  // register a mouse move listener if mouse is down
  document.onmousemove = function onMouseMove(e) {
    // e.clientY will be the position of the mouse as it has moved a bit now
    // offsetHeight is the height of the block-1
    block.style.height = block.offsetHeight + e.clientY - dragX + "px";
    // update variable - till this pos, mouse movement has been handled
    dragX = e.clientY;
  }
  // remove mouse-move listener on mouse-up (drag is finished now)
  document.onmouseup = () => document.onmousemove = document.onmouseup = null;
}
body {
  margin: 0;
}

.outer {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.block {
  height: 50%;
}

.block-1 {
  background-color: red;
  resize: vertical; /* resize vertical */
  overflow: auto; /* resize works for overflow other than visible */
}

.block-2 {
  background-color: green;
  flex: 1; /* adjust automatically */
  min-height: 0;
  overflow: hidden; /* hide overflow on small width */
}

.slider {
  text-align: center;
  letter-spacing: 10px;
  background-color: #dee2e6;
  cursor: row-resize;
  user-select: none; /* disable selection */
}
<div class="outer">
  <div class="block block-1">
    Block 1
  </div>
  <div class="slider">slider</div>
  <div class="block block-2">
    Block 2
  </div>
</div>

查看更多
登录 后发表回答