javascript - 可调整大小的侧边栏 - 拖动即可调整大小

标签 javascript html css

我正在尝试创建一种布局,允许您通过拖动侧边栏的一个边缘来调整侧边栏的大小。这种行为可以在 CodePen/CodeSandbox 等中看到。 - 您可以拖动每个“代码窗口”来调整其大小。我正在寻找相同的行为,但具有页面布局。

enter image description here

我想出的方法允许我拖动来调整大小,但是如果“主”区域(不是侧边栏的区域)内有很多内容,它就会放弃拖动。

我希望能够一直拖动到屏幕边缘,无论其中的内容如何。

我认为展示这个问题的最好方法是通过演示:

原始演示:

const resizer = document.querySelector("#resizer");
const sidebar = document.querySelector("#sidebar");

resizer.addEventListener("mousedown", (event) => {
  document.addEventListener("mousemove", resize, false);
  document.addEventListener("mouseup", () => {
    document.removeEventListener("mousemove", resize, false);
  }, false);
});

function resize(e) {
  const size = `${e.x}px`;
  sidebar.style.width = size;
}

/** 
 * Helpers 
 */

sidebar.style.width = '325px';
const mainContent = document.querySelector("#main-content");

function addContent() {
  const mainContentStr = [...Array(10).keys()].map(i => "Main Content");
  mainContent.innerHTML += mainContentStr.join(' ') + '<br /><br /><h1>Now drag to see how difficult it is, remove content to see how easy it is</h1>';
}

function removeContent() {
  mainContent.innerHTML = '';
}

document.querySelector("#add-content")
  .addEventListener('click', () => addContent())

document.querySelector("#remove-content")
  .addEventListener('click', () => removeContent())
body {
  position: relative;
  height: auto;
  min-height: 100vh;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  overflow: hidden;
  margin: 0;
}

#wrapper {
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  flex-direction: column;
  overflow: hidden;
  position: absolute;
  height: 100%;
  width: 100%;
  display: flex;
  margin: 0;
  padding: 0;
}

#container {
  width: 100%;
  height: 100%;
  flex-shrink: 0;
  position: relative;
  display: flex;
  overflow: hidden;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

#sidebar {
  height: 100%;
  position: relative;
  margin 0;
  padding: 0;
  box-sizing: border-box;
  background: lightgray;
  border: 2px solid darkgray;
}

#resizer {
  position: relative;
  z-index: 2;
  width: 18px;
  cursor: col-resize;
  border-left: 1px solid rgba(255, 255, 255, 0.05);
  border-right: 1px solid rgba(0, 0, 0, 0.4);
  background: #333642;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

#main {
  background: lightblue;
  height: 100%;
  flex-grow: 1;
  flex-direction: row;
  position: relative;
  display: flex;
  margin: 0;
  padding: 0;
}

#add-content {
  width: 80px;
  float: right;
  background-color: forestgreen;
}

#remove-content {
  width: 80px;
  float: right;
  background-color: salmon;
}
<div id="wrapper">
  <div id="container">
    <div id="sidebar">
      <p>Sidebar content</p>
      <button id="add-content">Add Content</button>
      <button id="remove-content">Remove Content</button>
    </div>
    <div id="resizer"></div>
    <div id="main">
      <p id="main-content"></p>
    </div>
  </div>
</div>

<小时/>

更新的演示:

添加按钮后,它们看起来垂直拉伸(stretch)了 100%

const resizer = document.querySelector("#resizer");
const sidebar = document.querySelector("#sidebar");

resizer.addEventListener("mousedown", (event) => {
  document.addEventListener("mousemove", resize, false);
  document.addEventListener("mouseup", () => {
    document.removeEventListener("mousemove", resize, false);
  }, false);
});

function resize(e) {
  const size = `${e.x}px`;
  sidebar.style.flexBasis = size;
}

/** 
 * Helpers 
 */

sidebar.style.flexBasis = '325px';
const mainContent = document.querySelector("#main-content");

function addContent() {
  const mainContentStr = [...Array(10).keys()].map(i => "Main Content");
  mainContent.innerHTML += mainContentStr.join(' ') + '<br /><br /><h1>Now drag to see how difficult it is, remove content to see how easy it is</h1>';
}

function removeContent() {
  mainContent.innerHTML = '';
}

document.querySelector("#add-content")
  .addEventListener('click', () => addContent())

document.querySelector("#remove-content")
  .addEventListener('click', () => removeContent())
body {
  position: relative;
  height: auto;
  min-height: 100vh;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  overflow: hidden;
  margin: 0;
}

#wrapper {
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  flex-direction: column;
  overflow: hidden;
  position: absolute;
  height: 100%;
  width: 100%;
  display: flex;
  margin: 0;
  padding: 0;
}

#container {
  width: 100%;
  height: 100%;
  flex-shrink: 0;
  position: relative;
  display: flex;
  overflow: hidden;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

#sidebar {
  height: 100%;
  position: relative;
  margin 0;
  padding: 0;
  box-sizing: border-box;
  background: lightgray;
  border: 2px solid darkgray;
  
  min-width: 0;
}

