背景:使用ai根据用户的需求生成应用,使用html+js+tailwind实现。导航页与页面内容分开,页面内容的html通过iframe标签嵌套的导航页中。
问题:如果导航页生成的页面超出浏览器窗口出现滚动条,iframe中内容超出高度也会滚动条。一个页面会出现双滚动条。
目的:iframe不出现滚动条
目前解决方案:使用iframe通信,在子页面onload后,获取子页面内容高度,通知导航页调整iframe标签的height。
导航页:修改iframe高度
function ytGetIframeResize (iframe) { window.addEventListener('message', function(e) { // 确保消息来自可信源 if (e.data && e.data.type === 'iframe-resize') { iframe.style.height = e.data.height + 'px'; const style = window.getComputedStyle(iframe.parentElement) // 导航页在左侧时,iframe超出部分被隐藏了 if (style.overflow === 'hidden') { iframe.parentElement.style.overflow = 'auto' } } }) }
iframe内嵌页面:页面加载完成后,获取内嵌页面高度
function ytSendPageSize () {function sendHeightToParent(e) { ytSendPageSizeBefor() let height = Math.max( document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight ); // iframe如果有横向滚动条,需要加上横向滚动条的高度 if (hasHorizontalScrollbar()) { height += 20 } window.parent.postMessage({ type: 'iframe-resize', height: height }, '*'); // 生产环境应替换为具体的父页面域名 } function loadPage (e) { window.scrollTo(0, 500); // 生成的页面会通过监听滚动条动态显示内容,通过改变滚动条位置将隐藏的内容显示出来 setTimeout(()=>{ sendHeightToParent(e) // 如果内容动态加载,可能需要MutationObserver const observer = new MutationObserver(sendHeightToParent); observer.observe(document.body, { attributes: true, childList: true, subtree: true, characterData: true }); }, 300) } window.addEventListener('load', loadPage); }
如果内嵌页面出现横向滚动条时,内容高度还有加上滚动条的高度。监听是否有横向滚动条:
function hasHorizontalScrollbar() { // 检查html元素 const html = document.documentElement; if (html.scrollWidth > html.clientWidth) return true; // 检查body元素 const body = document.body; if (body.scrollWidth > body.clientWidth) return true; return false; }
如果内嵌页面出现vh单位时,当iframe高度变化元素会根据iframe高度撑高导致变型。将vh转为px:
function ytSendPageSizeBefor () { // 获取当前视口高度 const vh = window.innerHeight / 100; const allElements = document.body.querySelectorAll('*'); allElements.forEach(el => { // 内联样式(优先级最高) if (el.style.height && el.style.height.includes('vh')) { const value = parseFloat(el.style.height); el.style.height = `${value * vh}px`; } // 计算样式(包括 Tailwind 普通类名如 h-screen) const computedHeight = getComputedStyle(el).height; if (computedHeight.endsWith('vh')) { el.style.height = `${parseFloat(computedHeight) * vh}px`; } }); // 2. 专门处理 Tailwind 任意值类名(如 h-[70vh]) const twVhRegex = /h-\[(\d+)vh\]/; // 匹配 h-[70vh] 类名 document.body.querySelectorAll('[class*="h-["]').forEach(el => { const classList = el.classList; classList.forEach(className => { const match = className.match(twVhRegex); if (match) { classList.remove(className) const vhValue = parseFloat(match[1]); el.style.height = `${vhValue * vh}px`; } }); }); }
浙公网安备 33010602011771号