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