技术论文(超详系列):javascript表格处理案例研究

javascript表格处理案例研究

摘 要:随着网页开发的流行,一些基础的开发过程变得越来越频繁,如数据的显示功能,在数据的显示过程中,往往采用表格来批量显示数据,如学生信息表、学生成绩表、订单状态表、物流跟踪表等都采用表格来显示数据。本文试图发表关于javascript处理表格的一个案例,用javaScript语言封装表格的数据处理功能。提供源码、详细设计、编程实践。

文 章 分 类:javascript编程实践;javascript基础;

标签:javascript基础;组件化

关 键 字:表格处理;javascirpt;数据显示

日 期:2022年1月28日 星期五


1、问题描述

        在网页开发中,基础数据的管理和维护是一项重要的任务,基础数据具有数据量大、数据长度短、易于显示等特点,在基础数据的显示方面往往采用表格来显示数据,表格是一种显示关系型数据的工具,大大的加强了数据的直观性、可维护性和易读性,所以表格处理程序是一种可复用性高、可实用性强的程序,它能够对网页开发中基础数据的管理和维护模块的开发起到非常重要的作用,这些作用体现在快捷开发、可复用性高、实用性强和易读性高等方面。一般来说,表格处理程序需具备以下几个方面的功能:

(1)数据加载

数据加载指表格应该能够显示数据。

(2)数据处理

数据处理指表格处理程序必须提供处理数据的接口,如数据的增删改查,重新加载数据等功能。

(3)表格样式处理

表格样式处理是对表格的美化过程,一个好的表格样式可以增强用户的体验。

2、设计思路

        数据加载是将一定格式、一定量的数据显示在表格上的过程,这个过程可用HTML的table标签来显示表格,用tr标签来表示行数据,用td标签来显示列数据,

数据处理是对表格上的数据的进行增删改查以及重新加载的过程,这个过程需要用javacript语言来实现。

表格的样式处理则由css来完成。

3、整体设计

        数据的加载过程需要设置数据的格式和数量,这对于初级开发者来说无法考虑到用什么样的数据格式才能满足所有的业务场景,一般来说数据的格式应该包含以下基本信息。

(1)表格的行数和列数

(2)表格的表头设置

(3)表格的主体数据

(4)主体数据的基本操作

对于表格的行数和列数以及主体数据可用一个二维数组来表示,在这个二维数组中,每一项是一个一维数组,这个一维数组就表示该表格中对应的一行数据,而这个一维数组的每项就对应该表格中对应行的每列数据,这样二维数组的长度就对应表格的行数,二维数组中每项对应的一维数组的长度就对应了表格的列数。

由于我们有时需要对表格中某行数据进行相应的处理,所以表格需要增加一列操作列来表示某行数据对应的操作,这些操作由一系列的按钮构成,假设这些操作对应的按钮在一个集合{btn1,btn2,btn3,...,btnn}中,那么表格对应的操作列可用一个二维布尔数组表示,即

[[true,true,true,...,false],

...,

[true,true,true,...,false]]

该二维数组的行数和列数分别与表格的主体数据的行数和操作列对应的可操作集合的长度一致,该二维数组的数据表示该行数据包含或者不包含某项操作,即o[i][j] = true|false,表示表格中第i行包括或者不包括第j项操作,如果包含,则o[i][j] = true,如果不包含,则o[i][j]=false。

对于表格表头设置,表格的表头包括表格的列属性值和该列的宽度,如一个学生成绩表的表头应该包含一下几个属性值,即[<学生姓名>,<学生学号>,<科目>,<成绩>,<年级排名>] 等。

4、详细设计

/*表格基本配置*/

var tableconfig = {

id:...,

colN:...,

width:...,

data:...,

title:...,

head:...,

btns:...,

}

/*表格基本配置属性详解*/

属性

类型

说明

id

string

页面中表格元素的id值

colN

int

页面中表格元素的列的数量

