平常開發中,有這樣的需求,須要在表格中進行框選,並對框選中的內容進行批量更改。源碼於文章結尾javascript
下面連接供在線調試:html
https://codesandbox.io/s/tabl...vue
主要思路經過監聽鼠標事件,進行框選框繪製。獲取框選 的dom,並計算其是否在框選區域,來進行批量更改。其中主要的方式 getClientRects。java
一、初始化表格數據結構node
由於表格爲星期/時間,相對結構會有點子複雜,問題不大,giao。git
setTableConfig() { let timeThArr = Array.from(new Array(24).keys()); let timeTdArr = Array.from(new Array(48).keys()); timeTdArr = timeTdArr.map((item) => { let obj = { id: item, }; return obj; }); this.timeThArr = timeThArr; this.timeTdArr = timeTdArr; let tableList = this.tableData; tableList.map((item, index) => { this.timeThArr.map((temp, key) => { item.push({ key: key + index * 24, }) }) }) this.tableData = tableList; },
二、點擊單格選中github
除了框選也能夠單擊選中web
handleClickTimeData(obj, index) { let tableList = _.clone(this.tableData); _.map(tableList[index], (item) => { if (item.key == obj.key) { item.checked = !item.checked; } }); this.tableData = tableList; },
三、重置數據結構
取消全部框選dom
reset() { let tableList = _.clone(this.tableData); _.map(tableList, (item) => { _.map(item, temp => { temp.checked = false; }) }); this.tableData = tableList; },
一、表格綁定mousedown、mousemove、mouseup事件
handleMouseDown(e) { this.is_show_mask = true; this.start_x = e.clientX; this.start_y = e.clientY; this.end_x = e.clientX; this.end_y = e.clientY; document.body.addEventListener("mousemove", this.handleMouseMove); document.body.addEventListener("mouseup", this.handleMouseUp); }, handleMouseMove(e) { this.end_x = e.clientX; this.end_y = e.clientY; }, handleMouseUp() { document.body.removeEventListener("mousemove", this.handleMouseMove); document.body.removeEventListener("mouseup", this.handleMouseUp); this.is_show_mask = false; this.handleDomSelect(); this.resetXY(); },
二、計算dom是否在包含在框選區域內部
collide(rect1, rect2) { const maxX = Math.max(rect1.x + rect1.width, rect2.x + rect2.width); const maxY = Math.max(rect1.y + rect1.height, rect2.y + rect2.height); const minX = Math.min(rect1.x, rect2.x); const minY = Math.min(rect1.y, rect2.y); if ( maxX - minX <= rect1.width + rect2.width && maxY - minY <= rect1.height + rect2.height ) { return true; } else { return false; } },
三、鼠標鬆開後進行一系列操做
(1)首先獲取框選的dom,主要的方法爲getClientRects
(2)而後計算獲取的元素是否在框選範圍內
(3)對範圍內的dom進行後續操做
handleDomSelect() { const dom_mask = window.document.querySelector(".mask"); const rect_select = dom_mask.getClientRects()[0]; let selectKeys = []; document.querySelectorAll(".week-data-td").forEach((node, index) => { const rects = node.getClientRects()[0]; if (this.collide(rects, rect_select) === true) { selectKeys.push(index); } }); if (selectKeys.length < 2) return; let tableList = _.clone(this.tableData); tableList = _.map(tableList, (item, key) => { return _.map(item, (temp) => { if (selectKeys.indexOf(temp.key) > -1) { temp.checked = true; } return temp; }); }); this.tableData = tableList; },
框選這部分代碼,具體參考大佬代碼
http://www.360doc.com/content...
https://github.com/ttypZhoupe...
若是這篇文章對大佬有幫助,請不要吝嗇你的贊。來個一鍵三連就更好了,感謝大佬參閱。