• JS学习大作业-Excel


      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4     <meta charset="utf-8" />
      5     <title>"Excel"</title>
      6     <style type="text/css">
      7         img{
      8             pointer-events: none;
      9         }
     10         #maintable {
     11             table-layout: fixed;
     12             border: #999999 1px solid;
     13             border-collapse: collapse;
     14             user-select: none;
     15         }
     16         #maintable td, #maintable th {
     17             box-sizing: border-box;
     18             user-select: none;
     19             height: 20px;
     20              65px;
     21         }
     22         #maintable td {
     23             border: #D4D4D4 1px solid;
     24         }
     25         #maintable th {
     26             border: #999999 1px solid;
     27             background-color: #E6E6E6;
     28             font-size: 13px;
     29             overflow: hidden;
     30         }
     31         #maintable .rowth {
     32              25px;
     33         }
     34         #maintable .colth {
     35             height: 30px;
     36         }
     37         .show {
     38             display: block;
     39         }
     40         .hide {
     41             display: none;
     42         }
     43         #contextmenu {
     44             position: fixed;
     45              120px;
     46             border: #D4D4D4 1px solid;
     47             background-color: white;
     48         }   
     49             #contextmenu div {
     50                 color: #333333;
     51                 padding: 5px 20px;
     52                  120px;
     53                 box-sizing: border-box;
     54                 background-color: white;
     55             }
     56                 #contextmenu div:hover {
     57                     background: #E6E6E6;
     58                 }
     59         #resizeline {
     60             pointer-events: none;
     61             position: absolute;
     62             border-left: dashed 1px red;
     63         }
     64         #selectdiv {
     65             border: green 2px solid;
     66             box-sizing: border-box;
     67             background-color: rgba(200,200,200,0.5);
     68             position: absolute;
     69             pointer-events: none; 
     70         }
     71 
     72     </style>
     73     <script type="text/javascript">
     74         window.addEventListener("load", function () {
     75             new ExcelTable("maintable", 3, 20, 20, 300, 5);
     76         });
     77         function ExcelTable(id, span, initRow, initCol, maxWidthOrHeight, minWidthOrHeight) {
     78             this.span = (undefined == span) ? 3 : span;
     79             this.initRow = initRow;
     80             this.initCol = initCol;
     81             this.maxWidthOrHeight = (undefined == maxWidthOrHeight) ? 300 : maxWidthOrHeight;
     82             this.minWidthOrHeight = (undefined == minWidthOrHeight) ? 5 : minWidthOrHeight;
     83             this.curRow = 0;
     84             this.curCol = 0;// colindex of mouseEvents.target
     85             this.resizeElem = null;// resize operator elem
     86             this.resizeFlag = false;
     87             this.downOffset = 0; //when resize,movedownEvent starting position
     88             this.upOffset = 0; //when resize,moveupEvent ending position
     89             this.selSrcElem = null;//when select,movedownEvent.target
     90             this.selDesElem = null; //when select,moveupEvent.target
     91             this.selFlag = false;    
     92             this.table = document.getElementById(id);
     93             this.allImg=null;
     94             this.resizeLine = null;
     95             this.contextMenu = null;
     96             this.selectDiv = null;
     97             var self = this;
     98             /*this.handler1 = function (e) {
     99                 //var mouseMoveElement = this;//***此时回调的this是触发此事件的元素
    100                 self.documentMouseMoveFun(e);
    101             };*/
    102             this.handler2 = function (e) {
    103                 //var mouseMoveElement = this;//***此时回调的this是触发此事件的元素
    104                 self.documentMouseUpFun(e);
    105             };
    106             //other method
    107             this.handler1 = (function (me) {
    108                 return function (e) {
    109                     me.documentMouseMoveFun(e);
    110                 };
    111             })(this);
    112             this.init();
    113         }
    114         ExcelTable.getOffSet = function (obj) {
    115             var p = new Object();
    116             p.x = obj.offsetLeft;
    117             p.y = obj.offsetTop;
    118             obj = obj.offsetParent;
    119             while (obj) {
    120                 p.x += obj.offsetLeft;
    121                 p.y += obj.offsetTop;
    122                 obj = obj.offsetParent;
    123             }
    124             return p;
    125         }
    126         ExcelTable.calcColNum = function (num) {
    127             var colNum = [];
    128             var letters = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
    129             colNum.push(letters[num % letters.length]);
    130             num = Math.floor(num / letters.length);
    131             while (num) {
    132                 --num;
    133                 colNum.push(letters[num % letters.length]);
    134                 num = Math.floor(num / letters.length);
    135             }
    136             return colNum.reverse().join("");
    137         }
    138         ExcelTable.prototype.insertRowOrCol = function () {
    139             if (this.curCol == 0) {
    140                 this.insertRow();
    141             }
    142             else if (this.curRow == 0) {
    143                 this.insertCol();
    144             }
    145         }
    146         ExcelTable.prototype.insertRow = function () {
    147             //real time get latest rowsNum,colsNum
    148             var rowsNum = this.table.rows.length;
    149             var colsNum = this.table.rows.item(0).cells.length;
    150             var row = this.table.insertRow(this.curRow);
    151             var th = document.createElement("th");//first insert a th
    152             th.className = "rowth";
    153             row.appendChild(th);
    154             for (var i = 1; i < colsNum; ++i) {
    155                 row.insertCell(i);
    156             }
    157             this.refreshRowSerialNumber();
    158         }
    159         ExcelTable.prototype.refreshRowSerialNumber = function () {
    160             //real time get latest rowsNum,colsNum
    161             var rowsNum = this.table.rows.length;
    162             for (var j = 1; j < rowsNum; ++j) {
    163                 if (j > 0) {
    164                     this.table.rows[j].cells[0].innerText = j;
    165                 }
    166             }
    167         }
    168         ExcelTable.prototype.insertCol = function () {
    169             //real time get latest rowsNum,colsNum
    170             var rowsNum = this.table.rows.length;
    171             var colsNum = this.table.rows.item(0).cells.length;
    172             var th = document.createElement("th");//first insert a th
    173             th.className = "colth";
    174             this.table.rows[0].insertBefore(th, this.table.rows[0].childNodes[this.curCol]);
    175             for (var i = 1; i < rowsNum; ++i) {
    176                 this.table.rows[i].insertCell(this.curCol);
    177             }
    178             this.refreshColSerialNumber();
    179         }
    180         ExcelTable.prototype.refreshColSerialNumber = function () {
    181             //real time get latest rowsNum,colsNum
    182             var colsNum = this.table.rows.item(0).cells.length;
    183             for (var j = 1; j < colsNum; ++j) {
    184                 this.table.rows[0].cells[j].innerText = ExcelTable.calcColNum(j - 1);
    185             }
    186         }
    187         ExcelTable.prototype.deleteRowOrCol = function () {
    188             if (this.curCol == 0) {
    189                 this.deleteRow();
    190             }
    191             else if (this.curRow == 0) {
    192                 this.deleteCol();
    193             }
    194         }
    195         ExcelTable.prototype.deleteRow = function () {
    196             //real time get latest rowsNum,colsNum
    197             var rowsNum = this.table.rows.length;
    198             var colsNum = this.table.rows.item(0).cells.length;
    199             this.table.deleteRow(this.curRow);
    200             this.refreshRowSerialNumber();
    201         }
    202         ExcelTable.prototype.deleteCol = function () {
    203             //real time get latest rowsNum,colsNum
    204             var rowsNum = this.table.rows.length;
    205             var colsNum = this.table.rows.item(0).cells.length;
    206             for (var i = 0; i < rowsNum; ++i) {
    207                 this.table.rows[i].deleteCell(this.curCol);
    208             }
    209             this.refreshColSerialNumber();
    210         }
    211         ExcelTable.prototype.showContextMenu = function (offx, offy) {
    212             this.contextMenu.style.left = offx + "px";
    213             this.contextMenu.style.top = offy + "px";
    214             this.contextMenu.className = "show";
    215         }
    216         ExcelTable.prototype.hideContextMenu = function () {
    217             this.contextMenu.className = "hide";
    218         }
    219         ExcelTable.prototype.showResizeLine = function (offx, offy) {
    220             this.resizeLine.style.left = offx + "px";
    221             this.resizeLine.style.top = offy + "px";
    222             this.resizeLine.className = "show";
    223         }
    224         ExcelTable.prototype.hideResizeLine = function () {
    225             this.resizeLine.className = "hide";
    226         }
    227         ExcelTable.prototype.contextMenuFun = function (e) {
    228             this.curRow = e.target.parentElement.rowIndex;
    229             this.curCol = e.target.cellIndex;
    230             if (this.curRow == 0 || this.curCol == 0) {
    231                 e.preventDefault();
    232                 var offx = e.clientX;//==e.screenX
    233                 var offy = e.clientY;//!=e.screenY
    234                 this.showContextMenu(offx, offy);
    235             }
    236         }
    237         ExcelTable.prototype.showSelectDiv = function (offx, offy, width, height) {
    238             this.selectDiv.className = "show";
    239             this.selectDiv.style.left = offx + "px";
    240             this.selectDiv.style.top = offy + "px";
    241             this.selectDiv.style.width = width + "px";
    242             this.selectDiv.style.height = height + "px";
    243         }
    244         ExcelTable.prototype.hideSelectDiv = function () {
    245             this.selectDiv.className = "hide";
    246         }
    247         ExcelTable.prototype.documentAddOrRemoveMouseMoveEvents = function (add) {
    248             /*var self = this;
    249             var handler = function (e) {
    250                 self.documentMouseMoveFun(e); //keynote:handler can't use "this",becauese "this" is the context variable that refers to the element that fired the event 
    251             };*/
    252             if (add) {
    253                 document.addEventListener('mousemove', this.handler1, false);
    254             }
    255             else {
    256                 document.removeEventListener('mousemove', this.handler1, false);
    257             }
    258         }
    259         ExcelTable.prototype.documentAddOrRemoveMouseUpEvents = function (add) {
    260             /*var self = this;
    261             var handler = function (e) {
    262                 self.documentMouseUpFun(e);
    263             };*/
    264             if (add) {
    265                 document.addEventListener('mouseup', this.handler2, false);
    266             }
    267             else {
    268                 document.removeEventListener('mouseup', this.handler2, false);    
    269             }
    270         }
    271         ExcelTable.prototype.documentMouseMoveFun = function (e) {    
    272             this.documentMouseMoveResizeFun(e);
    273         }
    274         ExcelTable.prototype.documentMouseUpFun = function (e) {
    275             if (this.resizeFlag) {
    276                 this.documentMouseUpResizeFun(e);
    277             }
    278             this.documentMouseUpSelectFun(e);
    279         }
    280         ExcelTable.prototype.documentMouseMoveResizeFun = function (e) {
    281             if (this.curRow == 0 && this.curCol != 0) {//resize column width
    282                 //The maximum width of the resizeElem is not more than 300px, and the minimum is no less than 5px;
    283                 if ((e.clientX - ExcelTable.getOffSet(this.resizeElem).x) <= this.maxWidthOrHeight && (e.clientX - ExcelTable.getOffSet(this.resizeElem).x) >= this.minWidthOrHeight) {
    284                     this.resizeLine.style.left = e.clientX + 'px';
    285                     this.upOffset = e.clientX;
    286                 } else if ((e.clientX - ExcelTable.getOffSet(this.resizeElem).x) > this.maxWidthOrHeight) {
    287                     this.upOffset = ExcelTable.getOffSet(this.resizeElem).x + this.maxWidthOrHeight;
    288                 } else {
    289                     this.upOffset = ExcelTable.getOffSet(this.resizeElem).x + this.minWidthOrHeight;
    290                 }
    291             }
    292             else if (this.curCol == 0 && this.curRow != 0) {//resize row height
    293                 //The maximum height of the resizeElem is not more than 300px, and the minimum is no less than 5px;
    294                 if ((e.clientY - ExcelTable.getOffSet(this.resizeElem).y) <= this.maxWidthOrHeight && (e.clientY - ExcelTable.getOffSet(this.resizeElem).y) >= this.minWidthOrHeight) { //最大不超过300px,最小不小于5px;
    295                     this.resizeLine.style.top = e.clientY + 'px';
    296                     this.upOffset = e.clientY;
    297                 } else if ((e.clientY - ExcelTable.getOffSet(this.resizeElem).y) > this.maxWidthOrHeight) {
    298                     this.upOffset = ExcelTable.getOffSet(this.resizeElem).y + this.maxWidthOrHeight;
    299                 } else {
    300                     this.upOffset = ExcelTable.getOffSet(this.resizeElem).y + this.minWidthOrHeight;
    301                 }
    302             }
    303         }
    304         ExcelTable.prototype.documentMouseUpResizeFun = function (e) {
    305            if (this.curRow == 0 && this.curCol != 0) {//resize column width
    306                 this.resizeLine.className = "hide";
    307                 var w = this.resizeElem.offsetWidth + this.upOffset - this.downOffset;
    308                 //Loop to resize width
    309                 var trs = this.table.rows;
    310                 for (var i = 0; i < trs.length; ++i) {
    311                     trs[i].cells[this.resizeElem.cellIndex].style.width = w + 'px';
    312                 }
    313             }
    314             else if (this.curCol == 0 && this.curRow != 0) {//resize row height
    315                 this.resizeLine.className = "hide";
    316                 var h = this.resizeElem.offsetHeight + this.upOffset - this.downOffset;
    317                 //Loop to resize height
    318                 var tr = this.resizeElem.parentElement;
    319                 for (var i = 0; i < tr.cells.length; ++i) {
    320                     //must use next two lines to change height
    321                     tr.cells[i].style.height = h + 'px';
    322                     tr.cells[i].style.lineHeight = h + 'px';
    323                 }    
    324             }
    325             this.resizeFlag = false;
    326             this.table.style.cursor = "default";
    327             this.resizeElem = null;
    328             this.documentAddOrRemoveMouseMoveEvents(false);
    329             this.documentAddOrRemoveMouseUpEvents(false);
    330         }
    331         ExcelTable.prototype.documentClickFun = function (e) {
    332             this.hideContextMenu();
    333         }
    334         ExcelTable.prototype.tableMouseMoveFun = function (e) {
    335             if (!this.resizeFlag) {//when  event of documentMouseMove occur,tableMouseMove also occur;so make a distinction
    336                 this.tableMouseMoveResizeFun(e);
    337             }
    338             if (this.selFlag) {
    339                 this.tableMouseMoveSelectFun(e);
    340             }
    341         }
    342         ExcelTable.prototype.tableMouseDownFun = function (e) {
    343             // deal with resize
    344             if (this.resizeElem != null) {
    345                 this.tableMouseDownResizeFun(e);
    346             }
    347             else {
    348                 //deal with  selection
    349                 this.tableMouseDownSelectFun(e);
    350             }
    351         }
    352        
    353         ExcelTable.prototype.tableMouseMoveResizeFun = function (e) {
    354             this.curRow = e.target.parentElement.rowIndex;
    355             this.curCol = e.target.cellIndex;
    356             this.table.style.cursor = "default";
    357             this.resizeElem = null;
    358             var elem_offset;
    359             if (this.curRow == 0 && this.curCol != 0) {//resize column width
    360                 //Get the mouse and element position, determine whether to trigger resize, and change the mouse style
    361                 //offsetX,offsetY:When an event occurs, the mouse is opposite the upper left corner of the e.target
    362                 elem_offset = e.target.offsetWidth;
    363                 if (elem_offset - e.offsetX <= 3) {
    364                     this.resizeElem = e.target;
    365                     this.table.style.cursor = 'e-resize'; //resizeElem.style.cursor = 'e-resize';--error,The cursor style  is valid on the entire table, otherwise the cursor style is out of reach after the resizeElem
    366                 } else if ((e.offsetX <= 3) && (this.curCol > 1)) {
    367                     this.resizeElem = e.target.previousSibling;
    368                     this.table.style.cursor = 'e-resize';
    369                 } 
    370             }
    371             else if (this.curCol == 0 && this.curRow != 0) {//resize row height
    372                 elem_offset = e.target.offsetHeight;
    373                 if (elem_offset - e.offsetY <= 3) {
    374                     this.resizeElem = e.target;
    375                     this.table.style.cursor = 's-resize';
    376 
    377                 } else if ((e.offsetY <= 3) && (this.curRow > 1)) {
    378                     //find e.target Previous column corresponding element
    379                     this.resizeElem = this.table.rows[this.curRow - 1].cells[this.curCol];
    380                     this.table.style.cursor = 's-resize';
    381                 } 
    382             }
    383             //TD element not handled 
    384         }
    385         ExcelTable.prototype.tableMouseDownResizeFun = function (e) {
    386             if (this.table.style.cursor == 'e-resize') {//resize column width
    387                 this.resizeFlag = true;
    388                 this.resizeLine.style.left = ExcelTable.getOffSet(this.resizeElem).x + this.resizeElem.offsetWidth + 'px'; //The resize line should appear on the right edge of the element
    389                 this.resizeLine.style.width = "0px";
    390                 this.resizeLine.style.height = this.table.offsetHeight + 'px'; 
    391                 this.resizeLine.style.top = ExcelTable.getOffSet(this.table).y + 'px'; 
    392                 this.resizeLine.style.borderLeft = "dashed 1px red";
    393                 this.resizeLine.className = "show";
    394                 this.downOffset = ExcelTable.getOffSet(this.resizeElem).x + this.resizeElem.offsetWidth;
    395             }
    396             else if (this.table.style.cursor == 's-resize') {//resize row height
    397                 this.resizeFlag = true;
    398                 this.resizeLine.style.left = ExcelTable.getOffSet(this.table).x + 'px'; ;
    399                 this.resizeLine.style.width = this.table.offsetWidth + 'px'; 
    400                 this.resizeLine.style.height = "1px";
    401                 this.resizeLine.style.top = ExcelTable.getOffSet(this.resizeElem).y + this.resizeElem.offsetHeight + 'px'; //The resize line should appear on the bottom edge of the element
    402                 this.resizeLine.style.borderTop = "dashed 1px red";
    403                 this.resizeLine.className = "show";
    404                 this.downOffset = ExcelTable.getOffSet(this.resizeElem).y + this.resizeElem.offsetHeight;
    405             }
    406             this.documentAddOrRemoveMouseMoveEvents(true);
    407             this.documentAddOrRemoveMouseUpEvents(true);
    408         }
    409 
    410         ExcelTable.prototype.tableMouseDownSelectFun = function (e) {
    411             if (e.target == this.table) return; //Moving outside of the table, is this.table
    412             if (e.target == this.allImg) return; //e.target isn't img
    413             //if selSrcElem is th,then selDesElem can be th or td;
    414             //But, selSrcElem is td,then selDesElem must is td;
    415             this.selFlag = true;
    416             this.selSrcElem = e.target;
    417             this.selDesElem = e.target;
    418             this.documentAddOrRemoveMouseUpEvents(true);
    419         }
    420         ExcelTable.prototype.tableMouseMoveSelectFun = function (e) {
    421             if (e.target == this.table) return;
    422             if (e.target == this.allImg) return;
    423             if ((this.selSrcElem.tagName == "TD") && (e.target.tagName != "TD")) return;
    424             this.selDesElem = e.target;
    425             this.calSelectPositionFun();
    426         }
    427         ExcelTable.prototype.calSelectPositionFun = function () {
    428             var selSrcRow = this.selSrcElem.parentElement.rowIndex;
    429             var selSrcCol = this.selSrcElem.cellIndex;
    430             var selDesRow = this.selDesElem.parentElement.rowIndex;
    431             var selDesCol = this.selDesElem.cellIndex;
    432 
    433             var srcOffx = ExcelTable.getOffSet(this.selSrcElem).x;
    434             var srcOffy = ExcelTable.getOffSet(this.selSrcElem).y;
    435             var DesOffx = ExcelTable.getOffSet(this.selDesElem).x;
    436             var DesOffy = ExcelTable.getOffSet(this.selDesElem).y;
    437             var divwidtd = (DesOffx > srcOffx) ? this.selDesElem.offsetWidth : this.selSrcElem.offsetWidth;
    438             var divheight = (DesOffy > srcOffy) ? this.selDesElem.offsetHeight : this.selSrcElem.offsetHeight;
    439 
    440             if ((selSrcRow != 0 && selSrcCol != 0) && (selDesRow != 0 && selDesCol != 0)) {
    441                 this.showSelectDiv(Math.min(srcOffx, DesOffx), Math.min(srcOffy, DesOffy), Math.abs(DesOffx - srcOffx) + divwidtd, Math.abs(DesOffy - srcOffy) + divheight);
    442             }
    443             else if ((selSrcCol == 0 && selSrcRow != 0) && (selDesRow != 0)) {//选择行
    444                 this.showSelectDiv(ExcelTable.getOffSet(this.selSrcElem).x, Math.min(srcOffy, DesOffy), this.table.offsetWidth, Math.abs(DesOffy - srcOffy) + divheight);
    445             }
    446             else if ((selSrcRow == 0 && selSrcCol != 0) && (selDesCol != 0)) {//选择行
    447                 this.showSelectDiv(Math.min(srcOffx, DesOffx), ExcelTable.getOffSet(this.selSrcElem).y, Math.abs(DesOffx - srcOffx) + divwidtd, this.table.offsetHeight);
    448             }
    449         }
    450         ExcelTable.prototype.documentMouseUpSelectFun = function (e) {
    451             // selDesElem is the last valid value in tableMouseMoveSelectFun
    452             this.selFlag = false;
    453             if (this.selSrcElem == null) return;
    454             this.calSelectPositionFun();
    455             this.documentAddOrRemoveMouseUpEvents(false);
    456         }
    457         ExcelTable.prototype.initTable = function () {
    458             var elemTd = null;
    459             var elemTr = null;
    460             for (var i = 0; i < this.initRow; ++i) {
    461                 elemTr = document.createElement("tr");
    462                 for (var j = 0; j < this.initCol; ++j) {
    463                     if (i == 0 && j == 0) {
    464                         elemTd = document.createElement("th");
    465                         elemTd.className = "rowth";
    466                         this.allImg = document.createElement("img");
    467                         this.allImg.src = "img/all.jpg";
    468                         elemTd.appendChild(this.allImg);
    469                     }
    470                     else if (i == 0) {
    471                         elemTd = document.createElement("th");
    472                         elemTd.className = "colth";
    473                         elemTd.innerText = ExcelTable.calcColNum(j - 1);
    474                     }
    475                     else if (j == 0) {
    476                         elemTd = document.createElement("th");
    477                         elemTd.className = "rowth";
    478                         elemTd.innerText = i;
    479                     }
    480                     else {
    481                         elemTd = document.createElement("td");
    482                     }
    483                     elemTr.appendChild(elemTd);
    484                 }
    485                 this.table.appendChild(elemTr);
    486             }
    487         }
    488         ExcelTable.prototype.initContextMenu = function () {
    489             this.contextMenu = document.createElement("div");
    490             this.contextMenu.id = "contextmenu";
    491             var elemInsert = document.createElement("div");
    492             elemInsert.innerText = "insert";
    493             this.contextMenu.appendChild(elemInsert);
    494             var elemDelete = document.createElement("div");
    495             elemDelete.innerText = "delete";
    496             this.contextMenu.appendChild(elemDelete);
    497             //var self = this;
    498             //elemInsert.addEventListener("click", function () {
    499             //    self.insertRowOrCol();
    500             //});//Two methods are available
    501             elemInsert.addEventListener("click", (function (me) {
    502                 return function () {
    503                     me.insertRowOrCol();
    504                 };
    505             })(this));
    506             var self = this;
    507             elemDelete.addEventListener("click", function () {
    508                 self.deleteRowOrCol();
    509             });
    510             document.body.appendChild(this.contextMenu);
    511             this.hideContextMenu();
    512         }
    513         ExcelTable.prototype.initResizeLine = function () {
    514             this.resizeLine = document.createElement('div');
    515             this.resizeLine.id = "resizeline";
    516             document.body.appendChild(this.resizeLine);
    517             this.hideResizeLine();
    518         }
    519         ExcelTable.prototype.initSelectDiv = function () {
    520             this.selectDiv = document.createElement('div');
    521             this.selectDiv.id = "selectdiv";
    522             document.body.appendChild(this.selectDiv);
    523             this.hideSelectDiv();
    524 
    525         }
    526         ExcelTable.prototype.init = function () {
    527             //initialize table
    528             this.initTable();
    529             //initialize contextmenu
    530             this.initContextMenu();
    531             //initialize resizeLine
    532             this.initResizeLine();
    533             //initialize selectDiv
    534             this.initSelectDiv();
    535             
    536             this.addEvents = (function (self) {
    537                 self.table.addEventListener("contextmenu", function (e) {
    538                     self.contextMenuFun(e);
    539                 });
    540                 self.table.addEventListener("mousemove", function (e) {
    541                     self.tableMouseMoveFun(e);
    542                 });
    543                 self.table.addEventListener("mousedown", function (e) {
    544                     self.tableMouseDownFun(e);
    545                 });
    546 
    547                 document.addEventListener("click", function (e) {
    548                     self.documentClickFun(e);
    549                 });
    550             })(this);
    551         }
    552     </script>
    553 </head>
    554 <body>
    555     <table id="maintable"></table>
    556 </body>
    557 </html>
    View Code

    实现的功能如下:

    1.插入,删除

    2.改变列宽和行高

    3.选择功能

    存在的bug:当执行了操作2和3之后,再执行1,行高会改变,选择区域也无法刷新。

    学到的知识:

    1. 尽量不用innerHTML,代码不清楚,耗费编译资源大,用innerText取代,或者使用createElement

    2.js中少修改style,可以通过添加className来修改,前提是在css中设定好.class 的样式

    3.事件之间的关系:鼠标move事件documentMouseMove和tableMouseMove都会触发,置于执行顺序这就涉及到冒泡与捕获的关系

                             oncontext会触发mousedown,mouseup等

                             onclick和ondbclick会同时存在,一般通过在oclick中加timeout来区分,后续学习。

    4.事件响应函数中的this,两种方法,不能直接使用this,因为this始终指向当前上下文,对于事件响应函数中的this只当前响应元素。

        elemInsert.addEventListener("click", (function (me) {
          return function () {
            me.insertRowOrCol();
          };
        })(this));


        var self = this;
        elemDelete.addEventListener("click", function () {
          self.deleteRowOrCol();
        });

    5.js函数类 哪些设为成员变量(每个对象都需要单独有一份),哪些设为类的方法(工具方法),哪些设为原型方法

    6.修改表格的行列高:

    //Loop to resize width
    var trs = this.table.rows;
    for (var i = 0; i < trs.length; ++i) {
    trs[i].cells[this.resizeElem.cellIndex].style.width = w + 'px';
    }

    //Loop to resize height
    var tr = this.resizeElem.parentElement;
    for (var i = 0; i < tr.cells.length; ++i) {
    //must use next two lines to change height
    tr.cells[i].style.height = h + 'px';
    tr.cells[i].style.lineHeight = h + 'px';
    }

    7.两个重要的属性:

     pointer-events: none;//表示它将捕获不到任何点击,而只是让事件穿透到它的下面。

    user-select: none;//文本不能被选择

    8.参数,默认参数

    在Javascript中, 函数定义的参数个数, 与调用时传入的参数个数,是可以不同的.
    一般情况下,在定义函数时,将必须传入的参数放在前面, 可选的参数放在后面.在函数体内部需要对参数的传入情况作判断,以防参数不存在时程序出错.
    例如
    function js(x, y, z) {
    this.x = x || 0;//或者this.span = (undefined == span) ? 3 : span;
    this.y = y || 0;
    this.z = z || 0;
    }

    调用时可以传入0-3个参数都不会出错,但传参的顺序是已经定了的.
    比如:
    var A = new js(); //A.x=0, A.y=0, A.z=0
    var A=new js(5, 3); //A.x=5, A.y=3, A.z=0

    如果只想传递参数y, 则必须传递两个参数,其中第一个可传入null或0

    如x是可选y是必选,建议在定义函数时改变形参的顺序

    9.几个变量:elem.offsetLeft,elem.offsetTop,elem.offsetParent

                    elem.offsetWidth,elem.offsetHeight,

                    e.offsetX,e.offsetY

                    e.screenX,e.screenY

    10,尽量使用addEventListener和removeEventListener,少用onclick方法添加事件响应函数,因为onclick方法会存在覆盖行为,前者可以添加多个事件处理程序

    注意:addEventListener和removeEventListener中第二个参数指向的函数必须是同一个,因此必须在外面定义好handler,才能确保使用的是同一个函数,如果在内部分别定义,及时函数体相同,也是指向不同位置的不同函数。详细可参见代码中例子。

    问题:addEventListener和removeEventListener次数不对称会怎样?

    通过addEventListener()添加的事件处理程序只能使用removeEventListener()来移除;移除时传入的参数与添加处理程序时使用的参数相同。这也意味着通过addEventListener()添加的匿名函数无法移除,如下面的例子所示:

    复制代码
    var btn = document.getElementById("myBtn");
    btn.addEventListener("click", function () {
        alert(this.id);
    }, false);
    btn.removeEventListener("click", function () {  //无效!
        alert(this.id);
    }, false);

    11.表格操作:

    获取当前元素行列号:this.curRow = e.target.parentElement.rowIndex;
                                this.curCol = e.target.cellIndex;

    获取表格行列数: var rowsNum = this.table.rows.length;
             var colsNum = this.table.rows.item(0).cells.length;

    插入行:

         var row = this.table.insertRow(this.curRow);
        for (var i = 1; i < colsNum; ++i) {
        row.insertCell(i);
        }

    删除行:this.table.deleteRow(this.curRow);

    插入列:

      for (var i = 0; i < rowsNum; ++i) {
      this.table.rows[i].insertCell(this.curCol);
      }

    删除列:

      for (var i = 0; i < rowsNum; ++i) {
      this.table.rows[i].deleteCell(this.curCol);
      }

    12.消息处理事件函数参数必须写上e,负责函数体内默认的e为全局event对象,类似window对象

    需要继续学习:

    1.table 布局  其属性:width height overFlow:scroll

    给 thead tbody tfoot上添加事件

    2.JS浮点数运算

  • 相关阅读:
    应用express mockjs模拟前端json数据接口
    sublime text3 cssrem 快速px转rem插件
    python多版本共存问题(以2.7和3.5系列版本为例)
    免费的大数据学习资料,这一份就足够
    大数据时代的三大趋势和三大困境
    四个填空题,你会如何回答怎么学大数据?看看阿里的大数据学习!
    为什么学习大数据,大数据专家写给大数据分析学习者的10个理由
    你知道大数据强大在哪里!!!你永远也不会猜到
    大数据的强大你知道多少
    零基础入门到精通:Python大数据与机器学习之Pandas-数据操作
  • 原文地址:https://www.cnblogs.com/Yogurshine/p/6985405.html
Copyright © 2020-2023  润新知