拖动侧面的条以独立调整元素宽度,页面上任意数量的元素

Drag bar on side to resize element width independently, any number of elements on page

我正在尝试通过自己的句柄独立调整元素 (.box) 的宽度。 通过我收集的内容,只有最后一个元素是可调整大小的。 Min-widthmax-width 应该不是问题,因为它已通过 css.

处理

我愿意:

  1. 通过句柄(.handle)独立调整任何元素(.box)的宽度。 (当它的句柄被拖动时,只有那个框会调整大小)
  2. 优化代码,示例 whenDragging() 函数(现在 'mouseup' 即使我没有调整大小时也会调用事件)- 不确定是否需要?

var isHandlerDragging = false;

var handlers = document.querySelectorAll('.handler');
  for( i=0; i < handlers.length; i++ ){
    var handler = handlers[i];
};
  
var wrappers = document.querySelectorAll('.wrapper');
  for( i=0; i < wrappers.length; i++ ){
    var wrapper = wrappers[i];
};

var boxes = document.querySelectorAll('.box');
  for( i=0; i < boxes.length; i++ ){
    var box = boxes[i];
};

function whenDragging() {
  if(isHandlerDragging === true){
    document.querySelector('*').style.userSelect = "none";
    document.querySelector('*').style.pointerEvents = "none";      
    document.querySelector('*').style.cursor = "ew-resize";
  }else{
    document.querySelector('*').style.cssText = null;
  };
}

document.addEventListener('mousedown', function(e) {
  if (e.target === handler) {
    isHandlerDragging = true;
  }
  whenDragging()
});

document.addEventListener('mousemove', function(e) {
  if (!isHandlerDragging) {
    return false;
  }
  var containerOffsetLeft = wrapper.offsetLeft;
  var pointerRelativeXpos = e.clientX - containerOffsetLeft;
  box.style.width = pointerRelativeXpos + 'px';
});

document.addEventListener('mouseup', function(e) {
  isHandlerDragging = false;
  whenDragging()
});
.wrapper{
  display:flex;
  margin-top:20px;
}

.box{
  width:100%;
  max-width:100%;
  min-width:100px;
  height:50px;
  border:0;
  background-color:black;
}

.handler{
  width:20px;
  flex-shrink:0;
  cursor: ew-resize;
  background-color:red;
}
<div class="wrapper">
  <iframe class="box"></iframe>
  <div class="handler"></div>
</div>

<div class="wrapper">
  <iframe class="box"></iframe>
  <div class="handler"></div>
</div>

此示例中有几个主要特点需要注意:

  • 包装器是弹性盒子,因此我们必须考虑如果我们尝试将它们保持在 100% 宽度但改变内部元素会发生什么情况,假设其中一个的宽度设置为 px 术语
  • 框元素是 iframe。这意味着默认情况下,它们上的任何鼠标事件都不会发生(在这个级别),结果是用户将光标移到它们上面什么都不做。

代码中还有一些其他需要更改的东西 - 特别是对鼠标采取的操作 up/down/move - 问题中的代码一直使用相同的框元素(我认为是错误的) 所以我们将其更改为在与其关联的处理程序上的 mousedown 上拾取当前框。我们还使其成为最大宽度为(其容器的)100% 的包装器,因此不可能将光标向右移动到右手边缘,从而使处理程序离开容器。

const container = document.querySelector('.container');

let box = ''; //initial situation, no box is being dragged

container.addEventListener('mousedown', function(e) {
  if (e.target.classList.contains('handler')) {
    box = e.target.parentElement.querySelector('.box');
  }
});

container.addEventListener('mousemove', function(e) {
  if (box != '') {
   box.parentElement.style.width = (e.clientX + 20) + 'px';
  }
});

container.addEventListener('mouseup', function(e) {//from mouseup
  box = '';
});
.container {
  width: 100%;
  height: 100%;
  overflow: hidden;
  margin: 0;
  padding: 0;
}
.wrapper{
  display:flex;
  margin: 0;
  padding: 0;
  margin-top:20px;
  width: 100%;
  max-width: 100%;
}

.box{
  width:100%;
  display: inline-block;
  /*max-width:100%;*/
  min-width:100px;
  height:50px;
  border:0;
  background-color:black;
  margin: 0;
  padding: 0;
}

.handler{
  display: inline-block;
  width:20px;
  height: 50px;
  flex-shrink:0;
  cursor: ew-resize;
  background-color:red;
  margin: 0;
  padding: 0;
}

iframe {
 pointer-events: none;
}
<div class="container">
  <div class="wrapper">
    <iframe class="box"></iframe>
    <div class="handler"></div>
  </div>

  <div class="wrapper">
    <iframe class="box"></iframe>
    <div class="handler"></div>
  </div>
</div>

注意:现在可以通过将指针事件设置为 none 来查看 iframe 上的鼠标操作。这可能适合也可能不适合现实世界的场景,但它回答了既定的问题。