關於有固定列的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) {
}
},
};