width

string

页面中表格元素的宽度

data

二维数组

页面中表格元素的数据

title

二维数组

页面中表格元素的表头设置

head

string

页面中表格元素的head

btns

json

页面中表格元素的行的操作

/*表格基本配置属性之btns属性详解*

属性

类型

说明

title

string

操作按钮的名称

index

int

操作按钮的下标

handle

function

操作按钮的执行函数

Xbtn

json

X表示操作按钮的简称,用英文表示,Xbtn的json格式中包含了title、index和handle即以上三个属性,X可任意命名,btns中可含多个Xbtn

/*表格基本配置属性之handle属性详解*

属性

类型

说明

i

int

操作按钮对应的行数的下标

index

int

该行对相应操作按钮的下标

/*父类表格基本配置属性详解*

属性

类型

说明

pagepre

int

表格每页可显示的数据条数,默认为10

skin

string

表格对应的皮肤名

hasOrder

boolean

规定表格每行是否显示行下标

hasCheckbox

boolean

规定表格每行是否可选

load

function

表格加载时每行数据的展示层执行函数

reload

function

表格数据重新加载函数,执行时表格将被重置

selected

function

当表格每行可选时,提供的获取被选择行的函数

next

function

获取下一页的表格数据

prev

function

获取上一页的表格数据

to

function

跳转到任何一页的表格数据

注:父类表格基本配置属性由表格处理程序提供,开发者可覆盖

/*父类表格基本配置属性之load函数详解*

属性

类型

说明

i

int

展示层执行函数加载时的行的下标值

data

一维数组

展示层加载函数执行时的行对应的数据

/*父类表格基本配置属性之reload函数详解*

属性

类型

说明

i

int

展示层执行函数加载时的行的下标值

data

一维数组

展示层加载函数执行时的行对应的数据

configdata

二维数组

重新加载数据时新数据

注:reload函数的参数为可选参,当为一个参数时表示重新加载整个表格,当为两个参数时表示重新加载i对应行的数据。

5、源程序设计

        fe.js

(function(FE) {
	FE.config = {
		tableSettings : {
			pagePre : 10,
			skin : "sky_table",
			hasOrder : true,
			hasCheckBox : true,
			theme : {
				th : {
					font : [ 18, "黑体", "#FFFFFF" ],
					style : [ "center" ]
				},
				td : {
					font : [ 16, "新宋体", "black" ],
					style : [ "left" ]
				},
				tr : {
					height : 24,
				}
			},
			reload : function(data) {
				var id = this.getAttribute("id");
				window[id + "_tableSettings"].data = data;
				this.innerHTML = "";
				FE.createTable(window[id + "_tableSettings"]);
			}
		}
	};

	FE.extend = function(obj, fnName, fn) {
		obj[fnName] = fn;
	}

	FE.createTable = function(tableSettings) {
		var settings = FE.config.tableSettings || tableSettings;

		var _table = null;

		for ( var setting in tableSettings) {
			settings[setting] = tableSettings[setting];
		}

		console.info(settings);
		var _tableHead = document.createElement("thead");
		var _tableBody = document.createElement("tbody");

		if (settings.id) {
			var _table = FE("#" + settings.id);
			_table.appendChild(_tableHead);
			_table.appendChild(_tableBody);
			_table.setAttribute("border", "0");
			if (settings.skin) {
				_table.addClass(settings.skin);
			}

			window[settings.id + "_tableSettings"] = settings;
			FE.extend(_table, "reload", FE.config.tableSettings.reload);

		}

		if (settings.colN) {
			var _tr = document.createElement("tr");
			_tr.style.height = settings.theme.tr.height;
			if (settings.hasOrder) {
				var _th = document.createElement("th");
				if (settings.hasCheckBox) {
					_th.innerHTML = "全选";
				}
				_tr.appendChild(_th);
			}
			if (settings.hasCheckBox) {
				var _th = document.createElement("th");
				var _input = document.createElement("input");
				_input.setAttribute("id", "all");
				_input.setAttribute("type", "checkbox");
				_th.appendChild(_input);
				_tr.appendChild(_th);
			}
			for ( var i = 0; i < settings.colN; i++) {
				var _th = document.createElement("th");
				_th.style.fontSize = settings.theme.th.font[0];
				_th.style.fontFamily = settings.theme.th.font[1];
				_th.style.fontWeight = "bold";
				_th.style.color = settings.theme.th.font[2];
				_th.innerHTML = settings.title[i];
				_th.style.width = settings.width[i];
				_tr.appendChild(_th);
			}

			if (settings.btns) {
				var _th = document.createElement("th");
				_th.style.fontSize = settings.theme.th.font[0];
				_th.style.fontFamily = settings.theme.th.font[1];
				_th.style.fontWeight = "bold";
				_th.style.color = settings.theme.th.font[2];
				_th.innerHTML = "操作";
				_tr.appendChild(_th);
			}
			_tableHead.appendChild(_tr);
		}

		if (settings.data) {
			for ( var i = 0; i < settings.data.length; i++) {
				var _tr = document.createElement("tr");
				_tr.style.height = settings.theme.tr.height;

				if (i % 2 != 0 && settings.skin) {
					_tr.className = settings.skin + "_tr";
				}

				if (settings.hasOrder) {
					var _td = document.createElement("td");
					_td.style.textAlign = "center";
					_td.innerHTML = i + 1;
					_tr.appendChild(_td);
				}
				if (settings.hasCheckBox) {
					var _td = document.createElement("td");
					var _input = document.createElement("input");
					_input.setAttribute("id", "checkbox" + i);
					_input.setAttribute("type", "checkbox");
					_td.appendChild(_input);
					_tr.appendChild(_td);
				}
				var len = settings.btns ? settings.data[i].length - 1
						: settings.data[i].length;
				for ( var j = 0; j < len; j++) {
					var _td = document.createElement("td");
					_td.style.fontSize = settings.theme.td.font[0];
					_td.style.fontFamily = settings.theme.td.font[1];
					_td.style.color = settings.theme.td.font[2];
					_td.innerHTML = settings.data[i][j];
					_tr.appendChild(_td);
				}

				if (settings.btns) {
					var _td = document.createElement("td");

					for ( var btn in settings.btns) {
						var _btn = document.createElement("input");
						_btn.setAttribute("type", "button");
						var index = settings.btns[btn].index;
						if (settings.btns[btn].title) {
							_btn
									.setAttribute("value",
											settings.btns[btn].title);
						}

						if (settings.btns[btn].handle) {
							FE.extend(_table, btn + "_handle",
									settings.btns[btn].handle);
							_btn.setAttribute("row", i);
							_btn.setAttribute("index", index);
							_btn.setAttribute("btn", btn);
						}

						if (settings.btns
								&& settings.data[i][settings.data[i].length - 1][index]) {
							_td.appendChild(_btn);
						}

					}
					_tr.appendChild(_td);
				}

				_tr.onmouseover = function() {
					var _className = this.className;
					this.className = settings.skin + "_tr_mouseover";
					this.setAttribute("old", _className);
				}

				_tr.onmouseout = function() {
					this.className = this.getAttribute("old");
				}
				_tableBody.appendChild(_tr);
			}
		}

		_table.onclick = function(event, row, index) {
			if (event.target.localName == "input") {
				var row = event.target.getAttribute("row");
				var index = event.target.getAttribute("index");
				var btn = event.target.getAttribute("btn");
				this[btn + "_handle"](row, index);
			}
		}
		return _table;

	};

	
	window.FE = FE;
})(node);

function node(selector) {
	var result = getElement(selector);
	if (!result.length) {
		FE.extend(result, "addClass", addClass);
		FE.extend(result, "removeClass", removeClass);
		FE.extend(result, "valueOfStyle", valueOfStyle);
	} else {
		for ( var i = 0; i < result.length; i++) {
			FE.extend(result[i], "addClass", addClass);
			FE.extend(result[i], "removeClass", removeClass);
			FE.extend(result[i], "valueOfStyle", valueOfStyle);
		}
	}
	return result;
}
function getElement(selector) {
	if ((typeof selector) == "string") {
		var result = null;
		var selectors = selector.split(" ");
		for ( var i = 0; i < selectors.length; i++) {
			if (selectors[i].indexOf("#") == 0) {
				result = document.getElementById(selectors[i].substring(1));
			}

			if (selectors[i].indexOf("<") == 0 && selectors[i].indexOf(">") > 0) {
				if (selectors[i].indexOf(".") > 0) {
					var _selector = selectors[i].split(".");
					var tagName = _selector[0].substring(1,
							_selector[0].length - 1);
					result = result ? result.getElementsByTagName(tagName)
							: document.getElementsByTagName(tagName);
					if (result) {
						var doms = [];
						for ( var i = 0; i < result.length; i++) {
							var className = result[i].className;
							if (className.indexOf(_selector[1]) >= 0) {
								doms.push(result[i]);
							}
						}
						return doms;
					}
				} else {
					var tagName = selectors[i].substring(1,
							selectors[i].length - 1);

					if (result && (typeof result) == "object") {
						result = result.getElementsByTagName(tagName);
					} else {
						result = document.getElementsByTagName(tagName);
					}
				}
			}
		}
		return result;
	}
}
function addClass(className) {
	var _className = this.className;
	this.className = _className + " " + className;
}

function removeClass(className) {
	var _className = this.className;
	if (_className.indexOf(className) >= 0) {
		var classes = _className.split(" ");
		var classNameStr = "";
		for ( var i = 0; i < classes.length; i++) {
			if (classes[i] == className) {
				continue;
			} else {
				classNameStr += classes[i] + " ";
			}
		}
		this.className = classNameStr;
	}
}

function valueOfStyle() {
	if (elements.length == 1) {
		return this.style[elements[0]];
	} else {
		this.style[elements[0]] = elements[1];
	}
}

        index.html

<!DOCTYPE HTML>
<html>
  <head>
    <title>表格处理</title>
	<script type="text/javascript" src="js/base/1.0.3/fe.js"></script>
	<link rel="stylesheet" type="text/css" href="css/base/1.0.1/fe.css">
	<script type="text/javascript">
		window.onload = function() {
			var tableSettings = {
				id:"mytable",
				colN:2,
				data:[["createElement(tagName)","创建一个标签名为tagName的新元素节点",[true]],
				["A.appendChild(B)","把B节点添加至A节点的末尾",[true]],
				["insertBefore(A,B)","把A节点插入到B节点之前",[true]],
				["cloneNode(deep)","复制某个指定的的节点",[true]]],
				title:["名称","描述"],
				width:["300","600"],
				btns:{
					delbtn: {
						title:"删除",
						index:0,
						handle:function(row,index) {
							console.info(row);
							this.reload([["createElement","创建一个标签名为tagName的新元素节点",[true]],
						    				["A.appendChild(B)","把B节点添加至A节点的末尾",[true]],
						    				["insertBefore(A,B)","把A节点插入到B节点之前",[true]],
						    				["cloneNode(deep)","复制某个指定的的节点",[true]]]);
							}
						}
					}
			};
			var _table = FE.createTable(tableSettings);

		}

		
	</script>
  </head>
  
  <body>
  <div id="mytable"></div>
  </body>
</html>

        fe.css

.sky_table {
	border: 1px solid blue;
	border-radius: 10px;
}

.sky_table thead tr {
	background-color: #FF9900
}

.sky_table_tr {
	background-color: #0099CC
}

.sky_table_tr_mouseover {
	background-color: #99CCFF
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值