<html> <head> <style type = "text/css"> .grid {border: 1px solid #808080 ؛ تباعد الحدود: 0 ؛ العرض: 500 بكسل ؛ حدود الحدود: الانهيار} .grid th ، .grid td {الحدود: 0 ؛ text-align: center ؛} .grid tr {height: 25px ؛ line-height: 25px ؛} .grid tr.odd {background:#d0d0d0} .grid .btn {width: 80px ؛ text-align: center} </style> <script type = "text/javaScript"> (function () {// var util = {next: function next (eLe) {if (ele) {var n = ele.nextsibling ؛ if (n && n.nodeType ==== 1) {return n ؛} if (typeof JSON! == " Array.Protype.slice.call (OBJ ، 0) ؛ "غير محدد") {result.push) الإزاحة: وظيفة الإزاحة (eLe) {var result = {top: 0 ، left: 0} ؛ (ele.style.top || "0"). استبدال (/[^/d]+$/، "")) ؛ result.left = number (ele.offsetleft || (ele.style.left || "0"). استبدال (/[^/d]+$/، "")) ؛ if (eLe.ParentNode) {var r = Offset (eLe.ParentNode) ؛ result.top += r.top ؛ result.left += R.Left ؛ } نتيجة الإرجاع ؛ }} ؛ // 事件处理 var event = {on: function (eventType ، fn) {var element = this ؛ if (this.addeventListener) {this.adDeventListener (eventType ، fn ، false) ؛ } آخر إذا (this.attachevent) {// 将事件缓冲到该标签上 ، 已解决 هذه النافذة (现 fn 内 هذا العنصر 指向) 和移除匿名事件问题 var _eventref = '_'+eventType+'eventRef' ؛ if (! element [_eventref]) {element [_eventref] = [] ؛ } var _eventrefs = element [_eventref] ؛ مؤشر فار ؛ لـ (index in _eventrefs) {if (_eventrefs [index] ['Realfn'] == fn) {return ؛ }} var nestfn = function () {fn.apply (element ، mations) ؛ } ؛ element [_eventref] .push ({'Realfn': fn ، 'nestfn': nestfn}) ؛ element.attachevent ('on'+eventType ، nestfn) ؛ }} ، إزالة: function (eventType ، fn) {var element = this ؛ if (this.removeEventListener) {this.removeeventListener (EventType ، fn ، false) ؛ } آخر إذا (this.detachevent) {var _eventref = '_'+eventType+'eventRef' ؛ if (! element [_eventref]) {element [_eventref] = [] ؛ } var _eventRefs = element [_eventref] var index ؛ var nestfn ؛ لـ (index in _eventrefs) {if (_eventrefs [index] ['Realfn'] == fn) {nestfn = _eventrefs [index] ['nestfn'] ؛ if (index == _ eventrefs.length-1) {element [_eventref] = _ eventRefs.slice (0 ، index) ؛ } آخر {element [_eventref] = _ eventrefs.slice (0 ، index) .Concat (_eventrefs.slice (index+1 ، _eventrefs.length-1)) ؛ } استراحة؛ }} if (nestfn) {element.detachevent ('on'+eventType ، nestfn) ؛ }}}} ؛ // تمديد (function () {// 删除数组中指定下标出的元素 array.prototype.remove = function (index) {var o = this [index] ؛ if (typeof o! == "undefined") {if (index == 0) {this.shift () ؛ ARR2 = this.splice (1) ؛ i = 0 ؛ i <this.length ؛ i ++) {if (that im [i]! == "undefined") {fn.call (this [i] this.__data[this.length++] = obj; }, get:function(index){ return this.__data[index]; }, remove:function(index){ var obj = this.__data[index]; if(typeof obj !== "undefined"){ this.length--; } delete this.__data[index]; }, clear:function(){ this.__data = {}; this.length = 0 ؛ لـ (var k في هذا .__ data) {if (k && typeof this .__ data [k]! == "undefined") {fn.call (this .__ data [k] ، index ++) ؛ }}} ، toarray: function () {var arr = [] ؛ this.each (function () {arr.push (this) ؛}) ؛ إرجاع arr ؛ }} ؛ }) () ؛ // var grid = this.grid = function (table ، reports) {grid.prototype._init.call (هذا ، الجدول ، الخيارات) ؛ } grid.prototype = {_init: function (الجدول ، الخيارات) {if (typeof table === "undefined" ||! table) {throw "table غير محدد أو فارغ" ؛ } if (table.nodeType! == 1 ||!/^table $/i.test (table.tagname)) {throw "يجب أن يكون" الجدول "عنصر." ؛ } table.guid = ++ grid.guid ؛ هذا .__ cache = {} ؛ var self = this ؛ var header = this .__ cache ["header"] = loadheader () ؛ // header this .__ root = header.parentNode ؛ var templaterow = this .__ cache ["template"] = loadtemplate () ؛ // 模板行 this .__ cache ["dataformat"] = loadDataFormat () ؛ // 数据模板 this .__ cache ["" datarows "] = new collection () ؛ هذا .__ savecontainer = createSaveButton () ؛ // 保存按钮 هذا .__ cache ["commandhandles"] = {// command handels removerow: function () {var rowindex = this.getAttribute ("index") ؛ self.removerow.apply (self ، [rowindex]) ؛ } ، newline: function () {self.newline () ؛ }} ؛ هذا .__ regCommand = function (commandName ، row) {// 注册 command if (row) {var arg = row.getAttribute ("index") ؛ this.setAttribute ("index" ، arg || false) ؛ } this.commandName = commandName ؛ event.remove.call (هذا ، "انقر" ، exec) ؛ event.on.call (هذا ، "انقر" ، exec) ؛ } هذا .__ removerowCallback = function () {// 改变行的背景样式 var rows = this .__ cache ["datarows"] ؛ var customCache = this .__ cache ["CustomCache"] ؛ var arr = rows.toarray () ، dataArr = [] ؛ var rowindex ، row ، البيانات ؛ الصفوف. clear () ؛ arr.each (function (i) {rowindex = this.getAttribute ("index") ؛ data = customCache.get (rowindex) ؛ dataarr.push (data) ؛ this.setAttribute ("index" ، i.toString ()) ؛ if (! // sodd/s | /sodd$/g.test (this.className)) {this.className = (this.classname || ") +" Odd "؛ this.classname.replace (// sodd/s |/sodd $/g ، "") ؛ CustomCache.clear () ؛ DataArr.each (function () {customCache.add (this) ؛}) ؛ } // 事件处理 الخيارات = الخيارات || {} ؛ this.ondatabinding = Options.ondatabinding || هذا. this.onRowBinding = Options.OnRowBinding || هذا. this.onrowbered = Options.OnRowbered || هذا. وظيفة loadHeader () {var tr = table.firstchild ؛ if (tr && tr.nodeType! = 1) {tr = util.next (tr) ؛ } if (!/tr/i.test (tr.tagname)) {// 如果第一个元素不是 tr , 则浏览器支持 tbody tr = tr.firstchild ؛ if (tr.nodeType! = 1) {tr = util.next (tr) ؛ }} return tr ؛ } وظيفة loadtemplate () {tr = util.next (header) ؛ // 获取模板行 return tr ؛ } function loadDataFormat () {var nodes = templaterow.childnodes ، eLe ، data ، result = {} ، attr ؛ العقد = util.parsearray (العقد) ؛ nodes.each (function (i) {eLe = this ؛ if (eLe && ele.nodeType == 1) {attr = ele.data || ele.getattribute ("data") ؛ if (data) نتيجة العودة } الدالة CreateSaveButton () {var div = document.createElement ("div") ؛ div.style.position = "absolute" ؛ div.style.display = "none" ؛ div.style.width = "Auto" ؛ var btn = document.createElement ("button") ؛ btn.innerhtml = btn.innertext = btn.textContent = btn.value = "save" ؛ حاول {btn.type = "button" ؛ } catch (e) {btn.setAttribute ("type" ، "button") ؛ } div.appendchild (BTN) ؛ var btncancel = document.createElement ("button") ؛ btncancel.innerhtml = btncancel.innertext = btncancel.textContent = btncancel.value = "cancel" ؛ حاول {btncancel.type = "button" ؛ } catch (e) {btncancel.setattribute ("type" ، "button") ؛ } div.appendchild (btncancel) ؛ document.body.appendchild (div) ؛ event.on.call (btn ، "click" ، function () {self.save () ؛}) ؛ event.on.call (btncancel ، "Click" ، function () {div.style.display = "none" ؛ if (self .__ editrow) {self .__ editrow.parentnode.removechild (self .__ editrow) ؛ self .__ editrow = null ؛}}) ؛ إرجاع Div. } وظيفة exec () {if (self .__ editrow) {// 如果当前处于编辑模式 , 则禁用所有 return ؛ } var commandName = this.CommandName ؛ var handler = self .__ cache ["commandhandles"] [commandName] ؛ if (handler) {handler.call (this) ؛ }} // 去除模板行 templaterow.parentnode.removechild (templaterow) ؛ // 处理表格中的 command 事件 var elements = header.getElementSbyTagName ("*") ؛ العناصر = util.parsearray (عناصر) ؛ elements.each (function () {if (this.nodeType ==== 1) {var commandName = this.command || this.getAttribute ("command") ؛ if (commandName) {self .__ regCommand.Call (this ، commandname ، header) ؛}}}) ؛ } ، // bangding bind: function (data) {this.clear () ؛ if (data && data.length> 0) {var self = this ؛ data.each (function () {self.append (this) ؛}) ؛ }} ، // 清理表 , 删除所以除 header 以外的数据行 clear: function () {var rows = this .__ cache ["datarows"] ، row ؛ صفوف. rows.clear () ؛ // 清理 rows} ، // 删除指定的行 removerow: function (rowindex) {var rows = this .__ cache ["datarows"] ؛ var row = rows.get (rowindex) ؛ if (row) {var data = this .__ cache ["customCache"] [ROWINDEX] ؛ row.parentnode.removechild (row) ؛ الصفوف. // 通知用户数据行被移除 if (util.ispunction (this.onRowRemoved)) {this.onRowRemoved (data ، row) ؛ }} هذا .__ readOwCallback () ؛ } ، // 添加 行 append: function (data) {if (! data) {return ؛ } var template = this .__ cache ["template"] ؛ صفوف var = this .__ cache ["datarows"] ؛ var rowindex = rows.length ؛ var tr = template.clonenode () ؛ var customCache = this .__ cache ["CustomCache"] ؛ CustomCache.Add (البيانات) ؛ // 将数据行添加到 الجدول هذا .__ root.appendchild (tr) ؛ var self = this ؛ var td ، // 数据单元格 dataFormat ، // 数据格式化器 value ؛ // 单元格中的给定的数据 tr.setAttribute ("index" ، rowindex.toString ()) ؛ // 更改样式 if (rowindex ٪ 2 == 1) {tr.ClassName = (tr.className || "") + "Odd" ؛ } // 通知 行数据绑定开始 if (util.ispunction (this.onrowbinding)) {this.onRowBinding (rowindex ، tr) ؛ } var templatetd = template.firstchild ؛ بينما (templatetd) {td = templatetd.clonenode (true) ؛ Tr.AppendChild (TD) ؛ if (td.nodeType == 1 && templatetd.field) {dataFormat = this .__ cache ["dataFormat"] [templatetd.field] ؛ TD.RemoVeatTribute ("البيانات") ؛ td.field = templatetd.field ؛ value = data [dataFormat.field] ؛ // 通知单元格数据绑定事件 value = this.ondatabinding (dataFormat.field ، value ، td ، data) ؛ if (value! == false) {// 如果返回 false , 则不用做赋值操作 switch (dataFormat.render) {case "innerhtml": td.innerhtml = typeof value == "undefined" || القيمة == فارغة؟ "" : قيمة؛ استراحة؛ الحالة "innertext": افتراضي: td.innertext = td.textContent = typeof value == "undefined" || القيمة == فارغة؟ "" : قيمة؛ استراحة؛ }}} templatetd = templatetd.nextsibling ؛ } ows.add (tr) ؛ // 处理 command var elements = tr.getElementsByTagName ("*") ، ele ، attr ؛ العناصر = util.parsearray (عناصر) ؛ elements.each (function () {eLe = this ؛ if (ele.nodeType == 1 && (eLe.Command || ele.getAttribute ("command"))) {attr = eLe.Command || ele.getattribute ("command") ؛ self .__ regcommand.call (eLe ، etr ، tr) ؛}}) ؛ // 通知 行数据绑定完成 if (util.ispunction (this.onrowbered)) {this.onrowbered (rowindex ، tr) ؛ }} ، // 手动产生新的输入行 newline: function () {if (this .__ editrow) {// 如果当前有存在编辑行 , 则直接返回 每次最多限制编辑一行数据 每次最多限制编辑一行数据 return ؛ } var template = this .__ cache ["template"] ؛ var row = this .__ editrow = template.clonenode (false) ؛ var templatetd = template.firstchild ؛ var textarealist = [] ؛ بينما (templatetd) {td = templatetd.clonenode (true) ؛ row.appendchild (TD) ؛ if (td.nodeType == 1) {if (templatetd.field) {td.field = templatetd.field ؛ td.innerhtml = "" ؛ var dataFormat = this .__ cache ["dataFormat"] [templatetd.field] ؛ var textarea = null ؛ if (dataFormat.render == "innerhtml") {textArea = document.createElement ("textarea") ؛ } آخر {textArea = document.createElement ("input") ؛ textarea.type = "text" ؛ } textarea.style.display = "none" ؛ td.appendchild (textarea) ؛ TextArealist.push (textarea) ؛ }} templatetd = templatetd.nextsibling ؛ } // 将数据行添加到 جدول هذا .__ root.appendChild (row) ؛ var height = row.offsetheight ، width = row.offsetWidth ، Offset = util.offset (row) ؛ textArealist.each (function () {this.style.height = (0.8 * الارتفاع) + "px" ؛ this.style.width = (0.8 * this.parentNode.offSetWidth) + "px" ؛ this.style.display = "" ؛}) ؛ var left = offset.left + width + 5 ؛ var top = offset.top ؛ this.__saveContainer.style.top = Top + "PX" ؛ هذا .__ savecontainer.style.left = left + "px" ؛ هذا .__ savecontainer.style.height = this .__ savecontainer.style.lineheight = height + "px" ؛ هذا .__ savecontainer.style.display = "block" ؛ } ، // 保存手动产生的数据行数据 حفظ: function () {if (! this .__ editrow) {return ؛ } var row = this .__ editrow ؛ var td = row.firstchild ؛ var data = {} ؛ بينما (td) {if (td.nodeType === 1 && td.field) {var dataFormat = this .__ cache ["dataFormat"] [td.field] ؛ var textarea = null ؛ if (dataFormat.render == "innerhtml") {textArea = td.getElementSbyTagName ("textarea") [0] ؛ } آخر {textArea = td.getElementsByTagName ("input") [0] ؛ } value = textarea.value ؛ Switch (dataFormat.datatype) {case "number": value = util.trim (value) ؛ value = number (value.length == 0؟ 0: value) ؛ استراحة؛ الافتراضي: استراحة ؛ } البيانات [td.field] = value ؛ } td = td.nextsibling ؛ } هذا .__ editrow.parentnode.removechild (هذا .__ editrow) ؛ هذا .__ editrow = null ؛ هذا .__ savecontainer.style.display = "none" ؛ // 通知用户正在保存数据 if (util.isfunction (this.ongaving)) {this.ongaving (data) ؛ } this.append (data) ؛ } ، getRowData: function (rowIndex) {return this .__ cache ["customCache"]. get (rowIndex) ؛ } ، // 数据绑定到指定 cell 时的事件 onDataBinding: function (الحقل ، القيمة ، الخلية ، البيانات) {قيمة الإرجاع ؛ } ، // 当数据行绑定开始时的事件 onRowBinding: function (RowIndex ، row) {} ، // 当数据行绑定完成时的事件 //@param row {dom element tr} onRowbered: function (rowindex ، row) {} ، Grid.Guid = 0 ؛ }) () ؛ </script> </head> <body> <body> <table id = "table_demo"> <tr> <th> id </h> <th> الاسم </th> <h> descpription </th> <h> <button type = "button" command = "newline" data = '{"حقل": "id" ، "datatype": "number" ، "render": "innertext"}'> 1 </td> <td data = '{"field": "name" ، "datatype: data = '{"الحقل": "الوصف" ، "datatype": "string" ، "render": "innerhtml"}'> worksservice </td> <td> <trate type = "button" command = "readow"> delete </utton> </td> </tr> </table> document.getElementById ("table_demo") ؛ var g = new Grid (table ، {onDatabinding: function (field ، value) {return value ؛} ، onRowbered: function (rowindex ، row) {}}) ؛ g.bind ([{id: 0 ، name: "kilin"} ، {id: 1 ، name: "kilin1"} ، {id: 2 ، name: "kilin2"} ، {id: 3 ، name: "kilin3"}]) ؛ </script> </body> </html>