如果我将高度设置为其内容的 100%,则在 Javascript 中拖动以调整面板大小会冻结

问题描述 投票:0回答:1

我无法使用鼠标拖动面板来调整其大小。我认为这是一个类似于 Stackoverlow 上的 this Question 的问题,因此可以用

flexbox
解决,但通过分析和测试代码,我意识到它们不是适合我的情况的正确解决方案,因为我的情况不同。 Flexbox 和这个问题似乎不是解决方案。也许这是一个涉及 Javascript 而不是 CSS 的问题。

我想要什么?我希望能够拖动右侧面板的线(图中所示的线)并调整面板大小,将其向右或向左移动。右侧面板内有一个

iframe
。如果我只将
widht:100%
设置为 iframe(在 id
#preview
的 css 中),那么它的调整大小工作正常,但是当我也将
height:100%
应用于
iframe
时,它不再工作,调整大小停止。我实际上需要
iframe
也有
height:100%
因为我希望 iframe 延伸到整个面板一样长。

问题何时出现? 如果拖动右侧面板线(图中所示的线)并将其从右向左移动,则面板会正确展开。随后,在放大面板后,如果您尝试缩小它(从右向左拖动线条)并将其恢复到初始大小,那么一切都会冻结。

解决方案尝试。我尝试了各种(无用的)CSS解决方案,我也尝试使用

flexbox
,我还尝试了我在这个链接上面讨论的Stackoverflow问题的解决方案,但它都是无用的。问题似乎不是Flexbox。 Flexbox 看起来没什么用。所以我想问题可能是我用来调整大小的Javascript代码。我补充一下:建议“拖动事件”的好心用户的评论很有趣。我尝试过,但不起作用(也许是我的错误,我不知道)

P.S:

我想继续使用纯JavaScript,我不想使用jQuery。另外我想使用 height:100% 和百分比而不是 height: 将 iframe 扩展到容器:? px 使用 px 请问你们有人能帮我吗?谢谢你

const gutters = document.querySelectorAll(".gutter"); const panes = document.querySelectorAll(".pane"); const minWidth = document.querySelector(".wrapper").style.getPropertyValue("--min-width"); const minHeight = document.querySelector(".wrapper").style.getPropertyValue("--min-height"); function resizer(e) { window.addEventListener("mousemove", mousemove); window.addEventListener("mouseup", mouseup); // check gutter if vertical or horizontal const is_vertical = e.currentTarget.classList.contains("gutter-v"); // get previous position (x or y depending on is_vertical) const prev = is_vertical ? e.x : e.y; // get current pane, the parent pane of the gutter you are moving const currentPane = e.currentTarget.parentNode; const currentPanel = currentPane.getBoundingClientRect(); // get previous pane, when move gutter-v: // if current pane is center, prev pane will be left pane // if current pane is right, prev pane will be center pane // left pane will never be current pane cause it don't have gutter const prevPane = currentPane.previousElementSibling; const prevPanel = prevPane.getBoundingClientRect(); function mousemove(e) { // minWidth and minHeight are string ('200px' and '100px' in this case), change them to integer const min = parseInt(is_vertical ? minWidth : minHeight); // calculate distance between prev and current position const distance = prev - (is_vertical ? e.x : e.y); // calculate new width/height of current pane and prev pane const newCurrentSize = (is_vertical ? currentPanel.width : currentPanel.height) + distance; const newPrevSize = (is_vertical ? prevPanel.width : prevPanel.height) - distance; // if new width/height is less than min, return and don't change pane style if (newCurrentSize < min || newPrevSize < min) return; // change pane width/height depending on is_vertical if (is_vertical) { currentPane.style.width = newCurrentSize + "px"; prevPane.style.width = newPrevSize + "px"; } else { currentPane.style.height = newCurrentSize + "px"; prevPane.style.height = newPrevSize + "px"; } } function mouseup() { window.removeEventListener("mousemove", mousemove); window.removeEventListener("mouseup", mouseup); } } gutters.forEach((gutter) => gutter.addEventListener("mousedown", resizer));
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
}

.wrapper {
  height: 100vh;
  width: 100vw;
  background: #333;
  border: 6px solid #666;
  display: flex;
}

.pane {
  position: relative;
  color: #fff;
  /* 
      --min-width in .wrapper inline style 
      <div class="wrapper" style="--min-width: 200px;--min-height: 100px;"> 
      */
  min-width: var(--min-width);
}

.pane:last-child {
  flex-grow: 1;
}

.pane:has(.pane) {
  padding: 0;
  display: flex;
  flex-direction: column;
}

.pane>.pane {
  /* 
      --min-height in .wrapper inline style 
      <div class="wrapper" style="--min-width: 200px;--min-height: 100px;">
      */
  min-height: var(--min-height);
}

.gutter {
  --l: 100%;
  --s: 10px;
  background: #666;
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
}

.gutter-v {
  width: var(--s);
  height: var(--l);
  cursor: col-resize;
}

.gutter-h {
  height: var(--s);
  width: var(--l);
  cursor: row-resize;
}

.left {
  width: 600px;
}

.center_container {
  width: 650px;
}

.center1 {
  height: 700px;
}

