關於有固定列的el-table 在滾動載入的時候固定列的行和非固定列的行對不齊有幾px的錯位且doLayout不生效有對應的解決方案
阿新 • • 發佈:2022-03-26
關於有固定列的el-table 在滾動載入的時候固定列的行和非固定列的行對不齊有幾px的錯位且doLayout不生效有對應的解決方案:
在滾動結束時通過對比固定列table和非固定列table強制dom操作
// @ts-ignore import elInfiniteScroll from "element-ui/lib/infinite-scroll"; const elScope = "ElInfiniteScroll"; const msgTitle = `[el-table-infinite-scroll]: `; const elTableScrollWrapperClass = ".el-table__body-wrapper"; // 處理滾動過程中固定列的行和非固定列的行不對齊的情況 function handleException( el: HTMLElement , scrollElem: HTMLElement, addEventLister: boolean = true) { let scrollTimer: any = null; function scrollCallback() { clearTimeout(scrollTimer); scrollTimer = setTimeout(() => { const scrollFixedElem = el.querySelector(".el-table__fixed-body-wrapper") as any; if (!scrollFixedElem) { return; } if (scrollFixedElem.scrollTop !== scrollElem.scrollTop) { scrollFixedElem.scrollTop = scrollElem.scrollTop; } const barHeight = 8; const tableHeaderHeight = 50; if (scrollElem.scrollHeight + barHeight === scrollElem.scrollTop + scrollElem.offsetHeight) { scrollFixedElem.style.top = tableHeaderHeight - barHeight + "px"; } else { scrollFixedElem.style.top = tableHeaderHeight + "px"; } }, 0); } if (addEventLister) { scrollElem.addEventListener("scroll", scrollCallback); } else { scrollElem.removeEventListener("scroll", scrollCallback); } } /** * 同步 el-infinite-scroll 的配置項 * @param sourceVNode * @param sourceElem * @param targetElem */ function asyncElOptions(sourceVNode: any, sourceElem: any, targetElem: any) { let value; ["disabled", "delay", "immediate"].forEach((name: string) => { name = "infinite-scroll-" + name; value = sourceElem.getAttribute(name); if (value !== null) { targetElem.setAttribute(name, value); } }); // fix: windows/chrome 的 scrollTop + clientHeight 與 scrollHeight 不一致的 BUG const name = "infinite-scroll-distance"; value = sourceElem.getAttribute(name); targetElem.setAttribute(name, value < 1 ? 1 : value); } export default { inserted(el: any, binding: any, vnode: any, oldVnode: any) { // 獲取 table 中的滾動層 const scrollElem = el.querySelector(elTableScrollWrapperClass); // 如果沒找到元素,返回錯誤 if (!scrollElem) { throw `${msgTitle}找不到 ${elTableScrollWrapperClass} 容器`; } // 設定自動滾動 scrollElem.style.overflowY = "auto"; // dom 渲染後 setTimeout(() => { // if (!el.style.height) { // scrollElem.style.height = "400px"; // console.warn( // `${msgTitle}請儘量設定 el-table 的高度,可以設定為 auto/100%(自適應高度),未設定會取 400px 的預設值(不然會導致一直載入)` // ); // } asyncElOptions(vnode, el, scrollElem); // 繫結 infinite-scroll elInfiniteScroll.inserted(scrollElem, binding, vnode, oldVnode); // 將子集的引用放入 el 上,用於 unbind 中銷燬事件 el[elScope] = scrollElem[elScope]; }, 0); // 處理滾動過程中固定列的行和非固定列的行不對齊的情況 handleException( el, scrollElem); }, componentUpdated(el: any, binding: any, vnode: any) { asyncElOptions(vnode, el, el.querySelector(elTableScrollWrapperClass)); }, unbind: (el: any) => { try { const scrollElem = el.querySelector(elTableScrollWrapperClass); handleException( el, scrollElem, false); elInfiniteScroll.unbind(); } catch (e) { } }, };