#resizer {
  flex-basis: 18px;

  position: relative;
  z-index: 2;
  cursor: col-resize;
  border-left: 1px solid rgba(255, 255, 255, 0.05);
  border-right: 1px solid rgba(0, 0, 0, 0.4);
  background: #333642;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

#main {
  flex-basis: 0;
  flex-grow: 1;
  min-width: 0;

  background: lightblue;
  height: 100%;
  flex-direction: row;
  position: relative;
  display: flex;
  margin: 0;
  padding: 0;
}

#add-content {
  width: 80px;
  float: right;
  background-color: forestgreen;
}

#remove-content {
  width: 80px;
  float: right;
  background-color: salmon;
}
<div id="wrapper">
  <div id="container">
    <div id="sidebar">
      <p>Sidebar content</p>
    </div>
    <div id="resizer"></div>
    <div id="main">
      <button id="add-content">Add Content</button>
      <button id="remove-content">Remove Content</button>
      <p id="main-content"></p>
    </div>
  </div>
</div>

最佳答案

要在 Flexbox 中设置固定不变宽度,请使用 flex-basis而不是宽度。根据该固定大小,Flex 元素可以根据可用空间以及 flex-growflex-shrink 的属性缩小或增大。

此外, flex 元素的默认 min-width 值为 auto。这意味着该元素的宽度不能小于其内容大小,即使您将其 flex-basis 设置为 0px 也是如此。这意味着我们必须将默认的 min-width 值覆盖为 0px,以便在拖动 #resizer 元素时,它可以完全收缩自己.

这是一个工作示例。我只是将 JS 和 CSS 中的 width 属性调整为 flex-basis 。然后,我还在 #main#sidebar 中添加了 0pxmin-width 属性。

const resizer = document.querySelector("#resizer");
const sidebar = document.querySelector("#sidebar");

resizer.addEventListener("mousedown", (event) => {
  document.addEventListener("mousemove", resize, false);
  document.addEventListener("mouseup", () => {
    document.removeEventListener("mousemove", resize, false);
  }, false);
});

function resize(e) {
  const size = `${e.x}px`;
  sidebar.style.flexBasis = size;
}

/** 
 * Helpers 
 */

sidebar.style.flexBasis = '325px';
const mainContent = document.querySelector("#main-content");

function addContent() {
  const mainContentStr = [...Array(10).keys()].map(i => "Main Content");
  mainContent.innerHTML += mainContentStr.join(' ') + '<br /><br /><h1>Now drag to see how difficult it is, remove content to see how easy it is</h1>';
}

function removeContent() {
  mainContent.innerHTML = '';
}

document.querySelector("#add-content")
  .addEventListener('click', () => addContent())

document.querySelector("#remove-content")
  .addEventListener('click', () => removeContent())
body {
  position: relative;
  height: auto;
  min-height: 100vh;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  overflow: hidden;
  margin: 0;
}

#wrapper {
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  flex-direction: column;
  overflow: hidden;
  position: absolute;
  height: 100%;
  width: 100%;
  display: flex;
  margin: 0;
  padding: 0;
}

#container {
  width: 100%;
  height: 100%;
  flex-shrink: 0;
  position: relative;
  display: flex;
  overflow: hidden;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

#sidebar {
  height: 100%;
  position: relative;
  margin 0;
  padding: 0;
  box-sizing: border-box;
  background: lightgray;
  border: 2px solid darkgray;
  
  min-width: 0;
}

#resizer {
  flex-basis: 18px;

  position: relative;
  z-index: 2;
  cursor: col-resize;
  border-left: 1px solid rgba(255, 255, 255, 0.05);
  border-right: 1px solid rgba(0, 0, 0, 0.4);
  background: #333642;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

#main {
  flex-basis: 0;
  flex-grow: 1;
  min-width: 0;

  background: lightblue;
  height: 100%;
  flex-direction: row;
  position: relative;
  display: flex;
  margin: 0;
  padding: 0;
}

#add-content {
  width: 80px;
  float: right;
  background-color: forestgreen;
}

#remove-content {
  width: 80px;
  float: right;
  background-color: salmon;
}
<div id="wrapper">
  <div id="container">
    <div id="sidebar">
      <p>Sidebar content</p>
      <button id="add-content">Add Content</button>
      <button id="remove-content">Remove Content</button>
    </div>
    <div id="resizer"></div>
    <div id="main">
      <p id="main-content"></p>
    </div>
  </div>
</div>

关于javascript - 可调整大小的侧边栏 - 拖动即可调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60981769/

相关文章:

javascript - IE 需要双击自定义按钮

javascript - 如何防止safari弹出密​​码保存框?

javascript - jQuery - 2 级 slider 通过单击返回到 1 级

jquery - 如何将默认的 css 属性解析为内联样式属性

javascript - 在同一项目上多次调用时 scrollTop 跳转

javascript - XMLHttpRequest跨域抛出错误

javascript - window.getSelection 在textarea中获取正确的选择

javascript - 在javascript中使用变量的值作为变量

html - 如何使我的页面与 IE 兼容?

python - 如何使文件夹登陆页面看起来像 Plone 门户中子站点的初始页面?