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. width: 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. width: 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. width: 120px;
  46. border: #D4D4D4 1px solid;
  47. background-color: white;
  48. }
  49. #contextmenu div {
  50. color: #333333;
  51. padding: 5px 20px;
  52. width: 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>

实现的功能如下:

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.参数,默认参数

  1. Javascript中, 函数定义的参数个数, 与调用时传入的参数个数,是可以不同的.
    一般情况下,在定义函数时,将必须传入的参数放在前面, 可选的参数放在后面.在函数体内部需要对参数的传入情况作判断,以防参数不存在时程序出错.
    例如
    function js(x, y, z) {
    this.x = x || 0;//或者this.span = (undefined == span) ? 3 : span;
    this.y = y || 0;
    this.z = z || 0;
    }
  2.  
  3. 调用时可以传入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
  4.  
  5. 如果只想传递参数y, 则必须传递两个参数,其中第一个可传入null0
  6.  
  7. 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()添加的匿名函数无法移除,如下面的例子所示:

  1. var btn = document.getElementById("myBtn");
  2. btn.addEventListener("click", function () {
  3. alert(this.id);
  4. }, false);
  5. btn.removeEventListener("click", function () { //无效!
  6. alert(this.id);
  7. }, 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浮点数运算

JS学习大作业-Excel的更多相关文章

  1. Python验证码识别处理实例 深度学习大作业

    转载自:http://python.jobbole.com/83945/ http://www.pyimagesearch.com/2014/09/22/getting-started-deep-le ...

  2. js大作业(0)

    DAY1:在看HTML5游戏开发实战.手写了一遍乒乓球.自己玩了半小时.实话讲,和本科学的MFC差别不大.通过setInterval函数获取用户的输入 从而允许多用户操作.parseInt把字符串化为 ...

  3. c++小学期大作业攻略(一)环境配置

    UPDATE at 2019/07/20 20:21 更新了Qt连接mysql的方法,但是是自己仿照连VS的方法摸索出来的,简单测试了一下能work但是不保证后期不会出问题.如果你在尝试过程中出现了任 ...

  4. 软件工程大作业(学生会管理系统)Web端个人总结报告

    软件工程大作业(学生会管理系统)Web端个人总结报告 一.小组信息 1.所在小组:第二组 2.小组选题:学生会管理系统 3.项目源代码链接: Web端源代码:code 小程序端源代码:code APP ...

  5. 大作业:开发一个精美的 Web 网站

    大作业:开发一个精美的 Web 网站 实验目的: 掌握一个完整精美网页开发的基本方法 实验要求: 1.开发一个 Web 站点,至少有 3 个以上的页面: 2.采用 CSS 和 HTML 文件分开方法: ...

  6. 【Knockout.js 学习体验之旅】(1)ko初体验

    前言 什么,你现在还在看knockout.js?这货都已经落后主流一千年了!赶紧去学Angular.React啊,再不赶紧的话,他们也要变out了哦.身旁的90后小伙伴,嘴里还塞着山东的狗不理大蒜包, ...

  7. 数据库大作业--由python+flask

    这个是项目一来是数据库大作业,另一方面也算是再对falsk和python熟悉下,好久不用会忘很快. 界面相比上一个项目好看很多,不过因为时间紧加上只有我一个人写,所以有很多地方逻辑写的比较繁琐,如果是 ...

  8. NODE.JS学习的常见误区及四大名著

    NODE.JS学习的常见误区及四大名著 前段时间由于不满于社区里很多人对于NODE.JS的种种误解而写了一篇文章名为: NODE.JS之我见:http://www.cnblogs.com/pugang ...

  9. JS 学习笔记--9---变量-作用域-内存相关

    JS 中变量和其它语言中变量最大的区别就是,JS 是松散型语言,决定了它只是在某一个特定时间保存某一特定的值的一个名字而已.由于在定义变量的时候不需要显示规定必须保存某种类型的值,故变量的值以及保存的 ...

随机推荐

  1. HTML5 学习02——新元素:canvas

    HTML5 Canvas <canvas>标签:使用脚本 (通常是JavaScript)来绘制图形——默认情况下 <canvas> 元素没有边框和内容. 在画布上(Canvas ...

  2. SharePoint PowerShell 修改母版页

    前言 最近在群里帮忙回答问题,碰到这么一个尴尬的问题,有人创建了一个新母版页,然后引用了新的母版页,不知道怎么的母版页有问题了,再也进不去站点了,希望修改回旧的母版页. 看到问题,想了一下,其实两种方 ...

  3. Java名称字符串进行星号处理

    /** * 对字符串处理:将指定位置到指定位置的字符以星号代替 * * @param content * 传入的字符串 * @param begin * 开始位置 * @param end * 结束位 ...

  4. 对类的理解(c++)

    介绍目录: 1.类成员 1.1 成员函数 1.2 构造函数 1.2.1 对构造函数的理解 1.2.2成员初始化列表 1.2.3必须使用成员初始化列表的几种情况 1.2.4对于拷贝构造函数的参数是一个引 ...

  5. SAP传输请求自动发布

        最近公司服务器做迁移,原R3 PRE需要迁到另外的地方,迁移后一段时间内,需要两套PRE环境同时运行,过一段时间后才将传输路线切换到新的PRE.在切换前,要求新PRE环境也要正常同步发布请求, ...

  6. grid - 通过网格区域命名和定位网格项目

    1.像网格线名称一样,网格区域的名称也可以使用grid-template-areas属性来命名.引用网格区域名称也可以设置网格项目位置. 设置网格区域的名称应该放置在单引号或双引号内,每个名称由一个空 ...

  7. 【PMP】组织结构类型

    1.简单型 描述:人员并肩工作,所有者/经营者直接做出主要决定并监督执行. PM角色:兼职(协调员) PM权限:极少(无) 项目管理人员:极少(无) 资源可用性:极少(无) 项目预算管理人:负责人 2 ...

  8. C# string 是不可变的,指什么不可变

    String 表示文本,即一系列 Unicode 字符.字符串是 Unicode 字符的有序集合,用于表示文本.String 对象是 System.Char 对象的有序集合,用于表示字符串.Strin ...

  9. 关于安装 Microsoft Office

    安装 Microsoft Office 道路可谓漫漫…… 学校信息网络中心提供的“正版Office”安装了好几次都没成功…… [关于安装包和安装] 看了这篇经验,还不错:  office2018官方下 ...

  10. C#设计模式 ---- 总结汇总

    一.引言 C#版本的23种设计模式已经写完了,现在也到了一个该总结的时候了.说起设计模式,我的话就比较多了.刚开始写代码的时候,有需求就写代码来解决需求,如果有新的需求,或者需求变了,我就想当然的修改 ...