当写完本系列后,我会把源代码分享出来给大家。本课程也会持续更新与矫正。欢迎留言指正!
经过前面几节内容的准备工作之后,终于到了要渲染表格的环节。渲染表格的模块,继承自渲染器。
结构设计
现在到了开始渲染表格的示例代码:
/**
* 表格渲染类
*/
class table_render extends renderDOM{
/**
* 初始化表格
*/
constructor() {
super();
}
}
在开始写代码的时候,先了解一下:表格如何工作的:
模块细节
全局计数器
安排了 creatGlobalId 作为一个简单的全局ID计数器。目前把它设计成为自增。
creatGlobalId(){
return "_"+this.GlobalId++;
}
渲染表格
左上角的标签
Tags.push({
"Tag" : "div", "ID" : this.creatGlobalId(), "ClassName" : "cells__spacer",
"Action":{
"click":function(){
// console.log("选择全部");
var cells__inputs = document.getElementsByClassName("cells__input");
var length = cells__inputs.length;
for(var i = 0;i<length;i++){
cells__inputs[i].style.backgroundColor = "#f3f2f1";
that.focus["cells"].push(cells__inputs[i].getAttribute("id"));
}
that.focus.x = 0;
that.focus.y = 0;
return false;
},
"change":function(){}
}
});
渲染列坐标
// 打印列号
while(col != x){
Tags.push({
"Tag" : "div", "ID" : col, "ClassName" : "cells__alphabet", "Text" : col,
"Data" : [
{ "k":"x", "v":col },
{ "k":"y", "v":"0" }
],
"Action":{
"click":that.colclick.bind(that),
"dblclick":function(){},
"change":function(){},
"mousemove":function(){
//更改鼠标样式
if (event.offsetX > this.offsetWidth - 10)
this.style.cursor = 'col-resize';
else
this.style.cursor = 'default';
},
"mouseover":function(){},
"mouseout":function(){},
"mousedown":function(){},
"mouseup":function(){},
"contextmenu":that.colcontextmenu.bind(that)
}
});
that.focus["ColumnsSize"].push("200px")
col = that.charcode.excel_Row_Increase(col,1);
}
渲染行坐标
// 打印行号
for(i = 1; !(i > y); i++ ){
Tags.push({
"Tag" : "div", "ID" : ""+i, "ClassName" : "cells__number", "Text" : ""+i,
"Data" : [
{ "k":"x", "v":"0" },
{ "k":"y", "v":i }
],
"Action":{
"click":that.rowclick.bind(that),
"change":function(){},
"mousemove":function(){
//更改鼠标样式
if (event.offsetY > this.offsetHeight - 10)
this.style.cursor = 'row-resize';
else
this.style.cursor = 'default';
},
"contextmenu":that.rowcontextmenu.bind(that)
}
});
that.focus["RowsSize"].push("25px")
}
渲染单元格
这是渲染结果
var cellsTags = [];
col = "A";
for(i = 1; !(i > y); i++ ){
while(col != x){
cellsTags.push({
"Tag" : "div", "ID" : col+i, "ClassName" : "cells__input", "Text" : "",
"Data" : [
{ "k":"merge", "v": col+i+":"+col+i },
{ "k":"t", "v":"" },
{ "k":"v", "v":"" },
{ "k":"w", "v":"" },
{ "k":"f", "v":"" },
{ "k":"x", "v":""+col },
{ "k":"y", "v":i }
],
"Action":{
"click":that.cellclick.bind(that),
"dblclick":that.celldblclick.bind(that),
"change":that.cellchange.bind(that),
"mouseover":that.cellmouseover.bind(that),
"mouseout":that.cellmouseout.bind(that),
"mousedown":that.cellmousedown.bind(that),
"mouseup":that.cellmouseup.bind(that),
"contextmenu":that.cellcontextmenu.bind(that)
}
});
col = that.charcode.excel_Row_Increase(col,1);
}
col = "A";
}
this.renderDOM('cells',cellsTags,function(target){ },function(target){ });
在这里,重点提一下浏览器的事件这个概念,浏览器的事件1有很多种。
- click:按下鼠标(通常是按下主按钮)时触发。
- dblclick:在同一个元素上双击鼠标时触发。
- mousedown:按下鼠标键时触发。
- mouseup:释放按下的鼠标键时触发。
- mousemove:当鼠标在一个节点内部移动时触发。当鼠标持续移动时,该事件会连续触发。为了避免性能问题,建议对该事件的监听函数做一些限定,比如限定一段时间内只能运行一次。
- mouseenter:鼠标进入一个节点时触发,进入子节点不会触发这个事件(详见后文)。
- mouseover:鼠标进入一个节点时触发,进入子节点会再一次触发这个事件(详见后文)。
- mouseout:鼠标离开一个节点时触发,离开父节点也会触发这个事件(详见后文)。
- mouseleave:鼠标离开一个节点时触发,离开父节点不会触发这个事件(详见后文)。
- contextmenu:按下鼠标右键时(上下文菜单出现前)触发,或者按下“上下文菜单键”时触发。
- wheel:滚动鼠标的滚轮时触发,该事件继承的是WheelEvent接口。
click事件指的是,用户在同一个位置先完成mousedown动作,再完成mouseup动作。因此,触发顺序是,mousedown首先触发,mouseup接着触发,click最后触发。
dblclick事件则会在mousedown、mouseup、click之后触发。
mouseover事件和mouseenter事件,都是鼠标进入一个节点时触发。两者的区别是,mouseenter事件只触发一次,而只要鼠标在节点内部移动,mouseover事件会在子节点上触发多次。