最近公司閒的dan疼,非要模仿Excel作一個網頁版的Excel,剛開始據說要作這麼一個東西的時候瞬間以爲公司領導高(sang)瞻(xin)遠(bing)矚(kuang),只能頭鐵的接下了,那就開始幹。其實主要目的是爲了能連上本身的數據庫,方便操做表格,後來發現實現成本過高,作了一個前端DEMO就果斷放棄了,可是這個DEMO仍是有點意思,發開DEMO過程當中有些心得與收穫。
https://github.com/zhuqitao/E... css
先看看目前的效果圖:html
領導說先作一個demo看看效果,那就亮出咱家的看家本領吧html+css+js三劍客,不就是表格嗎,html填上table,修修樣式,頁面效果就ok了。前端
第一個碰到的問題就是滾動問題,看上面的截圖就知道其實這是一種表格表頭固定,表格第一列固定,其餘部分滾動的效果,可是其實沒有那麼簡單,還有一個問題是垂直滾動的時候第一行(表頭)不動,可是第一列得跟着動啊,水平滾動亦是如此,這可怎麼辦啊,這種狀況沒遇到過啊,可是得解決啊。vue
不知道的網友們能夠考慮考慮怎麼作? 知道怎麼處理這種狀況的也別噴博主菜。
最後的解決方法就是寫了三個table,一個放表頭(第一行),一個放第一列,一個放表格主要內容,看下圖:react
table1放置表頭(A,B,C),table2放置第一列,table3放置中間操做區域,把table一、2設置爲overflow:hidden,只有table3能夠滾動,監聽table3的滾動事件,獲取table3的scrollLeft和scrollTop而後分別給table一、table2的scrollLeft和scrollTop賦值。jquery
這個是本DEMO惟一的亮點了(我的認爲)。
表格目前定下的是30*30的表格。一開始的想法是監聽鼠標按下(mousedown)事件獲取鼠標按下時的位置,而後再監聽鼠標移動事件(mousemove),獲取鼠標當前的位置,而後根據當前位置和按下時位置畫一個矩形,循環遍歷全部的單元格元素,判斷單元格是否在矩形內,而後給選中的單元格添加active類。git
這樣作的結果是頁面很是卡,由於鼠標移動過程會屢次觸發鼠標移動事件(mousemove),會屢次進行單元格元素循環遍歷。 後來就不在鼠標移動事件裏面進行單元格遍歷操做,在鼠標鬆開事件裏面遍歷全部的單元格元素。github
這樣確實快了一些,可是還有一個問題上面兩種方法都沒解決的問題,就是若是選擇了不少元素(好比100個),在遍歷單元格元素的時候須要對着100個元素操做添加active類,其實js操做操做DOM是比較耗時的,這裏也沒有想到什麼好的DOM操做緩存的方法。web
就在束手無策的時候想到了目前流行的虛擬dom框架(react、vue等),果斷使用了vue。在vue實例裏建立兩個對象數組,分別做爲行數據和列數據,頁面上分別對<tr>和<td>標籤使用v-for循環渲染,這樣就能生成一張表格。每一個單元格都給加上行數和列樹標誌。算法
在鼠標按下獲取鼠標按下時所在單元格的行數和列數,鼠標鬆開時獲取鬆開時所在單元格的行數和列數,而後先循環行數據的數組,全部在選中的行數的數據對象添加選中標誌,而後再循環列數據的數組,全部在選中的列數的數據對象添加選中標誌,在頁面對<tr>和<td>標籤使用v-for循環渲染時動態綁定class類,只有行和列同時被選中,單元格才設置爲選中狀態,這樣其實只循環了30+30=60次,瞬間把複雜度有原來的O(n^2)下降到O(2n)。
其實背後是經過vue的diff算法快速的計算出須要改變的dom元素,而後利用虛擬dom快速渲染到頁面上,速度大大提高。這也讓我真實的感覺到這些框架的威力(怪不得這麼火)。
個人語言表達能力不是很強,上面說的你們不知道有沒有聽明白,沒明白的能夠看看源代碼(^︹^)。
有一款jquery插件js-xlsx能夠幫助在線打開本地xls文件,並把xls文件轉成json。
利用xml的createElementNS建立帶有指定命名空間的元素節點,再利用js自帶Blob數據類型保存xls文件:
var urlObject = window.URL || window.webkitURL || window; var export_blob = new Blob(['test']); var save_link = document.createElementNS("http://www.w3.org/1999/xhtml", "a") var ev = document.createEvent("MouseEvents"); ev.initMouseEvent( "click", true, false, window, 0, 0, 0, 0, 0 , false, false, false, false, 0, null ); save_link.href = urlObject.createObjectURL(export_blob); save_link.download = 'test.xls'; save_link.dispatchEvent(ev);
當一個HTML文檔切換到設計模式 designMode時,文檔對象暴露 execCommand 方法,該方法容許運行命令來操縱可編輯區域的內容。詳情查看MDN地址:https://developer.mozilla.org...
AbsolutePosition 設定元素的 position 屬性爲「absolute」(絕對)。 BackColor 設置或獲取當前選中區的背景顏色。 BlockDirLTR 目前還沒有支持。 BlockDirRTL 目前還沒有支持。 Bold 切換當前選中區的粗體顯示與否。 BrowseMode 目前還沒有支持。 Copy 將當前選中區複製到剪貼板。 Paste 用剪貼板內容覆蓋當前選中區(目前還沒有支持)。 ... // 例子 document.execCommand("copy") document.execCommand("cut") document.execCommand('paste')
獲取鼠標選中的文本
手動設置剪切板,通常用於用戶複製內容時添加版權信息。