抽离fixed生成

This commit is contained in:
Julyp
2020-02-02 15:20:49 +08:00
parent 19e50a15ed
commit 80ea1b9ff4
5 changed files with 149 additions and 133 deletions

View File

@@ -1,6 +1,4 @@
import {
sort
} from './vdom';
import sort from './vdom';
import {
cloneNode,
appendChild,
@@ -10,6 +8,7 @@ import {
querySelector,
querySelectorAll
} from './node-ops';
import createFixed from './fixed';
import {
throttle,
debounce,
@@ -21,6 +20,7 @@ import {
} from './utils';
import scrollBarWidth from './scrollbar-width';
export default function initMixin(Table) {
Table.prototype._init = function(options = {}) {
if (!options.selector) {
@@ -88,15 +88,15 @@ export default function initMixin(Table) {
vm.size.theadHeight = thead.offsetHeight;
vm.size.tbodyHeight = customHeight - thead.offsetHeight;
vm.$tbodyWrapper.style.height = vm.size.tbodyHeight + "px";
//删除空余的table节点
removeChild(table.parentNode, table);
rollupFixed(vm, thead, tbody)
createFixed(vm, thead, tbody)
//获取tbody的data数据
vm.data = initData(vm, tbody);
initSortEvent(vm);
bindEvents(vm);
if (vm.scrollY) {
@@ -108,87 +108,8 @@ export default function initMixin(Table) {
}
}
function rollupFixed(vm, theadModel, tbodyModel) {
const {
fixedLeft,
fixedRight
} = vm.props;
let rootMinWidth = 320;
querySelectorAll(vm.$root, ".smart-table_body-wrapper").forEach(wrapper => {
wrapper.style.height = vm.size.tbodyHeight + "px";
})
//左边有固定列
if (fixedLeft.thead.length > 0) {
rootMinWidth = rootMinWidth > fixedLeft.width ? rootMinWidth : fixedLeft.width;
//构建header
let thead = cloneNode(theadModel, true);
querySelectorAll(querySelector(thead, "tr"), "th").forEach((column, index) => {
if (fixedLeft.thead.indexOf("field-" + index) === -1) {
column.classList.add('is-hidden')
}
})
let headerWrapper = createTabelWrapper("smart-table_fixed-header-wrapper", vm, "header", thead);
//构建body
let tbody = cloneNode(tbodyModel, true);
let rows = querySelectorAll(tbody, "tr");
rows.forEach(row => {
querySelectorAll(row, "td").forEach((column, index) => {
if (fixedLeft.tbody.indexOf("field-" + index) === -1) {
column.classList.add('is-hidden')
}
})
})
let bodyWrapper = createTabelWrapper("smart-table_fixed-body-wrapper", vm, "body", tbody);
bodyWrapper.style.top = vm.size.theadHeight + "px";
bodyWrapper.style.height = (vm.size.tbodyHeight - (vm.scrollX ? vm.gutterWidth : 0)) + "px";
let fixedContainer = createElement("div", "smart-table_fixed");
appendChildren(fixedContainer, [headerWrapper, bodyWrapper]);
fixedContainer.style.width = fixedLeft.width + "px";
fixedContainer.style.height = (vm.size.fixWrapperHeigth - (vm.scrollX ? vm.gutterWidth : 0)) + "px";
appendChild(vm.$root, fixedContainer);
vm.$fixedLeft = bodyWrapper;
}
//右边有固定列
if (fixedRight.thead.length > 0) {
rootMinWidth = rootMinWidth + fixedRight.width;
//构建header
let thead = cloneNode(theadModel, true);
querySelectorAll(querySelector(thead, "tr"), "th").forEach((column, index) => {
if (fixedRight.thead.indexOf("field-" + index) === -1) {
column.classList.add('is-hidden')
}
})
let headerWrapper = createTabelWrapper("smart-table_fixed-header-wrapper", vm, "header", thead);
//构建body
let tbody = cloneNode(tbodyModel, true);
let rows = querySelectorAll(tbody, "tr");
rows.forEach(row => {
let offsetX = -1;
querySelectorAll(row, "td").forEach((column, index) => {
offsetX += getIntByAttr(column, "colspan", 1);
if (fixedRight.tbody.indexOf("field-" + offsetX) === -1) {
column.classList.add('is-hidden')
}
})
})
let bodyWrapper = createTabelWrapper("smart-table_fixed-body-wrapper", vm, "body", tbody);
bodyWrapper.style.top = vm.size.theadHeight + "px";
bodyWrapper.style.height = (vm.size.tbodyHeight - (vm.scrollX ? vm.gutterWidth : 0)) + "px";
let fixedContainer = createElement("div", "smart-table_fixed-right");
fixedContainer.style.right = (vm.scrollY ? vm.gutterWidth : 0) + "px";
appendChildren(fixedContainer, [headerWrapper, bodyWrapper]);
fixedContainer.style.width = fixedRight.width + "px";
fixedContainer.style.height = (vm.size.fixWrapperHeigth - (vm.scrollX ? vm.gutterWidth : 0)) + "px";
appendChild(vm.$root, fixedContainer);
vm.$fixedRight = bodyWrapper;
if (vm.scrollY) {
let rightPatch = createElement("div", "smart-table_fixed-right-patch");
rightPatch.style.width = vm.gutterWidth + "px";
rightPatch.style.height = vm.size.theadHeight + "px";
appendChild(vm.$root, rightPatch)
}
}
vm.$root.style.minWidth = rootMinWidth + "px";
function layout() {
}
//根据表格中的tbody第一行 查出每列的宽度并记录
@@ -221,46 +142,10 @@ function getColgroup(thead, tbody, theadLength) {
}
function bindEvents(vm) {
vm.$tbodyWrapper.addEventListener("scroll", () => syncPostion(vm), {
passive: true
})
window.addEventListener("resize", debounce(600, () => {
let table = vm.$root;
let oldWrapperWidth = vm.size.wrapperWidth;
let oldTableWidth = vm.size.tabelWidth;
let newWrapperWidth = table.offsetWidth;
let newTableWidth = parseInt(oldTableWidth * (newWrapperWidth / oldWrapperWidth));
let headerWrapper = querySelector(vm.$theadWrapper, '.smart-table_header');
let bodyWrapper = querySelector(vm.$tbodyWrapper, '.smart-table_body');
vm.colgroup.forEach(function(item, index) {
vm.colgroup[index] = parseInt(newTableWidth * (item / oldTableWidth)) + 1
})
vm.size.wrapperWidth = newWrapperWidth;
vm.size.tabelWidth = newTableWidth;
headerWrapper.style.width = newTableWidth + 'px';
bodyWrapper.style.width = newTableWidth + 'px';
// 替换colgroup
replaceColGroup(vm, headerWrapper);
replaceColGroup(vm, bodyWrapper);
replaceFixedColGroup(vm, querySelector(table, '.smart-table_fixed'), newTableWidth);
replaceFixedColGroup(vm, querySelector(table, '.smart-table_fixed-right'), newTableWidth);
}))
let trs = querySelectorAll(vm.$tbodyWrapper, 'tr');
let fixedLeftTrs = querySelectorAll(vm.$root, '.smart-table_fixed .smart-table_fixed-body-wrapper tr');
let fixedRightTrs = querySelectorAll(vm.$root, '.smart-table_fixed-right .smart-table_fixed-body-wrapper tr');
trs.forEach((tr, trIndex) => {
tr.addEventListener('mouseenter', () => {
tr.className = 'smart-table_hover-tr';
if (fixedLeftTrs.length > 0) fixedLeftTrs[trIndex].className = 'smart-table_hover-tr';
if (fixedRightTrs.length > 0) fixedRightTrs[trIndex].className = 'smart-table_hover-tr';
})
tr.addEventListener('mouseleave', () => {
tr.className = ''
if (fixedLeftTrs.length > 0) fixedLeftTrs[trIndex].className = '';
if (fixedRightTrs.length > 0) fixedRightTrs[trIndex].className = '';
})
})
bindScrollEvents(vm)
bindHoverEvents(vm)
bindSortEvents(vm);
bindResizeEvents(vm)
}
function replaceFixedColGroup(vm, selector, newTableWidth) {
@@ -292,7 +177,31 @@ function syncPostion(vm) {
})()
}
function initSortEvent(vm) {
function bindScrollEvents(vm) {
vm.$tbodyWrapper.addEventListener("scroll", () => syncPostion(vm), {
passive: true
})
}
function bindHoverEvents(vm) {
let trs = querySelectorAll(vm.$tbodyWrapper, 'tr');
let fixedLeftTrs = querySelectorAll(vm.$root, '.smart-table_fixed .smart-table_fixed-body-wrapper tr');
let fixedRightTrs = querySelectorAll(vm.$root, '.smart-table_fixed-right .smart-table_fixed-body-wrapper tr');
trs.forEach((tr, trIndex) => {
tr.addEventListener('mouseenter', () => {
tr.className = 'smart-table_hover-tr';
if (fixedLeftTrs.length > 0) fixedLeftTrs[trIndex].className = 'smart-table_hover-tr';
if (fixedRightTrs.length > 0) fixedRightTrs[trIndex].className = 'smart-table_hover-tr';
})
tr.addEventListener('mouseleave', () => {
tr.className = ''
if (fixedLeftTrs.length > 0) fixedLeftTrs[trIndex].className = '';
if (fixedRightTrs.length > 0) fixedRightTrs[trIndex].className = '';
})
})
}
function bindSortEvents(vm) {
let els = Array.from(querySelectorAll(vm.$root, "th[sort]"));
if (els.length === 0) return;
els.forEach(el => {
@@ -319,6 +228,30 @@ function initSortEvent(vm) {
})
}
function bindResizeEvents(vm) {
window.addEventListener("resize", debounce(600, () => {
let table = vm.$root;
let oldWrapperWidth = vm.size.wrapperWidth;
let oldTableWidth = vm.size.tabelWidth;
let newWrapperWidth = table.offsetWidth;
let newTableWidth = parseInt(oldTableWidth * (newWrapperWidth / oldWrapperWidth));
let headerWrapper = querySelector(vm.$theadWrapper, '.smart-table_header');
let bodyWrapper = querySelector(vm.$tbodyWrapper, '.smart-table_body');
vm.colgroup.forEach(function(item, index) {
vm.colgroup[index] = parseInt(newTableWidth * (item / oldTableWidth)) + 1
})
vm.size.wrapperWidth = newWrapperWidth;
vm.size.tabelWidth = newTableWidth;
headerWrapper.style.width = newTableWidth + 'px';
bodyWrapper.style.width = newTableWidth + 'px';
// 替换colgroup
replaceColGroup(vm, headerWrapper);
replaceColGroup(vm, bodyWrapper);
replaceFixedColGroup(vm, querySelector(table, '.smart-table_fixed'), newTableWidth);
replaceFixedColGroup(vm, querySelector(table, '.smart-table_fixed-right'), newTableWidth);
}))
}
function initProps(thead) {
let props = {};
//创建表头单元格二维数组
@@ -366,7 +299,7 @@ function initFixed(thead, vm) {
colgroup,
props
} = vm;
const columnLen = colgroup.length;
const colgroupLen = colgroup.length;
let fixedLeft = {
thead: [],
tbody: [],
@@ -408,8 +341,8 @@ function initFixed(thead, vm) {
let colspan = getIntByAttr(columns[i], "colspan", 1);
for (let j = 0; j < colspan; j++) {
rightCnt++;
fixedRight.tbody.push("field-" + (columnLen - rightCnt))
fixedRight.width = fixedRight.width + colgroup[columnLen - rightCnt];
fixedRight.tbody.push("field-" + (colgroupLen - rightCnt))
fixedRight.width = fixedRight.width + colgroup[colgroupLen - rightCnt];
}
}
}