还未完成的开发(构想中,有时间再写吧)
1、列的显示/隐藏
2、固定列
3、分页
4、支持加载异步数据
5、多级表头
表头属性
属性名 | 描述 | 类型 | 默认值 |
---|---|---|---|
key | 设置字段名。通常是表格数据列的唯一标识 |
string | - |
label | 设置列的标题。 |
string | - |
width | 设置列宽。若不填写,则自动分配;若填写,则支持值为:数字、百分比。如: |
number/string | - |
align | 单元格排列方式。可选值有: |
string |
|
templet | {key: "name", label:"姓名", align: "left", tempelt:function(d){ return ''+d.name+''; }}, |
function | - |
设置固定列,即不跟随 table 横向滚动条而滚动。可选值有:
|
string | - |
表格基础属性
属性名 | 描述 | 类型 | 默认值 |
---|---|---|---|
el | 绑定原始 table 元素,必填。 | string/DOM | - |
height | 设置表格容器高度,默认自适应。其他可选值的规则如下:
|
number string |
- |
resizable | 表格宽度随页面大小变化自适应 | boolean | true |
rows | 表头属性集,通过数组定义表头,必填。 更多表头属性见 : 表头属性 |
array | - |
data | 直接赋值数据。既适用于只展示一页数据 | array | - |
shaoyu.js
(function (global) {
"use strict";
var Shaoyu = function () {
this.options = {
el: "",
page: true,
rows: [],
height: "",
data: [],
keys: [],
resizable: true
};
this.cellMinWidth = 80;
this.isSzScroll = false;
this.isHxScroll = false;
this.kongyuWidth = 0;
};
Shaoyu.prototype = {
init: function (config) {
var _this = this;
if (!config.el) {
console.error("el is required!");
return false;
}
config.el = _this.getDom(config.el);
_this.options = Object.assign(this.options, config);
var str = '';
_this.append(_this.options.el, str, 1);
_this.render();
return _this;
},
render: function () {
this.renderHeader();
this.renderBody();
this.renderCellWidth();
this.bindEvent();
},
//渲染头部
renderHeader: function () {
var cellStyleArr = [];
cellStyleArr.push(".shaoyu-table-content{border-width: 1px;border-style: solid;border-color: #eee;}");
cellStyleArr.push(".shaoyu-table tbody tr:hover,.shaoyu-table thead tr{ background-color: #FAFAFA;}");
// cellStyleArr.push("th:nth-last-child(1),td:nth-last-child(1){ border-right: none !important;}");
cellStyleArr.push('.shaoyu-table-thead>tr>th{padding:5px 0;border-top:none;border-left:none;border-width:1px;border-style:solid;border-color:#eee;font-weight: 400;}');
cellStyleArr.push(".shaoyu-table-cell{height:28px;line-height:28px;padding:0 15px;position:relative;box-sizing:border-box;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}");
cellStyleArr.push(".shaoyu-table-tbody>tr>td{border-width:1px;border-style:solid;border-color:#eee;}");
cellStyleArr.push(".shaoyu-table-thead>tr>th,.shaoyu-table-tbody>tr>td{position:relative;padding:0px 15px;min-height:20px;line-height:20px;font-size:14px;border-top: none;border-left: none;}");
cellStyleArr.push("div.shaoyu-table-content .shaoyu-table{border-collapse:collapse;border-spacing:0;background-color:#fff;color:#666;}");
var str = "";
var _this = this;
_this.options.rows.map((x, i) => {
str = str + '' + x.label + ' ';
_this.options.keys.push(x.key);
cellStyleArr.push('.shaoyu-table-cell-' + x.key + '{text-align: ' + (x.align ? x.align : left) + ';}');
})
str = '' + str + ' ';
var el = document.querySelector("div.shaoyu-table-content div.shaoyu-table-header table");
cellStyleArr.push("div.shaoyu-table-body{height:" + this.options.height + "px;overflow: auto;}");
_this.append(el, str, 2);
_this.renderStyle(cellStyleArr);
},
renderStyle: function (arr) {
arr.unshift("");
this.append(document.querySelector("html head"), arr.join(""), 1);
},
//计算每列列宽
renderCellWidth: function () {
var cellStyleArr = [];
var _this = this;
var allWidth = _this.options.el.offsetWidth;
var hasWidthCellNum = 0;
var overedWidth = 0;
_this.options.rows.map(x => {
if (x.hasOwnProperty("width")) {
hasWidthCellNum++;
overedWidth = overedWidth + x.width;
cellStyleArr.push(".shaoyu-table-cell-" + x.key + "{width: " + x.width + "px;}")
}
});
console.log(_this.isSzScroll, _this.isHxScroll)
if (((_this.options.rows.length - hasWidthCellNum) * _this.cellMinWidth + overedWidth) < allWidth) {//如果所有列宽度没有超过容器宽度
if(_this.isSzScroll){
var residueWidth = allWidth - overedWidth - hasWidthCellNum * 32-15;
var cellWidth = Math.ceil(residueWidth / (_this.options.rows.length - hasWidthCellNum));
console.log(cellWidth);
cellWidth = (cellWidth - 32) > _this.cellMinWidth ? cellWidth - 32 : _this.cellMinWidth;
}else{
var residueWidth = allWidth - overedWidth - hasWidthCellNum * 32;
var cellWidth = Math.ceil(residueWidth / (_this.options.rows.length - hasWidthCellNum));
cellWidth = (cellWidth - 32) > _this.cellMinWidth ? cellWidth - 32 : _this.cellMinWidth;
}
_this.kongyuWidth = allWidth-overedWidth-hasWidthCellNum*32-((_this.options.rows.length - hasWidthCellNum)*(cellWidth+31));
_this.kongyuWidth = _this.kongyuWidth>0?_this.kongyuWidth:0;
if(_this.isSzScroll){
_this.kongyuWidth = _this.kongyuWidth-16;
}
console.log(allWidth,overedWidth,hasWidthCellNum,residueWidth,cellWidth,_this.kongyuWidth);
var firstNode = null;
_this.options.rows.map((x,i) => {
if (!x.hasOwnProperty("width")) {
if(!firstNode){
firstNode = true
cellStyleArr.push(".shaoyu-table-cell-" + x.key + "{width: " + (cellWidth+_this.kongyuWidth) + "px;}")
}else{
cellStyleArr.push(".shaoyu-table-cell-" + x.key + "{width: " + cellWidth + "px;}")
}
}
});
}else {//如果所有列宽度超过容器宽度
_this.options.rows.map(x => {
if (!x.hasOwnProperty("width")) {
cellStyleArr.push(".shaoyu-table-cell-" + x.key + "{width: " + _this.cellMinWidth + "px;}")
}
});
}
if(_this.isSzScroll){
cellStyleArr.push("th:nth-last-child(2){ border-right: solid 1px #eee !important;}")
}else{
if(_this.isHxScroll){
cellStyleArr.push("th:nth-last-child(2){ border-right: none !important;}")
}
}
_this.renderStyle(cellStyleArr);
},
//判断是否有滚动条:vertical纵轴,horizontal横轴
hasScrolled: function (element, direction) {
if (direction === 'vertical') {
return element.scrollHeight > element.clientHeight;
} else if (direction === 'horizontal') {
if (this.isSzScroll) {
return element.scrollWidth > element.clientWidth + 17;
}
return element.scrollWidth > element.clientWidth;
}
},
//渲染body
renderBody: function () {
var _this = this;
var str = '
';
var el = document.querySelector("div.shaoyu-table-content");
_this.append(el, str, 1);
_this.options.data.map(x => {
var str = "";
_this.options.rows.map(y => {
if (y.hasOwnProperty("tempelt")) {
str = str + '' + y.tempelt(x) + ''
} else {
str = str + '{{' + y.key + '}}'
}
})
str = '' + str + ' ';
var el = document.querySelector("div.shaoyu-table-content div.shaoyu-table-body table tbody");
_this.append(el, str, 2);
_this.parseData(el, x)
})
_this.onscroll();
//如果有竖向滚动
_this.isSzScroll = _this.hasScrolled(document.querySelector("#container div.shaoyu-table-content div.shaoyu-table-body"), "vertical");
_this.isHxScroll = _this.hasScrolled(document.querySelector("#container div.shaoyu-table-content div.shaoyu-table-body"), "horizontal");
if (_this.isSzScroll) {
var str = ' ';
var el = document.querySelector("div.shaoyu-table-content div.shaoyu-table-header table tr");
_this.append(el, str, 3);
}
var cellStyleArr = [];
if (_this.isSzScroll) {
cellStyleArr.push(".shaoyu-table-tbody>tr:nth-last-child(1)>td{ border-bottom: none !important;}");
_this.renderStyle(cellStyleArr);
}
},
//获取元素
getDom: function (el) {
return typeof el === "string" ? document.querySelector(el) : el;
},
//插入元素
append: function (dom, str, type) {
var _this = this;
[].forEach.call(_this.parseDom(str, type), function (el) {
dom.append(el);
});
},
//生成dom元素
parseDom: function (arg, type) {
var objE = document.createElement("div");
if (type == 2) {
objE = document.createElement("table");
} else if (type == 3) {
objE = document.createElement("tr");
}
objE.innerHTML = arg;
return objE.childNodes;
},
//解析模板字符串
parseData: function (el, data) {
let html = template(el, data)
if (typeof el === "string") {
document.getElementById(id).innerHTML = html;
} else {
el.innerHTML = html;
};
function template(id, obj) {
let tem = "";
if (typeof el === "string") {
tem = document.getElementById(id).innerHTML;
} else {
tem = el.innerHTML
}
let reg = /{{(\w*)}}/
let arr = []
while (arr = reg.exec(tem)) {
tem = tem.replace(arr[0], obj[arr[1]])
}
return tem
}
},
onscroll: function () {
var fixedDom = document.querySelector("#container div.shaoyu-table-content div.shaoyu-table-body");
fixedDom.addEventListener('scroll', winScroll, false);
function winScroll(e) {
//横向滚动
document.querySelector("#container div.shaoyu-table-content div.shaoyu-table-header").scrollLeft = fixedDom.scrollLeft;
// if (fixedDom.offsetLeft < document.body.scrollLeft) {
// };
// if (fixedDom.offsetLeft > document.body.scrollLeft) {
// };
}
},
bindEvent: function () {
var _this = this;
var timer;
window.onresize = function () {
if (timer) {
window.clearTimeout(timer)
};
timer = setTimeout(() => {
if (_this.options.resizable) {
var width = _this.options.el.parentNode.clientWidth;
_this.options.el.style.width = width + "px";
_this.renderCellWidth();
}
// 清空计时器
timer = null
}, 500)
}
}
};
//兼容CommonJs规范
if (typeof module !== 'undefined' && module.exports) module.exports = Shaoyu;
//兼容AMD/CMD规范
if (typeof define === 'function') define(function () {
return Shaoyu;
});
//注册全局变量,兼容直接使用script标签引入该插件
global.Shaoyu = Shaoyu;
//this,在浏览器环境指window,在nodejs环境指global
//使用this而不直接用window/global是为了兼容浏览器端和服务端
//将this传进函数体,使全局变量变为局部变量,可缩短函数访问全局变量的时间
})(this);
shaoyu.css
/* .shaoyu-table-thead>tr>th {
padding: 5px 0;
border-top: none;
border-left: none;
border-width: 1px;
border-style: solid;
border-color: #eee;
}
.shaoyu-table-cell {
height: 28px;
line-height: 28px;
padding: 0 15px;
position: relative;
box-sizing: border-box;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.shaoyu-table-tbody>tr>td {
border-width: 1px;
border-style: solid;
border-color: #eee;
}
.shaoyu-table-thead>tr>th,
.shaoyu-table-tbody>tr>td {
position: relative;
padding: 9px 15px;
min-height: 20px;
line-height: 20px;
font-size: 14px;
}
.shaoyu-table{
border-collapse: collapse;
border-spacing: 0;
width: 100%;
background-color: #fff;
color: #666;
} */
index.html
Document
你可能感兴趣的:(javascript,前端,开发语言)