From 5d20ecc6db76d160e33396baab709d4b6939242b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cjonyshi=E2=80=9D?= Date: Sat, 1 Dec 2018 17:51:01 +0800 Subject: [PATCH] =?UTF-8?q?table=20=E6=8B=96=E6=8B=BD=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Table.scss | 22 +-- src/TableHeader.js | 379 ++++++++---------------------------------- src/lib/dragColumn.js | 60 +------ src/utils.js | 57 +++++++ 4 files changed, 135 insertions(+), 383 deletions(-) diff --git a/src/Table.scss b/src/Table.scss index 1018293..9b5ad57 100644 --- a/src/Table.scss +++ b/src/Table.scss @@ -388,26 +388,14 @@ $table-move-in-color: $bg-color-base; .online-hover{ background:#000000; } + } - .th-drag-gap{ - background:transparent; - } - .th-drag-gap-hover{ - // background: #ccc; + &-drag-gap:hover{ cursor: col-resize; + .online{ + background: #000000 + } } - .th-drag-gap>div{ - background:transparent; - } - .th-drag-gap-hover>div{ - background: #000000 - } - // &.th-can-not-drag{ - // .th-drag-gap-hover{ - // cursor: none; - // width: 0px; - // } - // } } &-th:last-child { &-drag-gap{ diff --git a/src/TableHeader.js b/src/TableHeader.js index e8eccb7..8d6f4eb 100644 --- a/src/TableHeader.js +++ b/src/TableHeader.js @@ -1,4 +1,5 @@ import React, { Component } from "react"; +import ReactDOM from 'react-dom'; import PropTypes from "prop-types"; import shallowequal from "shallowequal"; import { throttle, debounce } from "throttle-debounce"; @@ -17,13 +18,6 @@ class TableHeader extends Component { constructor(props) { super(props); this.currentObj = null; - this.state = { - // border: false, - // dragAbleOrBord:props.draggable?"able":"", //border 拖拽列宽,able 交换列, - // dragAbleOrBordStart:"", // borderStart 开始拖拽宽度 ableStart 开始交换列 - - // draggable:props.draggable?props.draggable:false, - }; //拖拽宽度处理 if (!props.dragborder) return; this.border = false; @@ -32,14 +26,10 @@ class TableHeader extends Component { initPageLeftX: 0, initLeft: 0, x: 0, - width: 0 + width: 0, + option:'' }; this.table = null; - // let _da = {}; - // Object.assign(_da,this.props.rows[0]); - // this.drag.data = JSON.parse(JSON.stringify(this.props.rows[0])); - // let a = this.props.rows[0]; - let _row = []; this.props.rows[0] && this.props.rows[0].forEach(item => { @@ -51,25 +41,6 @@ class TableHeader extends Component { static defaultProps = { contentWidthDiff: 0 }; - - // componentWillReceiveProps(nextProps){ - // if(this.props.draggable != nextProps.draggable){ - // this.setState({ - // dragAbleOrBord:nextProps.draggable?"able":"", //border 拖拽列宽,able 交换列 - // // draggable:nextProps.draggable, - // }) - // } - - // if(this.props.dragborder != nextProps.dragborder){ - // this.setState({ - // dragAbleOrBord:nextProps.dragborder?"border":"", //border 拖拽列宽,able 交换列 - // }) - // } - // } - - // shouldComponentUpdate(nextProps) { - // return !shallowequal(nextProps, this.props); - // } /** * 动态绑定th line 事件 @@ -81,7 +52,8 @@ class TableHeader extends Component { for (let index = 0; index < ths.length; index++) { const element = ths[index];//.getAttribute('data-type'); if(!element.getAttribute('data-th-fixed')){ - const colLine = element.children[0]; + const colLine = element.children.length > 1?element.lastElementChild:element.children[0]; + // const colLine = element.children[0]; for (let i = 0; i < events.length; i++) { const _event = events[i]; let _dataSource = eventSource?element:colLine; @@ -110,13 +82,11 @@ class TableHeader extends Component { componentDidUpdate(){ this.initTable(); this.initEvent(); - // this.initDragAbleEvent(); } componentDidMount(){ this.initTable(); this.initEvent(); - // this.initDragAbleEvent(); } /** @@ -127,10 +97,13 @@ class TableHeader extends Component { {key:'mouseup', fun:this.onLineMouseUp}, {key:'mousemove', fun:this.onLineMouseMove} ]; - this.thEventListen(events,'',true);//表示把事件添加到th元素上 - this.thEventListen([{key:'mousedown',fun:this.onLineMouseDown}]);//表示把事件添加到竖线 - this.bodyEventListen([{key:'mouseup',fun:this.bodyonLineMouseMove}]); + if(this.props.dragborder){ + this.thEventListen(events,'',true);//表示把事件添加到th元素上 + this.thEventListen([{key:'mousedown',fun:this.onLineMouseDown}]);//表示把事件添加到竖线 + this.bodyEventListen([{key:'mouseup',fun:this.bodyonLineMouseMove}]); + } + if(!this.props.draggable)return; //拖拽交换列事件 this.thEventListen([{key:'mousedown',fun:this.dragAbleMouseDown}],'',true);//表示把事件添加到竖线 } @@ -152,6 +125,7 @@ class TableHeader extends Component { * 获取table的属性存放在this.table 中。(公用方法) */ initTable(){ + if(!this.props.dragborder && !this.props.draggable)return; let el = ReactDOM.findDOMNode(this); let tableDome = el.parentNode; let table = {}; @@ -161,14 +135,28 @@ class TableHeader extends Component { table.ths = tableDome.getElementsByTagName("th"); } this.table = table; + + if(!this.props.dragborder)return; + if(document.getElementById("u-table-drag-thead-" + this.theadKey)){ + //hao 固定列table + this.fixedTable = {}; + let _fixedParentContext = document.getElementById("u-table-drag-thead-" + this.theadKey).parentNode; + let siblingDom = _fixedParentContext.parentNode.nextElementSibling; + if (siblingDom) { + let fixedTable = siblingDom.querySelector("table"); + this.fixedTable.table = fixedTable + this.fixedTable.cols = fixedTable.getElementsByTagName("col"); + // this.fixedTable.ths = fixedTable.tableDome.getElementsByTagName("th"); + } + } } - // --------------------th---------------------------- - + //---拖拽列宽代码逻辑----start----- onLineMouseMove = (e) => { - const { clsPrefix } = this.props; + const { clsPrefix ,dragborder} = this.props; Event.stopPropagation(e); let event = Event.getEvent(e); + if (!this.props.dragborder) return; if(this.drag.option != "border"){ return false; } @@ -178,14 +166,18 @@ class TableHeader extends Component { let newWidth = this.drag.oldWidth + diff; if(newWidth > this.drag.minWidth){ currentCols.style.width = newWidth +'px'; + //hao 修改表体的width + this.fixedTable.cols[this.drag.currIndex].style.width = newWidth + "px"; } + //hao todo + this.table.table.style.width = (parseInt(this.table.table.style.width) + diff);//改变table的width }; onLineMouseDown = (e) => { Event.stopPropagation(e); let event = Event.getEvent(e); const { clsPrefix, contentTable } = this.props; - console.log("--this.onLineMouseDown----"); + if (!this.props.dragborder) return; let currentIndex = parseInt(Event.getTarget(event).getAttribute("data-line-index")); let defaultWidth = Event.getTarget(event).getAttribute("data-th-width"); let currentObj = this.table.cols[currentIndex]; @@ -194,7 +186,6 @@ class TableHeader extends Component { this.drag.oldLeft = event.x; this.drag.oldWidth = parseInt((currentObj).style.width); this.drag.minWidth = currentObj.style.minWidth != ""?parseInt(currentObj.style.minWidth):defaultWidth; - console.log("--this.drag--target----",event); }; onLineMouseUp = (event) => { @@ -205,16 +196,21 @@ class TableHeader extends Component { }; clearDragBorder(){ + if (!this.props.dragborder) return; + let {rows} = this.props; + let data = {rows:rows[0],cols:this.table.cols,currIndex:this.drag.currIndex}; + this.props.afterDragColWidth && this.props.afterDragColWidth(data); this.drag = { option:"" }; } - // --------------------------------------th---------------------------------------- + //---拖拽列宽代码逻辑----start----- dragAbleMouseDown = (e) => { Event.stopPropagation(e); let event = Event.getEvent(e); + if (!this.props.draggable) return; event.target.setAttribute('draggable',true);//添加交换列效果 this.drag.option = 'dragAble'; this.removeDragBorderEvent();//清理掉拖拽列宽的事件 @@ -235,18 +231,19 @@ class TableHeader extends Component { // this.bodyEventListen([{key:'mouseup',fun:this.bodyonDragMouseMove}]); } - // removeDragAbleEvent(){ - // let events = [ - // {key:'dragstart',fun:this.onDragStart}, - // {key:'dragover', fun:this.onDragOver}, - // {key:'drop', fun:this.onDrop}, - // {key:'dragenter', fun:this.onDragEnter} - // ]; - // this.thEventListen(events,'remove',true); - // } + removeDragAbleEvent(){ + let events = [ + {key:'dragstart',fun:this.onDragStart}, + {key:'dragover', fun:this.onDragOver}, + {key:'drop', fun:this.onDrop}, + {key:'dragenter', fun:this.onDragEnter} + ]; + this.thEventListen(events,'remove',true); + } onDragStart = (e) => { let event = Event.getEvent(e); + if (!this.props.draggable) return; if(this.drag.option === 'border'){return;} let currentIndex = parseInt(Event.getTarget(event).getAttribute("data-line-index")); @@ -255,14 +252,9 @@ class TableHeader extends Component { event.dataTransfer.setData("Text", currentKey); this.currentObj = this.props.rows[0][currentIndex]; event.dataTransfer.setDragImage(event.target, 0, 0); - // this.props.onDragStart(event, this.currentObj); }; onDragOver = (e) => { - // let event = Event.getEvent(e); - // if(this.drag.option === 'border'){return;} - // let data = this.getCurrentEventData(e); - // if (!this.currentObj || this.currentObj.key == data.key) return; event.preventDefault(); }; @@ -271,11 +263,10 @@ class TableHeader extends Component { * @memberof TableHeader */ onDragEnter = (e) => { - // let event = Event.getEvent(e); + if (!this.props.draggable) return; if(this.drag.option === 'border'){return;} let data = this.getCurrentEventData(e); - if (!this.currentObj || this.currentObj.key == data.key) return; - // this.props.onDragEnter(event, data); + if (!this.currentObj || this.currentObj.key == data.key) return; }; /** @@ -283,9 +274,11 @@ class TableHeader extends Component { * @memberof TableHeader */ onDrop = (e) => { + if (!this.props.draggable) return; if(this.drag.option === 'border'){return;} let data = this.getCurrentEventData(e); if (!this.currentObj || this.currentObj.key == data.key) return; + if(!this.props.onDrop)return; this.props.onDrop(event,{dragSource:this.currentObj,dragTarg:data}); }; @@ -300,179 +293,7 @@ class TableHeader extends Component { return null; } } - - // --------------------------------------拖拽列交换---------------------------------------- - - - - - - - - - - - - - - - onMouseOver = (event, data) => { - //如果是固定列没有拖拽功能 - if (this.border || data.fixed) return; - const { clsPrefix } = this.props; - if(event.target.id != 'th-online'){ - event.target.className = `${clsPrefix}-thead-th-drag-gap th-drag-gap-hover`; - } - }; - - ableOnMouseMove = (event, data) => { - let {dragAbleOrBord} = this.state; - if(dragAbleOrBord === "borderStart" || dragAbleOrBord === "ableStart")return; - if(dragAbleOrBord === "able")return; - this.setState({ - dragAbleOrBord:"able" - }) - }; - - - - getOffsetLeft(obj){ - var tmp = obj.offsetLeft; - var val = obj.offsetParent; - while(val != null){ - tmp += val.offsetLeft; - val = val.offsetParent; - } - return tmp; - } - - - onThMouseUp = (event, data) => { - this.border = false; - const { clsPrefix, rows,columns } = this.props; - let eventDom = event.target; - let optDom; - if (eventDom.classList.contains(".th-drag-gap-hover")) { - optDom = eventDom; - } else { - optDom = eventDom.querySelector(`.${clsPrefix}-thead-th-drag-gap`); - } - if (optDom) { - optDom.classList.remove("th-drag-gap-hover"); - optDom.classList.add("th-drag-gap"); - } - // columns[this.drag.currIndex].width = data.width; - //宽度拖拽后,增加回调函数,外部可以记录宽度 - if ( - typeof this.props.afterDragColWidth == "function" && - rows && - rows[0] && - this.drag.currIndex - ) { - this.props.afterDragColWidth(rows[0],this.drag.currIndex); - } - }; - - onThMouseMove = (event, data) => { - if (!this.border) return; - //固定表头拖拽 - - const { dragborderKey, contentTable,headerScroll ,contentDomWidth,scrollbarWidth,bordered,rows} = this.props; - let x = event.pageX - this.drag.initPageLeftX + this.drag.initLeft - 0; - let contentTableDom = document.getElementById( - "u-table-drag-thead-" + this.theadKey - ).parentNode; - - if (!this.contentTableWidth) { - const styleWidth = contentTableDom.style.width; - if ( - styleWidth && - (typeof styleWidth == "number" || styleWidth.includes("px")) - ) { - this.contentTableWidth = parseInt(styleWidth); - } else { - this.contentTableWidth = parseInt(contentTableDom.scrollWidth); - } - } - const newTableWidth = this.contentTableWidth + x; - const newWidth = this.drag.width + x; - if (newWidth < this.props.minColumnWidth) { - //清楚样式 - let moveDom = event.target.querySelector(".th-drag-gap-hover"); - moveDom && moveDom.classList.remove("th-drag-gap-hover"); - // event.target.classList.remove('th-drag-gap-hover'); - return; - } - //设置hiden的left - //"u-table-drag-hide-table" - let currentHideDom = document - .getElementById("u-table-drag-hide-table-" + dragborderKey) - .getElementsByTagName("div")[this.drag.currIndex]; - currentHideDom.style.left = this.drag.initPageLeftX + x - grap + "px"; - - //获取最小宽度,不让拖动 - // let minWidth = 0; - // for(let i=0;i<=this.drag.currIndex;i++){ - // minWidth += this.drag.data[i].width; - // } - - // //判断最小值后在赋值 todo - // let currLeft = this.drag.initPageLeftX+x-grap; - // console.log("currLeft minWidth ",currLeft + " "+minWidth); - // if(currLeft <= minWidth){ - // return; - // } - // currentHideDom.style.left = currLeft+"px"; - - //设置当前的宽度 - let currentData = this.drag.data[this.drag.currIndex]; - currentData.width = newWidth; - let currentDom = document - .getElementById("u-table-drag-thead-" + this.theadKey) - .getElementsByTagName("th")[this.drag.currIndex]; - currentDom.style.width = newWidth + "px"; - // this.contentTableWidth = newTableWidth; - contentTableDom.style.width = newTableWidth + "px"; - // data.width = newWidth; - rows[0][this.drag.currIndex].width = newWidth; - this.drag.x = x; - let contentColDomArr = contentTableDom.querySelectorAll("colgroup col"); - contentColDomArr[this.drag.currIndex].style.width = newWidth + "px"; - //固定表头时,表头和表体分开,拖拽时表体的宽度也需要一起联动 - const siblingDom = contentTableDom.parentNode.nextElementSibling; - if (siblingDom) { - const bodyTableDom = siblingDom.querySelector("table"); - //2、是的话将表头对应的表格的宽度给表体对应的表格的宽度 - bodyTableDom.style.width = newTableWidth + "px"; - //3、对应的col也要跟这变 - let colDomArr = bodyTableDom.querySelectorAll("colgroup col"); - colDomArr[this.drag.currIndex].style.width = newWidth + "px"; - //4、设置overflow属性 - } - - //表头需要显示滚动条时,需兼容含有固定列 - if(headerScroll){ - - let showScroll = contentDomWidth - newTableWidth - scrollbarWidth ; - if(bordered){ - showScroll = showScroll -1; - } - const fixedLeftTable = contentTable.querySelector('.u-table-fixed-left .u-table-header') ; - const fixedRightTable = contentTable.querySelector('.u-table-fixed-rigth .u-table-header'); - const contentTableHeader = contentTable.querySelector('.u-table-scroll .u-table-header'); - if(showScroll < 0){ - //找到固定列表格,设置表头的marginBottom值为scrollbarWidth; - contentTableHeader.style.overflowX = 'scroll'; - fixedLeftTable && (fixedLeftTable.style.marginBottom = scrollbarWidth + "px"); - fixedRightTable && (fixedRightTable.style.marginBottom = scrollbarWidth + "px"); - }else{ - contentTableHeader.style.overflowX = 'hidden'; - fixedLeftTable && (fixedLeftTable.style.marginBottom = '0px'); - fixedRightTable && (fixedRightTable.style.marginBottom = '0px'); - } - } - }; - +//---拖拽列交换----end----- /** * @description 过滤输入后的回调函数 */ @@ -641,7 +462,7 @@ class TableHeader extends Component { let attr = dragborder ? { id: `u-table-drag-thead-${this.theadKey}` } : {}; return ( - + {rows.map((row, index) => ( {row.map((da, columIndex, arr) => { @@ -667,82 +488,26 @@ class TableHeader extends Component { delete da.filterdropdownfocus; } - let thAbleObj = {},thBorObj = {},thDefaultObj = {},thLineObj = {}; + let thDefaultObj = {}; let thClassName = `${da.className}`; - // if (draggable || dragborder) { - // if (draggable && dragAbleOrBordStart != "borderStart") { - thAbleObj = { - ...da, - onDragStart:(e)=>{this.onDragStart(e, da)}, - onDragOver:(e)=>{this.onDragOver(e, da)}, - onDrop:(e)=>{this.onDrop(e, da)}, - onDragEnter:(e)=>{this.onDragEnter(e, da)}, - onMouseMove:(e)=>{this.ableOnMouseMove(e, da)}, - onMouseDown:(e)=>{ - //避免表头其他元素对其影响 - const filterDom = contentTable.querySelector('.filterable'); - //是否是过滤行元素,是的话不触发 - const isFilterDom =filterDom ?filterDom.contains(e.target):false; - - if(e.target.classList.contains('uf') ||isFilterDom){ - return; - } - if(e.target.classList.contains('uf')){ - return; - } - }, - draggable:draggable, - // className:thObj.className+`${clsPrefix}-thead th-drag ${thHover}`, - key:da.key - }; - thClassName += `${clsPrefix}-thead th-drag ${thHover} `; - // } - // if (dragborder && dragAbleOrBord === "border") { - // if (dragborder && dragAbleOrBordStart != "ableStart") { - thBorObj.style={'width': da.width } - // thObj.className= thObj.className+`${clsPrefix}-thead-th ${canDotDrag}`, - thBorObj.onMouseMove = (e)=>{ - if(draggable){ - this.ableOnMouseMove(e, da) - } - this.onThMouseMove(e, da) + if(draggable){ + thClassName += `${clsPrefix}-thead th-drag ${thHover} `; } - thBorObj.onMouseUp = (e)=>{this.onThMouseUp(e, da)} - - thClassName += `${clsPrefix}-thead-th ${canDotDrag}`; - thBorObj.style= { width: da.width } - // key:i - // } - // thObj.className = thObj.className+`${fixedStyle}`; - thClassName += `${fixedStyle}`; + if(dragborder){ + thClassName += `${clsPrefix}-thead-th ${canDotDrag}`; + } + thClassName += `${fixedStyle}`; if(!da.fixed){ - thLineObj = { - onMouseMove:(e)=>{ e.stopPropagation();this.onMouseMove(e, da)}, - onMouseOut:(e)=>{this.onMouseOut(e, da)}, - onMouseDown:(e)=>{ e.stopPropagation();this.onMouseDown(e, da)}, - onMouseUp:(e)=>{this.onMouseUp(e, da)}, - onMouseOver:(e)=>{this.onMouseOver(e, da)}, - // className:`${clsPrefix}-thead-th-drag-gap th-drag-gap`, - }; - // if(dragAbleOrBordStart !== 'ableStart'){ - thLineObj.className = `${clsPrefix}-thead-th-drag-gap th-drag-gap`; - // } - // } - // {...thAbleObj} {...thBorObj} - return ( - {da.children} - { - da.fixed ? "":
(this.gap = el)} data-line-key={da.key} - data-line-index={columIndex} data-th-width={da.width} - data-type="online" - // {...thLineObj} - className = {`${clsPrefix}-thead-th-drag-gap`} - > -
- } - ) + {da.children} + { + dragborder ?
(this.gap = el)} data-line-key={da.key} + data-line-index={columIndex} data-th-width={da.width} + data-type="online" className = {`${clsPrefix}-thead-th-drag-gap`}> +
:"" + } + ) }else{ thDefaultObj = { ...da, diff --git a/src/lib/dragColumn.js b/src/lib/dragColumn.js index 1586e0b..c25bfe9 100644 --- a/src/lib/dragColumn.js +++ b/src/lib/dragColumn.js @@ -31,39 +31,7 @@ export default function dragColumn(Table) { }); return _column; } - - - // onDragStart=(event,data)=>{ - // if(this.props.onDragStart){ - // this.props.onDragStart(event,data) - // } - // } - - // onDragOver=(event,data)=>{ - // if(this.props.onDragOver){ - // this.props.onDragOver(event,data) - // } - // } - - // onDragEnter=(event,data)=>{ - // console.log('--------onDragEnter------------',data); - - // if(data.key == "checkbox")return; - // const {columns:_columns} = this.state; - // let columns = []; - // Object.assign(columns,_columns); - // columns.forEach((da)=>da.drgHover = false) - // let current = columns.find((da)=>da.key == data.key); - // if(current.fixed)return; - // current.drgHover = true; - // this.setState({ - // columns - // }); - // if(this.props.onDragEnter){ - // this.props.onDragEnter(event,data); - // } - // } - + onDrop=(event,data)=>{ let {dragSource,dragTarg} = data; let {columns} = this.state; @@ -83,32 +51,6 @@ export default function dragColumn(Table) { columns:JSON.parse(JSON.stringify(columns)) }); } - - onDrop_bak=(event,data)=>{ - if(data.key == "checkbox")return; - let {columns} = this.state; - const id = event.dataTransfer.getData("Text"); - let objIndex = columns.findIndex((_da,i)=>_da.key == id); - let targetIndex = columns.findIndex((_da,i)=>_da.key == data.key); - // if(columns[objIndex].fixed)return;//固定列不让拖拽 - // if(columns[targetIndex].fixed)return;//固定列不让拖拽 - columns.forEach((da,i)=>{ - da.drgHover = false; - if(da.key == id){//obj - da.dragIndex = targetIndex - } - if(da.key == data.key){//targetObj - da.dragIndex = objIndex; - } - }); - let _columns = columns.sort(compare('dragIndex')); - this.setState({ - columns:_columns.slice() - }); - if(this.props.onDrop){ - this.props.onDrop(event,data,columns); - } - } getTarget=(evt)=>{ return evt.target || evt.srcElement; diff --git a/src/utils.js b/src/utils.js index ad105e0..7996b8f 100644 --- a/src/utils.js +++ b/src/utils.js @@ -165,4 +165,61 @@ export function getColChildrenLength(columns,chilrenLen){ } }) return chilrenLen; +} + + + function addHandler(element,type,handler){ + + if(element.addEventListener){//检测是否为DOM2级方法 + element.addEventListener(type, handler, false); + }else if (element.attachEvent){//检测是否为IE级方法 + element.attachEvent("on" + type, handler); + } else {//检测是否为DOM0级方法 + element["on" + type] = handler; + } +} + + function removeHandler(element, type, handler){ + if (element.removeEventListener){ + element.removeEventListener(type, handler, false); + } else if (element.detachEvent){ + element.detachEvent("on" + type, handler); + } else { + element["on" + type] = null; + } +} + +//获取事件对象的兼容性写法 +function getEvent(event){ + return event ? event : window.event; +} + +//获取事件对象目标的兼容性写法 +function getTarget(event){ + return event.target || event.srcElement; +} + +function preventDefault(event){ + if (event.preventDefault){ + event.preventDefault(); + } else { + event.returnValue = false; + } +} + +function stopPropagation(event){ + if (event.stopPropagation){ + event.stopPropagation(); + } else { + event.cancelBubble = true; + } +} + +export const Event = { + addHandler, + removeHandler, + getEvent, + getTarget, + preventDefault, + stopPropagation } \ No newline at end of file