#preview {
  display: block;
  width: 100%;
  height: 100%;
  background: #991717;
  border: 0;
}
<div class="wrapper" style="--min-width: 200px;--min-height: 100px;">
  <div class="pane left">
    This is the left pane.
  </div>
  <div class="pane center_container">
    <div class="gutter gutter-v"></div>
    <div class="pane center1">
      This is the center pane1
    </div>
    <div class="pane">
      <div class="gutter gutter-h"></div>
      This is the center pane2.
    </div>
  </div>
  <div class="pane">
    <div class="gutter gutter-v"></div>
    <iframe id="preview"></iframe>
  </div>
</div>

javascript html css frontend
1个回答
0
投票
iframe

是另一个页面,当鼠标放在

iframe
上时,
mousemove
事件被中断。
您可以添加 

pointer-events: none;

来防止此问题。

#preview.resizing {
  pointer-events: none;
}

然后通过js移动开始和结束时添加/删除
.resize

const iframes = document.querySelectorAll("iframe");
...
// in resizer()
iframes.forEach((iframe) => iframe.classList.add("resizing"));

// in mouseup()
iframes.forEach((iframe) => iframe.classList.remove("resizing"));

const gutters = document.querySelectorAll(".gutter"); const panes = document.querySelectorAll(".pane"); const minWidth = document.querySelector(".wrapper").style.getPropertyValue("--min-width"); const minHeight = document.querySelector(".wrapper").style.getPropertyValue("--min-height"); const iframes = document.querySelectorAll("iframe"); function resizer(e) { window.addEventListener("mousemove", mousemove); window.addEventListener("mouseup", mouseup); // add .resizing when mousedown iframes.forEach((iframe) => iframe.classList.add("resizing")); // check gutter if vertical or horizontal const is_vertical = e.currentTarget.classList.contains("gutter-v"); // get previous position (x or y depending on is_vertical) const prev = is_vertical ? e.x : e.y; // get current pane, the parent pane of the gutter you are moving const currentPane = e.currentTarget.parentNode; const currentPanel = currentPane.getBoundingClientRect(); // get previous pane, when move gutter-v: // if current pane is center, prev pane will be left pane // if current pane is right, prev pane will be center pane // left pane will never be current pane cause it don't have gutter const prevPane = currentPane.previousElementSibling; const prevPanel = prevPane.getBoundingClientRect(); function mousemove(e) { // minWidth and minHeight are string ('200px' and '100px' in this case), change them to integer const min = parseInt(is_vertical ? minWidth : minHeight); // calculate distance between prev and current position const distance = prev - (is_vertical ? e.x : e.y); // calculate new width/height of current pane and prev pane const newCurrentSize = (is_vertical ? currentPanel.width : currentPanel.height) + distance; const newPrevSize = (is_vertical ? prevPanel.width : prevPanel.height) - distance; // if new width/height is less than min, return and don't change pane style if (newCurrentSize < min || newPrevSize < min) return; // change pane width/height depending on is_vertical if (is_vertical) { currentPane.style.width = newCurrentSize + "px"; prevPane.style.width = newPrevSize + "px"; } else { currentPane.style.height = newCurrentSize + "px"; prevPane.style.height = newPrevSize + "px"; } } function mouseup() { // remove .resizing when mouseup iframes.forEach((iframe) => iframe.classList.remove("resizing")); window.removeEventListener("mousemove", mousemove); window.removeEventListener("mouseup", mouseup); } } gutters.forEach((gutter) => gutter.addEventListener("mousedown", resizer));
*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  margin: 0;
}

.wrapper {
  height: 100vh;
  width: 100vw;
  background: #333;
  border: 6px solid #666;
  display: flex;
}

.pane {
  position: relative;
  color: #fff;
  /* 
      --min-width in .wrapper inline style 
      <div class="wrapper" style="--min-width: 200px;--min-height: 100px;"> 
      */
  min-width: var(--min-width);
}

.pane:last-child {
  flex-grow: 1;
}

.pane:has(.pane) {
  padding: 0;
  display: flex;
  flex-direction: column;
}

.pane>.pane {
  /* 
      --min-height in .wrapper inline style 
      <div class="wrapper" style="--min-width: 200px;--min-height: 100px;">
      */
  min-height: var(--min-height);
}

.gutter {
  --l: 100%;
  --s: 10px;
  background: #666;
  position: absolute;
  z-index: 1;
  top: 0;
  left: 0;
}

.gutter-v {
  width: var(--s);
  height: var(--l);
  cursor: col-resize;
}

.gutter-h {
  height: var(--s);
  width: var(--l);
  cursor: row-resize;
}

.left {
  width: 600px;
}

.center_container {
  width: 650px;
}

.center1 {
  height: 700px;
}

#preview {
  display: block;
  width: 100%;
  height: 100%;
  background: #991717;
  border: 0;
}

#preview.resizing {
  pointer-events: none;
}
<div class="wrapper" style="--min-width: 200px;--min-height: 100px;">
  <div class="pane left">
    This is the left pane.
  </div>
  <div class="pane center_container">
    <div class="gutter gutter-v"></div>
    <div class="pane center1">
      This is the center pane1
    </div>
    <div class="pane">
      <div class="gutter gutter-h"></div>
      This is the center pane2.
    </div>
  </div>
  <div class="pane">
    <div class="gutter gutter-v"></div>
    <iframe id="preview"></iframe>
  </div>
</div>

© www.soinside.com 2019 - 2024. All rights reserved.