ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Layui 标签页表单错位 3 分钟修复:监听切换事件重渲染 + 上线自查清单

Layui 标签页表单错位 3 分钟修复:监听切换事件重渲染 + 上线自查清单 Layui 标签页表单错位 3 分钟修复监听切换事件重渲染 上线自查清单【免费下载链接】layui一套遵循浏览器原生态开发模式的 Web UI 组件库。项目地址: https://gitcode.com/GitHub_Trending/la/layui做 Layui 后台系统时你一定遇到过这种场面标签页Tabs里嵌着表单Form第一个标签一切过去表单直接样式错乱——输入框高低不齐、下拉框弹层位置飘到别处严重时整个表单不显示只有强制刷新页面才活过来。先给结论根子出在渲染时机非激活标签页的内容被display: none藏起来表单在看不见的状态下完成初始化尺寸自然算错。最省事的修复就两步监听标签页的afterChange切换事件在内容显示后对当前面板里的表单调用form.render()重新渲染。本文给出可落地的两种方案、根因拆解和一份上线前的自查清单。快速修复监听标签切换事件重渲染表单核心思路一句话切换完成、内容真正可见之后再渲染表单。下面的最小片段来自一个标签页 表单的页面只依赖tabs和form两个模块// 1. 页面加载时先渲染当前激活面板里的表单 form.render(); // 2. 监听标签切换完成事件参数是渲染时的实例 id tabs.on(afterChange(userFormTabs), function (data) { // data.thisBodyItem当前激活的内容面板 var formElem data.thisBodyItem.querySelector(form); // 取出面板内的表单 form.render(null, formElem.getAttribute(lay-filter)); // 只重渲染这张表单 });逐行看点tabs.on(afterChange(实例id))是标签页提供的切换完成事件回调参数data里带着thisBodyItem它就是当前激活的内容面板节点。querySelector(form)取出该面板内的表单元素lay-filter相当于表单的「门牌」传给form.render()的第二个参数后只精准重渲染这一张不会波及别的表单。偷懒写法form.render()不传参数时会重渲染页面上全部表单表单少的时候完全够用。完整可运行的单文件示例HTML JS保存为 .html 直接打开即可!DOCTYPE html html head meta charsetutf-8 titleLayui 标签页 表单修复示例/title link relstylesheet hrefhttps://cdn.staticfile.org/layui/2.9.10/css/layui.css /head body div classlayui-container stylemargin-top: 20px; div classlayui-card div classlayui-card-header用户信息管理/div div classlayui-card-body div classlayui-tabs iduserFormTabs lay-filteruserFormTabs ul classlayui-tabs-header li lay-idbasic基本信息/li li lay-idcontact联系方式/li li lay-idsecurity安全设置/li /ul div classlayui-tabs-body !-- 基本信息默认激活 -- div classlayui-tabs-item layui-show form classlayui-form lay-filterbasicForm div classlayui-form-item label classlayui-form-label用户名/label div classlayui-input-block input typetext nameusername lay-verifyrequired placeholder请输入用户名 classlayui-input /div /div /form /div !-- 联系方式 -- div classlayui-tabs-item form classlayui-form lay-filtercontactForm div classlayui-form-item label classlayui-form-label手机号/label div classlayui-input-block input typetel namephone lay-verifyphone placeholder请输入手机号 classlayui-input /div /div /form /div !-- 安全设置 -- div classlayui-tabs-item form classlayui-form lay-filtersecurityForm div classlayui-form-item label classlayui-form-label密码/label div classlayui-input-block input typepassword namepassword lay-verifyrequired placeholder请输入密码 classlayui-input /div /div /form /div /div /div /div /div /div script srchttps://cdn.staticfile.org/layui/2.9.10/layui.js/script script layui.use([tabs, form], function () { var tabs layui.tabs; var form layui.form; // 1. 初始渲染默认激活面板的表单 form.render(null, basicForm); // 2. 监听标签切换事件切换后重渲染当前面板表单 tabs.on(afterChange(userFormTabs), function (data) { var formElem data.thisBodyItem.querySelector(form); var filter formElem formElem.getAttribute(lay-filter); if (filter) { form.render(null, filter); // 精准重渲染当前表单 } }); // 3. 表单提交事件示例拦截提交并回显数据 form.on(submit(*), function (data) { console.log(提交数据, data.field); return false; // 阻止默认提交 }); }); /script /body /html关键行tabs.on(afterChange(userFormTabs))里必须与#userFormTabs的lay-filter一致否则事件绑定不到实例form.on(submit(*))的*表示监听所有lay-filter的提交。为什么一切换就坏隐藏的标签页让表单「瞎了」先看点结构。非激活标签页的内容靠一条 CSS 规则隐藏/* 非激活的标签页内容面板 */ .layui-tabs-item { display: none; }display: none意味着这块 DOM 完全不参与布局没有宽高、不占位置浏览器直接跳过它的排版计算。问题就出在这里。Layui 的 form 模块渲染时会把原始元素加工成带样式的组件——select包成.layui-form-selectcheckbox、radio包成对应的勾选结构。加工过程需要读取输入框真实宽度、计算下拉弹层坐标等尺寸信息。而你在页面加载时调用的那次渲染往往赶上了表单还藏在display: none里的窗口期隐藏元素读不到正确的布局尺寸下拉面板、验证提示框的位置按 0 宽度或错误坐标计算等用户切换标签、内容可见时这些早已定型的样式不会自动重算错位就此发生。所以根因一句话表单初始化和标签页可见时机冲突了。默认激活的面板没问题因为渲染时它就在显示状态非激活面板里的问题全部源于先藏后渲染这个顺序。 记住这个顺序矛盾你就理解了两个方案为什么都围绕可见之后再渲染做文章。重表单场景非激活标签懒加载如果非激活面板里是重表单——几十个字段、上传控件、远程拉取的数据上面的全量预渲染 切换重渲染就不划算了。更好的策略是延迟初始化非激活面板先放占位切到了才加载内容并渲染没切到过的一律不碰。好处有三点首屏更快只渲染默认激活面板其余表单零成本天然避开渲染时机冲突表单初始化时面板必然可见尺寸信息完整支持 AJAX 分步加载重表单可以按标签页拆分配合加载动画体验更好。!-- 非激活面板先放占位不预先渲染表单 -- div classlayui-tabs-item idadvanceTab div classlayui-anim layui-anim-loading/div /divvar tabLoaded { advance: false }; // 记录各标签是否已加载 tabs.on(afterChange(complexTabs), function (data) { var layId data.thisHeaderItem.attr(lay-id); // 首次切到高级设置时才加载并渲染 if (layId advance !tabLoaded.advance) { $(#advanceTab).load(form-tpl/advance.html, function () { form.render(null, advanceForm); // 内容到位后再渲染 tabLoaded.advance true; }); } });关键行data.thisHeaderItem是当前选中的标签头节点lay-id是它的业务标识tabLoaded对象保证同一面板只加载渲染一次。$(id).load()用于拉取外部 HTML 片段需要页面已引入 jQuery 模块。⚠️ 注意懒加载方案下form.render的时机必须在内容插入之后放在.load()的回调里顺序反了又回到老问题。上线前自查清单代码提交前把这五条过一遍能避开绝大多数切标签坏表单的事故初始化顺序先渲染tabs再渲染默认激活面板的表单最后绑定afterChange等事件监听lay-filter 唯一每张表单的lay-filter互不重复重渲染时才不会误伤其他面板禁止嵌套 layui-form一个标签页面板里只放一张表单不要在表单里再嵌表单默认激活面板先自查它渲染时可见如果它都错位优先检查 CSS 是否被全局样式污染参考官方示例Layui 仓库自带可视化示例页面tests/visual/目录下有标签页与表单的现成用法如 tabs.html、form.html照着改比凭空搭稳得多。小结一句话回顾Layui 标签页里的表单样式错乱本质是隐藏状态下渲染的时机问题——用afterChange事件在切换后form.render()重渲染重表单则干脆等面板激活再懒加载两条路都能修好。想进一步看组件用法可参考本仓库的示例页tests/visual/tabs.html、tests/visual/form.html。【免费下载链接】layui一套遵循浏览器原生态开发模式的 Web UI 组件库。项目地址: https://gitcode.com/GitHub_Trending/la/layui创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表