制作拖动栏以调整CSS网格内的div大小 [英] Making a dragbar to resize divs inside CSS grids

查看:57
本文介绍了制作拖动栏以调整CSS网格内的div大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个唯一的容器div中有2个框和一条垂直div线(下面的代码和小提琴)。



我正在使用CSS网格将元素放置在内部容器



我要完成的工作是使用垂直线根据垂直线的位置水平调整两个框的大小。



如果这个问题很笨拙,我很抱歉,我是Web开发的新手,以前仅使用过Python,已经尝试过Google和stackoverflow搜索,但是所有解决方案似乎都过于复杂,通常需要其他库,我



HTML:

  < div class = wrapper> 
< div class = box a> A< / div>
< div class = handler>< / div>
< div class = box b> B< / div>
< / div>

CSS:

  body {
保证金:40px;
}

.wrapper {
display:grid;
grid-template-columns:200px 8px 200px;
grid-gap:10px;
background-color:#fff;
颜色:#444;
}

.box {
background-color:#444;
颜色:#fff;
border-radius:5px;
padding:20px;
字体大小:150%;
调整大小:两者;
}

.handler {
width:3px;
身高:100%;
padding:0px 0;
top:0;
背景:红色;
draggable:是;
}



但是,为了让您理解我将在下面发布的代码,您必须熟悉以下内容:




  • 使用 .addEventListener 进行事件绑定。在这种情况下,我们将结合使用 mousedown mouseup mousemove 确定用户是否在拖动元素的中间

  • CSS flexbox布局






解决方案说明



使用CSS的初始布局



首先,您将要使用CSS flexbox布局框。我们只需在父级上声明 display:flex ,然后使用 flex:1 1 auto (译为 let元素增大,使元素缩小并具有相等的宽度)。此布局仅在页面的初始呈现时有效:

  .wrapper {
/ *使用flexbox * /
显示:flex;
}

.box {
/ *使用box-sizing该元素的外部宽度将与width属性匹配* /
box-sizing:border-box;

/ *允许框扩大和缩小,并确保它们的大小均相等* /
flex:1 1自动;
}



听以拖动交互



您想听可能来自 .handler 元素的鼠标事件,并且想要一个全局标记来记住是否用户是否拖动:

  var handler = document.querySelector('。handler'); 
var isHandlerDragging = false;

然后,您可以使用以下逻辑检查用户是否拖动:

 文档。 addEventListener('mousedown',function(e){
//如果从.handler触发mousedown事件,则将标志切换为true
if(e.target === handler){
isHandlerDragging = true;
}
});

document.addEventListener('mousemove',function(e){
//如果拖动标志为false则不执行任何操作
if(!isHandlerDragging){
return false;
}

//正确设置boxA宽度
// [...更多逻辑在这里...]
});

document.addEventListener('mouseup',function(e){
//关闭鼠标悬停时的拖动标志
isHandlerDragging = false;
}) ;



计算方格A的宽度



现在剩下的就是计算框A的宽度(要在上面的代码中插入 [...更多逻辑此处...] 占位符) ,使其与鼠标的移动相匹配。 Flexbox将确保框B将填充剩余的空间:

  //获取偏移量
var containerOffsetLeft =包装器。 offsetLeft;

//获取相对于容器
的指针的x坐标var pointerRelativeXpos = e.clientX-containerOffsetLeft;

//调整框A
// * 8px是.handler及其内部伪元素
// *之间的左/右间距防止它增长
boxA.style.width =(pointerRelativeXpos-8)+'px';
boxA.style.flexGrow = 0;






