【问题标题】:Replicating nested and togglable <frameset> in HTML5在 HTML5 中复制嵌套和可切换的 <frameset>
【发布时间】:2021-09-08 19:45:32
【问题描述】:

我了解到&lt;frameset&gt; 标记自 HTML5 起已弃用。值得庆幸的是,Chrome 仍然支持渲染它,不幸的是,它是目前我发现的唯一适合我的用例的东西。

&lt;frameset&gt; 标记的重要元素是其他类似框架的对象所缺少的可拖动边框,即使有大量的 javascript 帮助,我也无法使用 iframe .

在我的例子中,另一个重要的事情是其中一个框架包含一个按钮/链接,导致另一个框架消失或重新出现。发生这种情况时,框架应适当调整大小以填充空间。

我当前的 HTML 类似于以下 MCVE:

index.html

<html>
<head>
    <script language="javascript">
        function toggleBottomFrame() {
            var bottomFrame = document.getElementById("bottomFrame");
            var horizFrameset = document.getElementById("horizFrameset");
            if (bottomFrame.style.display == "none") {
                bottomFrame.style.display = "";
                horizFrameset.rows = "*,25%";
            } else {
                bottomFrame.style.display = "none";
                horizFrameset.rows = "*,0px";
            }
        }
        document.toggleBottomFrame = toggleBottomFrame;
    </script>
</head>
<frameset id="horizFrameset" rows="*,0px">
    <frameset id="vertFrameset" cols="300px,*">
        <frame id="topLeftFrame" src="buttonpage.html"></frame>
        <frame id="topRightFrame"></frame>
    </frameset>
    <frame id="bottomFrame" style="display:none"></frame>
</frameset>
</html>

buttonpage.html

<html>
<head></head>
<body>
    <button onclick="parent.frameElement.ownerDocument.toggleBottomFrame();">
</body>
</html>

这在最初为其编写代码(并且需要继续支持)的 IE11 以及 Chrome 中都有效。

如何使用未弃用的功能实现完全相同的功能(包括,最重要的是,使用鼠标在框架的边框周围拖动以扩大或缩小其中一个框架的能力)?

如果可能,我想要一个标准客户端 JS 或 HTML 的解决方案,而不需要导入其他库,如 resize.js。这是为了一个非常轻量级的前端,我不想用我不需要的库来膨胀它。

【问题讨论】:

  • 请原谅这里的无知,但是“MVCE”是什么意思呢?我在搜索时得到“模型视图控制器”。在这种情况下,它只是意味着“模型视图控制器示例”吗?
  • @AnthonyLoPrimo 我一直把 MCVE 拼错为 MVCE,抱歉
  • 其实我都不知道它拼错了!哈。我感谢你澄清。我希望我能提供一个答案作为回报,但恐怕我无法提供太多帮助。不过,答案看起来很棒,希望对您有所帮助!

标签: javascript html iframe frameset


【解决方案1】:

您应该能够使用 flex 布局实现收缩和增长功能。以下2种方法可能有效。这两种方法都有右侧部分和底部部分作为 iframe,左侧部分有按钮来显示和隐藏右侧和底部部分。

选项 1

使用 flex 并使用 css resize 属性。

缺点是您需要使用右下角显示的调整大小按钮来调整大小。左侧部分的右下角可用于水平调整大小,右侧部分的右下角可用于垂直调整大小。请注意,由于 iframe 内容,右侧部分的右下角调整大小按钮可能不可见,但如果您将光标移至右下角,您会看到光标变为调整大小并允许您调整大小。

function toggleBottom() {
  if (document.getElementById('bottomFrame').clientHeight > 0) {
    document.getElementById('topFrame').style.height = '100%';
  } else {
    document.getElementById('topFrame').style.height = '80%';
  }
}

function toggleRight() {
  if (document.getElementById('topRightFrame').clientWidth > 0) {
    document.getElementById('topLeftFrame').style.width = '100%';
  } else {
    document.getElementById('topLeftFrame').style.width = '50%';
  }
}
html,
body {
  height: 98%;
}

.page-container {
  display: flex;
  flex-direction: column;
}

.container {
  display: flex;
  flex-direction: row;
  resize: vertical;
  border: 1px solid #000;
  overflow: hidden;
}

.container-top {
  height: 80%;
}

.container-bottom {
  flex: 1 1;
  overflow: hidden;
}

.container-left {
  width: 30%;
  border: 1px solid #000;
  resize: horizontal;
  overflow: hidden;
}

.container-right {
  flex: 1 1;
  height: 100%;
  border: 1px solid #000;
  overflow: hidden;
  display: flex;
}

.frame-right {
  flex: 1 1;
}

