原生javaScript手写简单的table.js
Posted 不羁的风
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原生javaScript手写简单的table.js相关的知识,希望对你有一定的参考价值。
JS
! function(global, factory) { typeof exports === ‘object‘ && typeof module !== ‘undefined‘ ? module.exports = factory() : typeof define === ‘function‘ && define.amd ? define(factory) : (global.Table = factory()); }(this, function() { return function(e) { //首先传递的参数必须是对象 否则报错 function isObject(obj) { return typeof obj === ‘object‘ && obj != null; } function isArray(arr) { return arr.constructor === ‘Array‘; } function create(ele) { return _doc.createElement(ele); } var _doc = document; if(!isObject(e) || isArray(e)) { throw new Error("数据类型错误"); } var _pros ={ el : e.el, url : e.url || ‘‘, data : e.data || [], sort : typeof e.sort === ‘boolean‘ && e.sort || false, columns : e.columns || [], queryParams : {}, rowNumber:typeof e.rowNumber === ‘boolean‘ && e.rowNumber || false, firstCheckBox:typeof e.firstCheckBox === ‘boolean‘ && e.firstCheckBox || false, slectRow:e.slectRow, getSelects:e.getSelects ||‘‘ } ///ajax(_pros.url, _pros.queryParams, init()); var table,tableParentNode,thead,tbody,tfoot,rows; ~function init() { //获取表格的父级元素 tableParentNode = _doc.querySelector(_pros.el); table = create("table"); table.className = "Table"; table.id = ‘table‘ + _pros.el; tableParentNode.appendChild(table); thead = create("thead"); table.appendChild(thead); tbody = create("tbody"); table.appendChild(tbody); tfoot = create("tfoot"); table.appendChild(tfoot); //添加表头 var str = ""; if(_pros.rowNumber) str += "<th style=‘display:block;width:30px;color:#ccc0;background-color: #cccccc29;‘></th>"; if(_pros.firstCheckBox)str +="<th style=‘width:30px;color:#ccc0;background-color: #cccccc29;width:130px;‘></th>"; _pros.columns.forEach(function(content) { str += "<th>" + content.field + "</th>"; }); thead.innerhtml = str; innsertTbody(); innsertTfoot(); }(); function innsertTbody() { //添加表体 rows = []; _pros.data.forEach(function(content,i) { var tr = create("tr"); var str = ""; if(_pros.rowNumber)str += "<td style=‘background-color:rgba(81, 238, 62, 0.64);color:#FFF;display: block;width:30px‘>" +(i+1)+ "</td>"; if(_pros.firstCheckBox) str += "<td style=‘background-color:rgba(167, 143, 30, 0.21);color:#FFF;width:100px;‘><input type=‘checkbox‘ style=‘width:16px;‘></input></td>"; _pros.columns.forEach(function(e) { if(content[e.data]){ str += "<td>" + content[e.data] + "</td>"; } }); rows.push(content); tr.onclick =_callFn; tr.innerHTML = str; tbody.appendChild(tr); }) } function _callFn(){ //console.log(this); var input = this.querySelector(‘input‘); if(input)input.checked =!input.checked; _pros.slectRow.call(this,rows,this.rowIndex-1); } function _callGetSelects(){ var inputs = _doc.querySelector(‘input‘); inputs.forEach(function(){ if(input.checked){ } }) _pros.getSelects.call(this,rows,this.rowIndex-1); } function innsertTfoot() { //添加表尾 var tr = create("tr"); var footstr = "<td style=‘width:100%‘><div>尾页</div><div>1</div> <div>首页</div><button id=‘exportExcle‘>导出EXCLE</button> </td>"; tr.innerHTML = footstr; tfoot.appendChild(tr); } _doc.querySelector(‘#exportExcle‘).onclick = exportExcle; //导出EXCLE function exportExcle() { if(getExplorer() == ‘ie‘) { var curTbl = _doc.getElementById("table"); var oXL = new ActiveXObject("Excel.Application"); //创建AX对象excel var oWB = oXL.Workbooks.Add(); //获取workbook对象 var xlsheet = oWB.Worksheets(1); //激活当前sheet var sel = _doc.body.createTextRange(); sel.moveToElementText(curTbl); //把表格中的内容移到TextRange中 sel.select; //全选TextRange中内容 sel.execCommand("Copy"); //复制TextRange中内容 xlsheet.Paste(); //粘贴到活动的EXCEL中 oXL.Visible = true; //设置excel可见属性 try { var fname = oXL.Application.GetSaveAsFilename("Excel.xls", "Excel Spreadsheets (*.xls), *.xls"); } catch(e) { print("Nested catch caught " + e); } finally { oWB.SaveAs(fname); oWB.Close(savechanges = false); //xls.visible = false; oXL.Quit(); oXL = null; //结束excel进程,退出完成 //window.setInterval("Cleanup();",1); idTmr = window.setInterval("Cleanup();", 1); } } else { tableToExcel(table, "报表管理信息") } } var idTmr; function getExplorer() { var explorer = window.navigator.userAgent; //ie if(explorer.indexOf("MSIE") >= 0) { return ‘ie‘; } //firefox else if(explorer.indexOf("Firefox") >= 0) { return ‘Firefox‘; } //Chrome else if(explorer.indexOf("Chrome") >= 0) { return ‘Chrome‘; } //Opera else if(explorer.indexOf("Opera") >= 0) { return ‘Opera‘; } //Safari else if(explorer.indexOf("Safari") >= 0) { return ‘Safari‘; } } function Cleanup() { window.clearInterval(idTmr); CollectGarbage(table); } /* template : 定义文档的类型,相当于html页面中顶部的<!DOCTYPE> 声明。(个人理解,不确定) encodeURIComponent:解码 unescape() 函数:对通过 escape() 编码的字符串进行解码。 window.btoa(window.encodeURIComponent(str)):支持汉字进行解码。 w :匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’ replace()方法:用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。 {(w+)}:匹配所有 {1个或更多字符} 形式的字符串;此处匹配输出内容是 “worksheet” 正则中的() :是为了提取匹配的字符串。表达式中有几个()就有几个相应的匹配字符串。 讲解(/{(w+)}/g, function(m, p) { return c[p]; } : /{(w+)}/g 匹配出所有形式为“{worksheet}”的字符串; function参数: m 正则所匹配到的内容,即“worksheet”; p 正则表达式中分组的内容,即“(w+)”分组中匹配到的内容,为“worksheet”; c :为object,见下图3 c[p] : 为“worksheet” */ var tableToExcel = (function() { var uri = ‘data:application/vnd.ms-excel;base64,‘, template = ‘<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>‘, base64 = function(s) { return window.btoa(unescape(encodeURIComponent(s))) }, // 下面这段函数作用是:将template中的变量替换为页面内容ctx获取到的值 format = function(s, c) { return s.replace(/{(w+)}/g, function(m, p) { return c[p]; } ) }; return function(table, name, filename) { if(!table.nodeType) table = _doc.getElementById(table.id) // 获取表单的名字和表单查询的内容 var ctx = { worksheet: name || ‘Worksheet‘, table: table.innerHTML }; // format()函数:通过格式操作使任意类型的数据转换成一个字符串 // base64():进行编码 window.location.href = uri + base64(format(template, ctx)) } })() //获取《style》标签样式 function getStyle(obj, attr) { return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj)[attr]; } //添加样式 !function addStyle() { var styleNode = create("style"); var tableMargin = parseFloat(getStyle(table, "margin-right")); var width = table.offsetWidth - tableMargin * 2; styleNode.innerHTML = "table tr,th,td{width:" + width + "px}"; var no_height_style="thead{padding-right: 0em;}thead tr:first-child,th{box-shadow: -1px -1.1px #CCC, 1.2px -1px #CCC;border:1px solid #ccc}"; //自定义高度 if(e.height) { //指定了高度 var o = tableParentNode.offsetHeight = e.height; var _height = e.height + thead.offsetHeight; if(_height >= o){ tbody.style.height = (o - thead.offsetHeight) + "px"; styleNode.innerHTML += no_height_style; //内容高度可以完全展示时 if(tbody.scrollHeight == tbody.clientHeight || tbody.scrollHeight < tbody.clientHeight) { //alert(); styleNode.innerHTML +="tbody tr:last-child,tbody tr:last-child td{border:1px solid #ccc;border-bottom:2px solid #ccc}"; //styleNode.innerHTML += no_height_style; } } } else { //如果没有指定tbody高度 styleNode.innerHTML += no_height_style; } _doc.head.appendChild(styleNode); }() _pros.sort && makeSorttable(table); //排序 var flag = true; //选择tr的第几个<td>的指进行排序 function sortRows(table, n) { //var tbody = table.getElementsByTagName("tbody")[0]; var tbody = table.tBodies[0]; var rows = tbody.getElementsByTagName(‘tr‘); rows = Array.prototype.slice.call(rows, 0); rows.sort(function(row1, row2) { var cell1 = row1.getElementsByTagName("td")[n]; var cell2 = row2.getElementsByTagName("td")[n]; if(cell1 && cell2) { var val1 = cell1.textContent || cell1.innerText; var val2 = cell2.textContent || cell2.innerText; if(val1 > val2) return flag ? 1 : -1; else if(val1 < val2) return flag ? -1 : 1; else return 0; } }) for(var i = 0, len = rows.length; i < len; i++) { tbody.appendChild(rows[i]); } }; //选择表格th进行排序 function makeSorttable(table) { var headers = table.getElementsByTagName("th"); /*for (var i=0,len = headers.length;i<len;i++) { (function(n){//使用闭包 headers[i].onclick=function(){ sortRows(table,n); flag = !flag; } })(i) }*/ //改进 for(let i = 0, len = headers.length; i < len; i++) { headers[i].onclick = function() { sortRows(table, i); flag = !flag; } } } // ajax封装 function ajax(url, data, callback, cache, async, type, dataType, traditional, error) { // layer.load(); var type = type || ‘post‘; //请求类型 var dataType = dataType || ‘json‘; //接收数据类型 var async = async || false; //异步请求 // var alone = alone || false;//独立提交(一次有效的提交) var cache = cache || false; //浏览器历史缓存 var traditional = traditional || false; //如果你想要用传统的方式来序列化数据,那么就设置为true var success = function(data) { // console.log(data); //layer.closeAll(); if(data.error == 0) { //服务器处理成功 if(callback != null) { callback(data.data); } } else { //服务器处理失败 toastr.error(data.info); } }; var error = error || function(data) { console.log(data); layer.closeAll(); if(data.status == 404) { toastr.error(‘请求失败,请求未找到‘); } else if(data.status == 503) { toastr.error(‘请求失败,服务器内部错误‘); } else { toastr.error(data.responseText); } }; $.ajax({ ‘url‘: url, ‘data‘: data, ‘type‘: type, ‘dataType‘: dataType, ‘async‘: async, ‘success‘: success, ‘cache‘: cache, ‘error‘: error, ‘traditional‘: traditional, ‘jsonpCallback‘: ‘jsonp‘ + (new Date()).valueOf().toString().substr(-4), }); } // submitAjax(post方式提交)同步 function submitAjax(form, success, cache) { cache = cache || true; var url = form.attr(‘action‘); var data = form.serialize(); ajax(url, data, success, cache, false, ‘post‘, ‘json‘); } // ajax提交(post方式提交)traditional 值为true 用传统的方式来序列化数据,同步 function post(url, data, success, cache) { ajax(url, data, success, cache, false, ‘post‘, ‘json‘, true); } } })
CSS
*{margin:0;padding:0} html,body{height: 100%;width: 100%;} table,tr,th,td{border-collapse:collapse ;} tr,th,td{ padding: 0; margin: 0; border: 1px solid #ccc; border-bottom: 0; } tr:not(:first-child),td:not(:last-child),tr:not(:last-child){ box-shadow: -1px -1.1px #CCC, 1.2px -1px #CCC; } tr:first-child,th:last-child,tr:last-child{ border-right:0; } table,thead,tbody{display:block;} table{ width: 80%; text-align: center; margin: 0 auto; table-layout: fixed; position: relative; word-wrap: break-word; word-break: break-all; } thead{ padding-right: 0.8em; border: 1px solid #ccc; } tbody{ overflow:auto; border: 1px solid #ccc; } tr:hover:not(:last-child){ background-color:#F0AD4E; } tfoot tr, tfoot tr td{ border: 0; display: block; } tfoot td div{ color: #2a6496; width: 40px; float: right; margin-left: 2px; margin-top: 2px; } tfoot td div:first-child,tfoot td div:last-child{ color: #FFF; border:0; background-color: #337ab7; } ::-webkit-scrollbar { width: 6px; height: 16px; background-color: #F5F5F5; } /*定义滚动条轨道 内阴影+圆角*/ ::-webkit-scrollbar-track { -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); border-radius: 10px; background-color: #b6d0c5; } /*定义滑块 内阴影+圆角*/ ::-webkit-scrollbar-thumb { border-radius: 10px; -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); background-color: #b9c355; }
DEMO
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript" src="js/table.js" ></script> <link rel="stylesheet" href="css/table.css" /> </head> <body> <div id="tb"></div> </body> <script> var t = new Table({ el:‘#tb‘, columns:[ {data:‘sex‘,field:‘性别‘}, {data:‘name‘,field:‘姓名‘}, {data:‘address‘,field:‘地址‘}, {data:‘age‘,field:‘年龄‘}, ], rowNumber:true, height:400, //firstCheckBox:true, data:[ {name:‘张三‘,age:‘28‘,sex:‘男‘,address:‘廊坊大城‘}, {name:‘李四‘,age:‘41‘,sex:‘男‘,address:‘西游‘}, {name:‘王五‘,age:‘11‘,sex:‘女‘,address:‘三国‘}, {name:‘赵六‘,age:‘51‘,sex:‘男‘,address:‘水浒‘}, {name:‘孙倩‘,age:‘51‘,sex:‘女‘,address:‘虹口‘}, {name:‘张三‘,age:‘28‘,sex:‘男‘,address:‘廊坊大城‘}, {name:‘李四‘,age:‘41‘,sex:‘男‘,address:‘西游‘}, {name:‘王五‘,age:‘11‘,sex:‘女‘,address:‘三国‘}, {name:‘赵六‘,age:‘51‘,sex:‘男‘,address:‘水浒‘}, {name:‘孙倩‘,age:‘51‘,sex:‘女‘,address:‘虹口‘}, {name:‘张三‘,age:‘28‘,sex:‘男‘,address:‘廊坊大城‘}, {name:‘李四‘,age:‘41‘,sex:‘男‘,address:‘西游‘}, {name:‘王五‘,age:‘11‘,sex:‘女‘,address:‘三国‘}, {name:‘赵六‘,age:‘51‘,sex:‘男‘,address:‘水浒‘}, {name:‘孙倩‘,age:‘51‘,sex:‘女‘,address:‘虹口‘}, {name:‘张三‘,age:‘28‘,sex:‘男‘,address:‘廊坊大城‘}, {name:‘李四‘,age:‘41‘,sex:‘男‘,address:‘西游‘}, {name:‘王五‘,age:‘11‘,sex:‘女‘,address:‘三国‘}, {name:‘赵六‘,age:‘51‘,sex:‘男‘,address:‘水浒‘}, {name:‘孙倩‘,age:‘51‘,sex:‘女‘,address:‘虹口‘}, {name:‘张三‘,age:‘28‘,sex:‘男‘,address:‘廊坊大城‘}, {name:‘李四‘,age:‘41‘,sex:‘男‘,address:‘西游‘}, {name:‘王五‘,age:‘11‘,sex:‘女‘,address:‘三国‘}, {name:‘赵六‘,age:‘51‘,sex:‘男‘,address:‘水浒‘}, {name:‘孙倩‘,age:‘51‘,sex:‘女‘,address:‘虹口‘}, {name:‘张三‘,age:‘28‘,sex:‘男‘,address:‘廊坊大城‘}, {name:‘李四‘,age:‘41‘,sex:‘男‘,address:‘西游‘}, {name:‘王五‘,age:‘11‘,sex:‘女‘,address:‘三国‘}, {name:‘赵六‘,age:‘51‘,sex:‘男‘,address:‘水浒‘}, {name:‘孙倩‘,age:‘51‘,sex:‘女‘,address:‘虹口‘}, {name:‘张三‘,age:‘28‘,sex:‘男‘,address:‘廊坊大城‘}, {name:‘李四‘,age:‘41‘,sex:‘男‘,address:‘西游‘}, {name:‘王五‘,age:‘11‘,sex:‘女‘,address:‘三国‘}, {name:‘赵六‘,age:‘51‘,sex:‘男‘,address:‘水浒‘}, {name:‘孙倩‘,age:‘51‘,sex:‘女‘,address:‘虹口‘}, {name:‘张三‘,age:‘28‘,sex:‘男‘,address:‘廊坊大城‘}, {name:‘李四‘,age:‘41‘,sex:‘男‘,address:‘西游‘}, {name:‘王五‘,age:‘11‘,sex:‘女‘,address:‘三国‘}, {name:‘赵六‘,age:‘51‘,sex:‘男‘,address:‘水浒‘}, {name:‘孙倩‘,age:‘51‘,sex:‘女‘,address:‘虹口‘}, {name:‘张三‘,age:‘28‘,sex:‘男‘,address:‘廊坊大城‘}, {name:‘李四‘,age:‘41‘,sex:‘男‘,address:‘西游‘}, {name:‘王五‘,age:‘11‘,sex:‘女‘,address:‘三国‘}, {name:‘赵六‘,age:‘51‘,sex:‘男‘,address:‘水浒‘}, {name:‘孙倩‘,age:‘51‘,sex:‘女‘,address:‘虹口‘}, {name:‘张三‘,age:‘28‘,sex:‘男‘,address:‘廊坊大城‘}, {name:‘李四‘,age:‘41‘,sex:‘男‘,address:‘西游‘} ], sort:true, slectRow:function(e,i){ console.log("下表 ======== "+i); console.log(e[i].name+"-----"+e[i].address); } }); </script> </html>
以上是关于原生javaScript手写简单的table.js的主要内容,如果未能解决你的问题,请参考以下文章