 Layui Tabs 標(biāo)簽頁(yè)中表單渲染錯(cuò)亂:切換 Tab 后下拉框?yàn)槭裁村e(cuò)位)
三步修復(fù) Layui Tabs 標(biāo)簽頁(yè)中表單渲染錯(cuò)亂切換 Tab 后下拉框?yàn)槭裁村e(cuò)位【免費(fèi)下載鏈接】layui一套遵循瀏覽器原生態(tài)開(kāi)發(fā)模式的 Web UI 組件庫(kù)。項(xiàng)目地址: https://gitcode.com/GitHub_Trending/la/layuiLayui 把表單Form放進(jìn)標(biāo)簽頁(yè)Tabs后切到非首個(gè)標(biāo)簽常出現(xiàn)輸入框錯(cuò)位、下拉框?qū)挾犬惓!D標(biāo)疊字。下面先復(fù)現(xiàn)、講清原因再給一套可照做的修復(fù)步驟改完附自查清單。先復(fù)現(xiàn)一下問(wèn)題用當(dāng)前主干源碼3.xlay-前綴類(lèi)名即可穩(wěn)定復(fù)現(xiàn)2.x 系列把類(lèi)名換成layui-前綴現(xiàn)象相同頁(yè)面里放一組lay-tabs第二個(gè)標(biāo)簽里放一個(gè)lay-form含下拉框和帶lay-affix圖標(biāo)的輸入框頁(yè)面加載時(shí)調(diào)用form.render()此時(shí)第二個(gè)標(biāo)簽還是隱藏的點(diǎn)擊切到第二個(gè)標(biāo)簽看到的現(xiàn)象下拉面板寬度變成 0或?qū)挾葘?duì)不上觸發(fā)輸入框輸入框右側(cè)的圖標(biāo)壓住文字間距為 0數(shù)字輸入框的加號(hào)/減號(hào)按鈕錯(cuò)位為什么會(huì)這樣打個(gè)比方關(guān)著抽屜你在里面量家具量出來(lái)全是零——抽屜拉開(kāi)后家具當(dāng)然對(duì)不上格子。機(jī)制很短非活動(dòng)標(biāo)簽內(nèi)容被.lay-tabs-item { display: none }隱藏見(jiàn) src/css/modules/tabs.css切換標(biāo)簽只是給內(nèi)容項(xiàng)加減lay-show類(lèi)不會(huì)觸發(fā)任何組件重新渲染而 Form 渲染時(shí)要在注入時(shí)刻量取元素實(shí)際寬度下拉面板寬度取title.width()、輸入框圖標(biāo)要寫(xiě)padding-rightdisplay: none的容器里寬度全是 0于是 padding、面板寬度都按 0 計(jì)算標(biāo)簽顯示后再展開(kāi)下拉錯(cuò)位就暴露出來(lái)了按步驟修復(fù)核心一句話尺寸類(lèi)組件必須在可見(jiàn)狀態(tài)渲染切換后補(bǔ)渲染一次即可。第 1 步給每個(gè)標(biāo)簽頁(yè)的表單一個(gè)唯一的lay-filterdiv classlay-tabs iddemoTabs ul classlay-tabs-header li lay-idbase基本信息/li li lay-idadvance高級(jí)設(shè)置/li /ul div classlay-tabs-body div classlay-tabs-item form classlay-form lay-filterbaseForm!-- 輸入框、select --/form /div div classlay-tabs-item form classlay-form lay-filteradvanceForm!-- 輸入框、select --/form /div /div /divlay-filter是后面精準(zhǔn)重渲染的鑰匙別省。第 2 步監(jiān)聽(tīng)切換事件切換完成后重渲染當(dāng)前標(biāo)簽里的表單?layui.use([tabs, form], function () { var tabs layui.tabs, form layui.form; tabs.render({ elem: #demoTabs }); // 實(shí)例 id 默認(rèn)取容器 id // 切換完成后執(zhí)行thisBodyItem 是當(dāng)前活動(dòng)的內(nèi)容項(xiàng) tabs.on(afterChange(demoTabs), function (data) { var filter data.thisBodyItem .find(form) .attr(lay-filter); // 當(dāng)前表單的 filter form.render(null, filter); // 只重渲染這一個(gè)表單 }); });第 3 步動(dòng)態(tài)插入內(nèi)容的標(biāo)簽先顯示、后渲染如果某個(gè)標(biāo)簽的內(nèi)容是 AJAX 或模板插入的不要插完立刻 render——插入時(shí)它還是隱藏的寬度照樣是 0。在afterChange回調(diào)里內(nèi)容此時(shí)已可見(jiàn)再調(diào)form.render(null, filter)。備選做法一句話重表單可以懶加載記錄各標(biāo)簽是否初始化過(guò)首次切入時(shí)才注入 HTML 并渲染后續(xù)切換跳過(guò)。改完怎么驗(yàn)證檢查項(xiàng)預(yù)期表現(xiàn)切到第二個(gè)標(biāo)簽輸入框與右側(cè)圖標(biāo)不再重疊間距正常展開(kāi) select面板寬度與觸發(fā)輸入框一致位置緊跟其下數(shù)字輸入框加/減按鈕對(duì)齊點(diǎn)擊可正常步進(jìn)來(lái)回切換多次組件不重復(fù)、不疊加、不錯(cuò)位表單提交/校驗(yàn)錯(cuò)誤提示落在對(duì)應(yīng)表單項(xiàng)上樣式正常常見(jiàn)問(wèn)題Q每次切換都重渲染會(huì)不會(huì)事件綁重復(fù)、開(kāi)銷(xiāo)很大不會(huì)。Form 的渲染是冪等的——源碼里每次渲染先hasRender.remove()移除舊的裝飾元素再重建見(jiàn) src/components/form.js不會(huì)疊加節(jié)點(diǎn)和事件。且我們只渲染當(dāng)前標(biāo)簽?zāi)且粋€(gè)表單范圍很小。Q切換時(shí)直接全局form.render()行不行能跑但會(huì)掃描整頁(yè)所有表單頁(yè)面表單多時(shí)有可見(jiàn)卡頓還可能干擾其他實(shí)例。帶上lay-filter精準(zhǔn)渲染更穩(wěn)。Q第一個(gè)默認(rèn)激活的標(biāo)簽也要處理嗎不用。它加載時(shí)就是可見(jiàn)的初始form.render()量到的寬度是對(duì)的錯(cuò)位的只是加載時(shí)被藏起來(lái)的那些標(biāo)簽。記住關(guān)鍵點(diǎn)隱藏容器里渲染量出來(lái)的尺寸就是 0讓表單在可見(jiàn)時(shí)渲染、切換后補(bǔ)渲染問(wèn)題就消失了。組件實(shí)現(xiàn)可對(duì)照源碼src/components/tabs.js、src/components/form.js【免費(fèi)下載鏈接】layui一套遵循瀏覽器原生態(tài)開(kāi)發(fā)模式的 Web UI 組件庫(kù)。項(xiàng)目地址: https://gitcode.com/GitHub_Trending/la/layui創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考