.frame-bottom {
  flex: 1 1 100%;
  border: 1px solid #000;
}
<html>
<body class="page-container">
  <div class="container container-top" id="topFrame">
    <div class="container-left" id="topLeftFrame">
      <button onclick="toggleBottom()">Toggle Bottom</button>
      <button onclick="toggleRight()">Toggle Right</button>
    </div>
    <div class="container-right" id="topRightFrame" >
      <iframe src="https://stackoverflow.com" class="frame-right">
    </iframe>
    </div>
  </div>
  <div class="container container-bottom" id="bottomFrame">
    <iframe class="frame-bottom" src="https://stackoverflow.com"></iframe>
  </div>
</body>

</html>

选项 2

使用 flex 并使用一些脚本,我们应该能够使整个边框可拖动。这灵感来自https://stackoverflow.com/a/53220241/2772300中的答案

const topRightFrame = document.getElementById("topRightFrame");
const topLeftFrame = document.getElementById("topLeftFrame");
const bottomFrame = document.getElementById("bottomFrame");
const topFrame = document.getElementById("topFrame");
const borderSize = 4;

function toggleBottom() {
  if (bottomFrame.clientHeight > borderSize) {
    topFrame.style.height = '100%';
  } else {
    topFrame.style.height = '80%';
  }
}

function toggleRight() {
  if (topRightFrame.clientWidth > borderSize) {
    topLeftFrame.style.width = '100%';
  } else {
    topLeftFrame.style.width = '50%';
  }
}


let mousePosition;
function resizeHorizontal(e){
  const dx = mousePosition - e.x;
  mousePosition = e.x;
  topLeftFrame.style.width = (parseInt(getComputedStyle(topLeftFrame, '').width) - dx) + "px";
}

topRightFrame.addEventListener("mousedown", function(e){
  if (e.offsetX < borderSize) {
    mousePosition = e.x;
    document.addEventListener("mousemove", resizeHorizontal, false);
  }
}, false);

document.addEventListener("mouseup", function(){
    document.removeEventListener("mousemove", resizeHorizontal, false);
}, false);


function resizeVertical(e){
  const dy = mousePosition - e.y;
  mousePosition = e.y;
  topFrame.style.height = (parseInt(getComputedStyle(topFrame, '').height) - dy) + "px";
}

bottomFrame.addEventListener("mousedown", function(e){
  if (e.offsetY < borderSize) {
    mousePosition = e.y;
    document.addEventListener("mousemove", resizeVertical, false);
  }
}, false);

document.addEventListener("mouseup", function(){
    document.removeEventListener("mousemove", resizeVertical, false);
}, false);
html,
body {
  height: 98%;
}

.page-container {
  display: flex;
  flex-direction: column;
}

.container {
  display: flex;
  flex-direction: row;
  overflow: hidden;
}

.container-top {
  height: 80%;
}

.container-left {
  width: 50%;
  overflow: hidden;
  height: 100%;
}

.container-right {
  flex: 1 1;
  height: 100%;
  overflow: hidden;
  display: flex;
  padding-left: 4px;
  background-color: #ccc;
  cursor: ew-resize;
}

.frame-right {
  flex: 1 1;
}

.container-bottom {
  flex: 1 1;
  overflow: hidden;
  padding-top: 4px;
  background-color: #ccc;
  cursor: ns-resize;
}

.frame-bottom {
  flex: 1 1 100%;
}

iframe {
  border: 0;
}
<html>
<body class="page-container">
  <div class="container container-top" id="topFrame">
    <div class="container-left" id="topLeftFrame">
      <button onclick="toggleBottom()">Toggle Bottom</button>
      <button onclick="toggleRight()">Toggle Right</button>
    </div>
    <div class="container-right" id="topRightFrame" >
      <iframe src="https://stackoverflow.com" class="frame-right">
    </iframe>
    </div>
  </div>
  <div class="container container-bottom" id="bottomFrame">
    <iframe class="frame-bottom" src="https://stackoverflow.com"></iframe>
  </div>
</body>

</html>

【讨论】:

  • 应该澄清一下,我将把它编辑到我的问题中,我需要它在 IE11 中工作,据我所知它不支持 css:resize。这是我在最初的调查中查看的事情之一。不过,我将尝试选项 2。
  • 是的,你是对的,resize 属性在 IE 11 中不可用。我在 IE 11 上将选项 2 代码作为独立 html 进行了检查,看起来它正在工作。
  • 好的,在尝试实施选项 2 后,它非常滞后并且拖着我的光标。我可以看到基本原理是如何工作的,尽管目前我认为这不是这个用例的可行解决方案。感谢您的建议。
【解决方案2】:

您是否查看过Golden Layout 来调整大小?然后,您可以在其中放置 iframe 以匹配包含 div 的大小。

很抱歉,这不是一个更完整的答案,但尽管这可能是一个值得探索但不太可能出现的领域。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-02
    • 2017-03-29
    • 2013-07-12
    • 2011-10-22
    • 2020-06-26
    • 2019-06-17
    • 2015-06-03
    相关资源
    最近更新 更多