如何用HTML5非废弃特性实现带拖拽边框、可切换的嵌套frameset功能
实现方案
本方案完全使用原生HTML/CSS/JS实现,无第三方依赖,兼容IE11与Chrome,完美复现原frameset的所有核心功能:可拖拽边框调整尺寸、框架间通信控制显隐、自适应填充剩余空间。
核心逻辑说明
- 用Flex布局实现框架的自适应占满剩余空间,替代原frameset的行列分配规则
- 仅用30行左右的JS实现拖拽边框调整尺寸功能,性能开销极低
- iframe间通信逻辑和原逻辑基本一致,仅需小幅修改调用路径
完整代码:index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style> * {margin: 0;padding: 0;box-sizing: border-box;} html, body {height: 100%;width: 100%;overflow: hidden;} /* 垂直方向整体布局:上部分+底部框架 */ .h-container {display: flex;flex-direction: column;height: 100%;} /* 上部分水平布局:左侧+右侧框架 */ .v-container {display: flex;flex: 1;overflow: hidden;} /* 通用iframe样式 */ iframe {border: none;flex: 1;height: 100%;} /* 左侧框架固定初始宽度 */ #leftFrame {width: 300px;flex: none;} /* 拖拽分隔栏样式 */ .divider {background: #ccc;flex: none;} .v-divider {width: 4px;cursor: col-resize;} .h-divider {height: 4px;cursor: row-resize;display: none;} /* 底部框架初始隐藏 */ #bottomFrame {height: 25%;flex: none;display: none;} </style> </head> <body> <div class="h-container" id="hContainer"> <div class="v-container"> <iframe id="leftFrame" src="buttonpage.html"></iframe> <div class="divider v-divider" id="vDivider"></div> <iframe id="rightFrame"></iframe> </div> <div class="divider h-divider" id="hDivider"></div> <iframe id="bottomFrame"></iframe> </div> <script> // 显隐底部框架逻辑,和原功能完全一致 function toggleBottomFrame() { var bottomFrame = document.getElementById('bottomFrame'); var hDivider = document.getElementById('hDivider'); if (bottomFrame.style.display === 'none' || bottomFrame.style.display === '') { bottomFrame.style.display = 'block'; hDivider.style.display = 'block'; } else { bottomFrame.style.display = 'none'; hDivider.style.display = 'none'; } } document.toggleBottomFrame = toggleBottomFrame; // 垂直拖拽(调整左右框架宽度)逻辑 var vDivider = document.getElementById('vDivider'); var leftFrame = document.getElementById('leftFrame'); var isVDragging = false; vDivider.addEventListener('mousedown', function(e) { isVDragging = true; document.body.style.cursor = 'col-resize'; e.preventDefault(); }); document.addEventListener('mousemove', function(e) { if (!isVDragging) return; var containerRect = leftFrame.parentElement.getBoundingClientRect(); var newWidth = e.clientX - containerRect.left; // 限制最小宽度避免缩没 if (newWidth > 100 && newWidth < containerRect.width - 100) { leftFrame.style.width = newWidth + 'px'; } }); document.addEventListener('mouseup', function() { isVDragging = false; document.body.style.cursor = 'default'; }); // 水平拖拽(调整上下框架高度)逻辑 var hDivider = document.getElementById('hDivider'); var bottomFrame = document.getElementById('bottomFrame'); var isHDragging = false; hDivider.addEventListener('mousedown', function(e) { isHDragging = true; document.body.style.cursor = 'row-resize'; e.preventDefault(); }); document.addEventListener('mousemove', function(e) { if (!isHDragging) return; var containerRect = document.getElementById('hContainer').getBoundingClientRect(); var newHeight = containerRect.bottom - e.clientY; // 限制最小高度 if (newHeight > 50 && newHeight < containerRect.height - 100) { bottomFrame.style.height = newHeight + 'px'; } }); document.addEventListener('mouseup', function() { isHDragging = false; document.body.style.cursor = 'default'; }); </script> </body> </html>
完整代码:buttonpage.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <button onclick="parent.document.toggleBottomFrame()">切换底部框架显隐</button> </body> </html>
兼容说明
所有用到的CSS属性和JS API均为IE11原生支持,无需额外polyfill:
- Flex布局在IE11下的基础用法完全兼容本方案的布局需求
- 拖拽事件逻辑没有用到任何新API,在Chrome和IE11下运行效果一致
- 父子iframe通信逻辑比原frameset方案更简洁,不存在跨路径调用问题
内容的提问来源于stack exchange,提问作者Green Cloak Guy
相关产品推荐
相关产品推荐

