在边框拖放时调整 div 的大小而不添加额外的标记

IT技术 javascript html css
2021-03-01 00:56:41

我有一个绝对定位的侧面板,我需要通过拖动此边框来更改其宽度。另外我需要在边框悬停时更改光标。是否可以在不添加另一个用于拖动的 div 的情况下执行此操作?

这是标记:

#right_panel {
    position: absolute;
    border-left: solid 3px #ccc;
    width: 100px;
    height: 100%;
    right: 0;
    background-color: #f0f0f0;
}
<body>
    <div id="right_panel"></div>
</body>

我不需要完整的解决方案。A Yes(有文档参考)/No 回答就足够了。我不需要助手的回答div我已经有一个:

var m_pos;
function resize(e){
    var parent = resize_el.parentNode;
    var dx = m_pos - e.x;
    m_pos = e.x;
    parent.style.width = (parseInt(getComputedStyle(parent, '').width) + dx) + "px";
}

var resize_el = document.getElementById("resize");
resize_el.addEventListener("mousedown", function(e){
    m_pos = e.x;
    document.addEventListener("mousemove", resize, false);
}, false);
document.addEventListener("mouseup", function(){
    document.removeEventListener("mousemove", resize, false);
}, false);
#right_panel {
    position: absolute;
    width: 96px;
    padding-left: 4px;
    height: 100%;
    right: 0;
    background-color: #f0f0f0;
}

#resize {
    background-color: #ccc;
    position: absolute;
    left: 0;
    width: 4px;
    height: 100%;
    cursor: w-resize;
}
<body>
    <div id="right_panel">
        <div id="resize"></div>
    </div>
</body>

同样,这是我想要的功能,除了我想删除额外的div.

3个回答

当然可以在没有额外 div 的情况下做到这一点。使用 css and::after创建边框并更改光标。使用MouseEvent.offsetX以确定是否要处理的元素的点击。

在您的示例中,您希望单击主 div,但仅单击前 4 个像素。您可以通过检查e.offsetX < 4您的点击处理程序来做到这一点

const BORDER_SIZE = 4;
const panel = document.getElementById("right_panel");

let m_pos;
function resize(e){
  const dx = m_pos - e.x;
  m_pos = e.x;
  panel.style.width = (parseInt(getComputedStyle(panel, '').width) + dx) + "px";
}

panel.addEventListener("mousedown", function(e){
  if (e.offsetX < BORDER_SIZE) {
    m_pos = e.x;
    document.addEventListener("mousemove", resize, false);
  }
}, false);

document.addEventListener("mouseup", function(){
    document.removeEventListener("mousemove", resize, false);
}, false);
#right_panel {
    position: absolute;
    width: 96px;
    padding-left: 4px;
    height: 100%;
    right: 0;
    background-color: #f0f0ff;
}

#right_panel::after {
    content: '';
    background-color: #ccc;
    position: absolute;
    left: 0;
    width: 4px;
    height: 100%;
    cursor: ew-resize;
}
<body>
    <div id="right_panel"></div>
</body>

这对我来说在 Firefox 上运行良好,但是在 Chrome 上,当右侧面板变得非常窄时,它开始变得疯狂 - 面板收缩的速度比我将鼠标移过的速度还要快。这是因为我使用的是 flexbox 而 Chrome 并没有一直尊重flex-shrink: 0为了解决这个问题,我将包含的行更改getComputedStyle为: panel.style.width = (parseInt(panel.style.width) + dx) + 'px';
2021-04-23 00:56:41
如何resize()将视口限制为特定百分比?
2021-05-11 00:56:41
还有一件事,panel.style.width可能不是数字(''例如可能是),因此您应该检查并回退到getComputedStyle上述内容。第一次resize调用函数时,它将回退到getComputedStyle,但所有其他时候,它将使用panel.style.width
2021-05-11 00:56:41

我希望它可以帮助你

http://jsfiddle.net/T4St6/82/

<div id="container">
    <div id="left_panel"> left content! </div>
    <div id="right_panel">
        <div id="drag"></div> right content!
    </div>
</div>

CSS

body, html {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}
#container {
    width: 100%;
    height: 100%;

}
 #left_panel {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    right: 100px;
    background: grey;
}

#right_panel {
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    width: 200px;
    color:#fff;
    background: black;
}
 #drag {
    position: absolute;
    left: -4px;
    top: 0;
    bottom: 0;
    width: 8px;
    cursor: w-resize;
}

查询

var isResizing = false,
    lastDownX = 0;

$(function () {
    var container = $('#container'),
        left = $('#left_panel'),
        right = $('#right_panel'),
        handle = $('#drag');

    handle.on('mousedown', function (e) {
        isResizing = true;
        lastDownX = e.clientX;
    });

    $(document).on('mousemove', function (e) {
        // we don't want to do anything if we aren't resizing.
        if (!isResizing) 
            return;

        var offsetRight = container.width() - (e.clientX - container.offset().left);

        left.css('right', offsetRight);
        right.css('width', offsetRight);
    }).on('mouseup', function (e) {
        // stop resizing
        isResizing = false;
    });
});
这在引导程序中也可行吗?
2021-04-18 00:56:41
@PirateApp 你能解释一下,你想达到什么目的吗?你想使用 bootstrap.css 吗?
2021-04-22 00:56:41
谢谢。这是一个可行的解决方案,但我正在尝试在没有用于拖动的辅助 div 的情况下执行此操作。
2021-05-10 00:56:41
@PirateApp 是的,这是可能的,您需要找到正确的引导程序 css 类,以及类的混合。
2021-05-12 00:56:41
在 mousemove 回调末尾添加“return false”以防止在 div 中选择文本。
2021-05-17 00:56:41

没有 jQuery:

var isResizing = false;

(function() {
  var container = document.getElementById("container"),
    left = document.getElementById("left_panel"),
    right = document.getElementById("right_panel"),
    handle = document.getElementById("drag");

  handle.onmousedown = function(e) {
    isResizing = true;
  };

  document.onmousemove = function(e) {
    // we don't want to do anything if we aren't resizing.
    if (!isResizing) {
      return;
    }

    var offsetRight = container.clientWidth - (e.clientX - container.offsetLeft);

    left.style.right = offsetRight + "px";
    right.style.width = offsetRight + "px";
  }

  document.onmouseup = function(e) {
    // stop resizing
    isResizing = false;
  }
})();
body {
  font-family: Helvetica, Arial;
  font-size: 12px;
}

body,
html {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

#container {
  width: 100%;
  height: 100%;
}

#left_panel {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  right: 100px;
  background: grey;
}

#right_panel {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 200px;
  color: #fff;
  background: black;
}

#drag {
  position: absolute;
  left: -4px;
  top: 0;
  bottom: 0;
  width: 8px;
  cursor: w-resize;
}
<body>
  <div id="container">
    <div id="left_panel"> left content! </div>
    <div id="right_panel">
      <div id="drag"></div> right content!
    </div>
  </div>
</body>

顺便说一句,您没有在实际功能的任何地方使用 lastDownX。留着也没有用。
2021-05-08 00:56:41