工作示例



  var handler = document.querySelector('。handler'); var wrapper = handler.closest('。wrapper '); var boxA = wrapper.querySelector('。box'); var isHandlerDragging = false; document.addEventListener('mousedown',function(e){//如果从.handler触发mousedown事件,则将标志切换为true (e.target === handler){isHandlerDragging = true;}}); document.addEventListener('mousemove',function(e){// //如果(!isHandlerDragging){ false;} //获取偏移量var containerOffsetLeft = wrapper.offsetLeft; //获取相对于容器的指针的x坐标var pointerRelativeXpos = e.clientX-containerOffsetLeft; //在框A上设置的任意最小宽度,否则为inne r内容将折叠为0的宽度var boxAminWidth = 60; //调整框A的大小// * * 8px是.handler及其内部伪元素之间的左/右间距// *将flex-grow设置为0以防止其增大boxA.style.width =(Math.max(boxAminWidth ,pointerRelativeXpos-8))+'px'; boxA.style.flexGrow = 0;}); document.addEventListener('mouseup',function(e){//用户鼠标向上时关闭拖动标志isHandlerDragging = false;});  

  body {margin:40px;}。wrapper {background-color:#fff;颜色:#444; / *使用flexbox * / display:flex;}。box {background-color:#444;颜色:#fff; border-radius:5px;填充:20px;字体大小:150%; / *使用box-sizing,以便元素的外部宽度与width属性匹配* / box-sizing:border-box; / *允许框增大和缩小,并确保它们的大小均相同* / flex:1 1 auto;}。handler {宽度:20px;填充:0;游标:ew-resize; flex:0 0 auto;}。handler :: before {content:’’;显示:块;宽度:4px;高度:100%;背景:红色; margin:0 auto;}  

 < div class =包装器 < div class = box> A< / div> < div class = handler>< / div> < div class = box> B< / div>< / div>  


I have 2 boxes and a vertical div line in one unique container div (code and fiddle below).

I'm using CSS grids to position my elements inside the container

What I'd like to accomplish is to use the vertical line to resize horizontally the two boxes based on the position of the vertical line.

I apologize if the question is noobish, I am new to web development, only used Python before, already tried to google and stackoverflow search but all solutions seem overly complicated and generally require additional libraries, I was looking for something simpler and JS only.

HTML:

<div class="wrapper">
  <div class="box a">A</div>
  <div class="handler"></div>
  <div class="box b">B</div>
</div>

CSS:

body {
  margin: 40px;
}

.wrapper {
  display: grid;
  grid-template-columns: 200px 8px 200px;
  grid-gap: 10px;
  background-color: #fff;
  color: #444;
}

.box {
  background-color: #444;
  color: #fff;
  border-radius: 5px;
  padding: 20px;
  font-size: 150%;
  resize: both;
}

.handler{
    width: 3px;
    height: 100%;
    padding: 0px 0;
    top: 0;
    background: red;
    draggable: true;
}

https://jsfiddle.net/gv8Lwckh/6/

解决方案

What you intend to do can be done using CSS flexbox—there is no need to use CSS grid. The bad news is that HTML + CSS is not so smart that declaring resize and draggable will make the layout flexible and adjustable by user interaction. For that, you will have to use JS. The good news is that this is actually not too complicated.

Here is a quick screen grab of output the code below:

However, for you to understand the code I will post below, you will have to familiarize yourself with:

  • Event binding using .addEventListener. In this case, we will use a combination of mousedown, mouseup and mousemove to determine whether the user is in the middle of dragging the element
  • CSS flexbox layout

Description of the solution

Initial layout using CSS

Firstly, you will want to layout your boxes using CSS flexbox. We simply declare display: flex on the parent, and then use flex: 1 1 auto (which translates to "let the element grow, let the element shrink, and have equal widths). This layout is only valid at the initial rendering of the page:

.wrapper {
  /* Use flexbox */
  display: flex;
}

.box {
  /* Use box-sizing so that element's outerwidth will match width property */
  box-sizing: border-box;

  /* Allow box to grow and shrink, and ensure they are all equally sized */
  flex: 1 1 auto;
}

Listen to drag interaction

You want to listen to mouse events that might have originated from your .handler element, and you want a global flag that remembers whether the user is dragging or not:

var handler = document.querySelector('.handler');
var isHandlerDragging = false;

Then you can use the following logic to check if the user is dragging or not:

document.addEventListener('mousedown', function(e) {
  // If mousedown event is fired from .handler, toggle flag to true
  if (e.target === handler) {
    isHandlerDragging = true;
  }
});

document.addEventListener('mousemove', function(e) {
  // Don't do anything if dragging flag is false
  if (!isHandlerDragging) {
    return false;
  }

  // Set boxA width properly
  // [...more logic here...]
});

document.addEventListener('mouseup', function(e) {
  // Turn off dragging flag when user mouse is up
  isHandlerDragging = false;
});

Computing the width of box A

All you are left with now is to compute the width of box A (to be inserted in the [...more logic here...] placeholder in the code above), so that it matches that of the movement of the mouse. Flexbox will ensure that box B will fill up the remaining space:

// Get offset
var containerOffsetLeft = wrapper.offsetLeft;

// Get x-coordinate of pointer relative to container
var pointerRelativeXpos = e.clientX - containerOffsetLeft;

// Resize box A
// * 8px is the left/right spacing between .handler and its inner pseudo-element
// * Set flex-grow to 0 to prevent it from growing
boxA.style.width = (pointerRelativeXpos - 8) + 'px';
boxA.style.flexGrow = 0;


Working example

var handler = document.querySelector('.handler');
var wrapper = handler.closest('.wrapper');
var boxA = wrapper.querySelector('.box');
var isHandlerDragging = false;

document.addEventListener('mousedown', function(e) {
  // If mousedown event is fired from .handler, toggle flag to true
  if (e.target === handler) {
    isHandlerDragging = true;
  }
});

document.addEventListener('mousemove', function(e) {
  // Don't do anything if dragging flag is false
  if (!isHandlerDragging) {
    return false;
  }

  // Get offset
  var containerOffsetLeft = wrapper.offsetLeft;

  // Get x-coordinate of pointer relative to container
  var pointerRelativeXpos = e.clientX - containerOffsetLeft;
  
  // Arbitrary minimum width set on box A, otherwise its inner content will collapse to width of 0
  var boxAminWidth = 60;

  // Resize box A
  // * 8px is the left/right spacing between .handler and its inner pseudo-element
  // * Set flex-grow to 0 to prevent it from growing
  boxA.style.width = (Math.max(boxAminWidth, pointerRelativeXpos - 8)) + 'px';
  boxA.style.flexGrow = 0;
});

document.addEventListener('mouseup', function(e) {
  // Turn off dragging flag when user mouse is up
  isHandlerDragging = false;
});

body {
  margin: 40px;
}

.wrapper {
  background-color: #fff;
  color: #444;
  /* Use flexbox */
  display: flex;
}

.box {
  background-color: #444;
  color: #fff;
  border-radius: 5px;
  padding: 20px;
  font-size: 150%;
  
  /* Use box-sizing so that element's outerwidth will match width property */
  box-sizing: border-box;
  
  /* Allow box to grow and shrink, and ensure they are all equally sized */
  flex: 1 1 auto;
}

.handler {
  width: 20px;
  padding: 0;
  cursor: ew-resize;
  flex: 0 0 auto;
}

.handler::before {
  content: '';
  display: block;
  width: 4px;
  height: 100%;
  background: red;
  margin: 0 auto;
}

<div class="wrapper">
  <div class="box">A</div>
  <div class="handler"></div>
  <div class="box">B</div>
</div>

这篇关于制作拖动栏以调整CSS网格内的div大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