<html> <kopf> <style type = "text/css"> .grid {border: 1px solid #808080; Grenzabteilung: 0; Breite: 500px; Grenzkollapse: Zusammenbruch} .Grid th, .grid td {Border: 0; Text-Align: Mitte;} .grid tr {Höhe: 25px; Linienhöhe: 25px;} .grid tr.odd {Hintergrund:#d0d0d0} .grid .BTN {width: 80px; text-align: center} </style> <skript type ! Array.prototype.slice.call (obj, 0); "Undefined") {result.push (Ziel); Offset: Funktion Offset (ele) {var result = {top: 0, links: 0}; (ele.style.top || "0"). Ersetzen (/[^/d]+$/, "")); result.left = number (ele.offsetleft || (ele.style.left || "0"). Ersetzen Sie (/[^/d]+$/, ""); if (ele.parentnode) {var r = offset (ele.parentnode); result.top += r.top; result.left += r.left; } Rückgabeergebnis; }}; // 事件处理 var event = {on: function (eventType, fn) {var element = this; if (this.adDeVentListener) {this.adDeVentListener (eventType, fn, false); } else if (this.attachEvent) {// 将事件缓冲到该标签上, 已解决 Dieses 指向 -Fenster (现 fn 内 this 指向 Element) 和移除匿名事件问题 var _EventRef = '_'+eventType+'eventRef'; if (! Element [_EventRef]) {Element [_EventRef] = []; } var _eventrefs = element [_EventRef]; var Index; für (index in _eventrefs) {if (_EventRefs [index] ['realfn'] == fn) {return; }} var nestfn = function () {fn.apply (Element, Argumente); }; Element [_EventRef] .push ({'realfn': fn, 'nestfn': nestfn}); Element.attacheEvent ('on'+EventType, nestfn); }}, entfernen: function (eventType, fn) {var element = this; if (this.removeEventListener) {this.removeEventListener (eventType, fn, false); } else if (this.detACHEvent) {var _eventref = '_'+eventType+'eventRef'; if (! Element [_EventRef]) {Element [_EventRef] = []; } var _eventrefs = element [_eventref] var index; var nestfn; für (index in _eventrefs) {if (_eventrefs [index] ['realfn'] == fn) {nestfn = _eventrefs [index] ['nestfn']; if (index == _ eventRefs.length-1) {element [_eventref] = _ eventRefs.slice (0, index); } else {element [_eventref] = _ eventRefs.slice (0, index) .concat (_EventRefs.Slice (Index+1, _eventrefs.Length-1)); } brechen; }} if (nestfn) {element.detACHEvent ('on'+eventType, nestfn); }}}}; // extend (function () {// 删除数组中指定下标出的元素 array.prototype.remove = function (index) {var o = this [index]; if (typeof o! == "undefined") {if (index == 0) {this.Shift ();} else if (index == this.length - 1) {this.pop (); arr2 = slice (Index+1); i = 0; i <this.Length; i ++) {if (typeof 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; für (var k in diesem .__ -Daten) {if (k && typeof this .__ data [k]! }}}, toArray: function () {var arr = []; this.each (function () {arr.push (this);}); arr zurückgeben; }}; }) (); // var grid = this.grid = function (Tabelle, Optionen) {grid.prototype._init.call (this, Tabelle, Optionen); } grid.prototype = {_init: function (Tabelle, Optionen) {if (TypeOF table === "undefined" ||! Tabelle) {Throw "Tabelle ist undefiniert oder null"; } if (table.nodetype! } table.guid = ++ grid.guid; this .__ 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 (); // 数据行 this .__ cache ["ComanitalCache"/New Collection (). this .__ SaveContainer = createSavebutton (); // 保存按钮 this .__ cache ["commandHandles"] = {// command Handels removerow: function () {var rowIndex = this.getAttribute ("Index"); self.removerow.apply (self, [rowIndex]); }, newline: function () {self.newline (); }}; this .__ regCommand = Funktion (commandname, row) {// 注册 Befehl if (zeile) {var arg = row.getAttribute ("index"); this.setAttribute ("Index", arg || false); } this.commandname = commandname; Event.remove.call (this, "click", exec); Event.on.call (this, "click", exec); } this .__ removerowCallback = function () {// 改变行的背景样式 var rows = this .__ cache ["datarows"]; var customCache = this .__ cache ["CustomCache"]; var arr = Zeilen.toArray (), dataarr = []; var RowIndex, Zeile, Daten; Reihen.Clear (); arr.each (Funktion (i) {rowIndex = this.getAtTribute ("index"); data = customCache.get (rowIndex); dataarr.push (data); this.setAttribute ("index", i.toString ()); Reihen.Add (this); if (i % 2 == 1) {// 基数行 基数行 基数行 基数行 基数行 基数行 基数行 基数行 基数行 基数行 基数行. if (! // Sodd/S | /sodd$/g.test (this.className)) {this.classname = (this.className || "") + "ungerade"; this.className.replace (// SODD/S |/SODD $/G, ""); CustomCache.clear (); Dataarr.each (function () {customCache.add (this);}); } // 事件处理 Optionen = Optionen || {}; this.ondatabinding = options.ondatabinding || this.ondatabinding; this.onrowbinding = options.onrowbinding || this.onrowbinding; this.onrowbinded = options.onrowBinded || this.onrowbed; function loelader () {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; } function loadTemplate () {tr = util.Next (Header); // 获取模板行 return tr; } Funktion loadDataFormat () {var nodes = templaterow.childnodes, ele, data, result = {}, attr; Knoten = util.ParSearray (Knoten); nodes.each (function (i) {ele = this; if (ele && ele.nodetype == 1) {attr = ele.data || ele.getAttribute ("data"); if (attr) {data = util.parsejson (attr); ele.field = data.field; Rückgabeergebnis; } function createSavebutton () {var div = document.createelement ("div"); Div.Style.position = "Absolute"; div.style.display = "keine"; Div.Style.Width = "Auto"; var btn = document.createelement ("button"); btn.innerhtml = btn.inNertext = btn.textContent = btn.value = "save"; try {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"; try {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;}}); Return Div; } function exec () {if (self .__ editrow) {// 如果当前处于编辑模式 , 则禁用所有 Befehl return; } var commandname = this.commandName; var handler = self .__ cache ["commandHandles"] [commandname]; if (Handler) {Handler.call (this); }} // 去除模板行 templaterow.parentnode.removechild (templaterow); // 处理表格中的 Befehl 事件 var Elements = Header.GetElementsByTagName ("*"); Elemente = util.ParSearray (Elemente); Elements.each (function () {if (this.nodetype ==== 1) {var commandname = this.command || this.getAtTribute ("Befehl"); if (commandname) {self .__ regcomand.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 以外的数据行 klare: function () {var rows = this .__ cache ["datarows"], zeile; rows.each (function () {row = this; if (row) {row.parentnode.removechild (row);}}); rows.clear (); // 清理 Zeilen}, // 删除指定的行 removerow: function (rowIndex) {var rows = this .__ cache ["datarows"]; var row = rows.get (rowIndex); if (zeile) {var data = this .__ cache ["customCache"] [rowIndex]; row.parentnode.removechild (row); Reihen.Remove (RowIndex); // 通知用户数据行被移除 if (util.isfunction (this.onrowremoveved)) {this.onrowremoved (Daten, Zeile); }} this .__ removerowCallback (); }, // 添加 行 append: function (data) {if (! Data) {return; } var template = this .__ Cache ["Vorlage"]; var rows = this .__ cache ["datarows"]; var rowIndex = Zeilen.Length; var tr = template.clonenode (); var customCache = this .__ cache ["CustomCache"]; CustomCache.add (Daten); // 将数据行添加到 table this .__ root.appendchild (tr); var self = this; var td, // 数据单元格 dataFormat, // 数据格式化器 value; // 单元格中的给定的数据 tr.setattribute ("index", rowIndex.toString ()); // 更改样式 if (rowIndex % 2 == 1) {tr.className = (tr.className || "") + "ungerade"; } // 通知 行数据绑定开始 if (util.isisfunction (this.onrowbinding)) {this.onrowbinding (rowIndex, tr); } var templatetd = template.FirstChild; while (templatetd) {td = templatetd.clonenode (true); Tr.Appendchild (TD); if (td.nodetype == 1 && templatetd.field) {dataFormat = this .__ cache ["dataFormat"] [templatetd.field]; td.removeAttribute ("Daten"); 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" || Wert == NULL? "" : Wert; brechen; Fall "InnerText": Standard: TD.Innertext = Td.TextContent = TypeOf Value == "undefined" || Wert == NULL? "" : Wert; brechen; }}} templatetd = templatetd.NextSsibling; } rows.add (tr); // 处理 Befehl var Elements = tr.GetElementsByTagName ("*"), Ele, attr; Elemente = util.ParSearray (Elemente); Elements.each (function () {ele = this; if (ele.nodetype == 1 && (ele.command || ele.getAttribute ("Befehl")) {attr = ele.command || ele.getAtTribute ("Befehl"); self .__ Regcommand.call (ele, ttr); // 通知 行数据绑定完成 if (util.isisfunction (this.onrowBinded)) {this.onrowBinded (rowIndex, tr); }}, // 手动产生新的输入行 newline: function () {if (this .__ editrow) {// 如果当前有存在编辑行 , 则直接返回 , 每次最多限制编辑一行数据 每次最多限制编辑一行数据 return; } var template = this .__ Cache ["Vorlage"]; var row = this .__ editrow = template.clonenode (false); var templatetd = template.Firstchild; var textArealist = []; while (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"); } else {textArea = document.CreateElement ("input"); textArea.type = "text"; } textArea.style.display = "Keine"; td.Appendchild (textarea); textArealist.push (textarea); }} templatetd = templatetd.Nextsibling; } // 将数据行添加到 Tabelle this .__ root.AppendChild (Zeile); var hohe = row.offseteight, width = row.Offsetwidth, offset = util.offset (row); textArealist.each (function () {this.style.height = (0,8 * Höhe) + "px"; this.style.width = (0.8 * this.parentnode.Offsetwidth) + "px"; this.style.display = "";}); var links = offset.left + width + 5; var top = offset.top; this.__SaveContainer.style.top = top + "px"; this .__ SaveContainer.style.left = links + "px"; this .__ SaveContainer.Style.Height = this .__ SaveContainer.Style.lineHeight = Höhe + "PX"; this .__ SaveContainer.Style.Display = "Block"; }, // 保存手动产生的数据行数据 speichern: function () {if (! This .__ editrow) {return; } var row = this .__ editrow; var td = row.Firstchild; var data = {}; while (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]; } else {textArea = td.getElementsByTagName ("input") [0]; } value = textArea.Value; Switch (DataFormat.Datatype) {Fall "Nummer": value = util.trim (value); value = number (value.length == 0? 0: value); brechen; Standard: Break; } Daten [td.field] = Wert; } td = td.nextsibling; } this .__ editrow.parentnode.removechild (this .__ editrow); this .__ editrow = null; this .__ SaveContainer.Style.Display = "None"; // 通知用户正在保存数据 if (util.isfunction (this.onave)) {this.onave (data); } this.append (Daten); }, getRowdata: function (rowIndex) {return this .__ cache ["CustomCache"]. get (rowIndex); }, // 数据绑定到指定 Cell 时的事件 OnDatabinding: Funktion (Feld, Wert, Zelle, Daten) {Rückgabewert; }. grid.guid = 0; }) (); </script> </head> <body> <table id = "table_demo"> <tr> <Th> id </th> <Th> Name </th> <Th> DescPription </th> <Th> <taste type = "button" command = "Newline"> Neue Zeile </thbast </th> </tr> <tr> <Td. Data = '{"Feld": "ID", "DataType": "Nummer", "Render": "InnerText"}'> 1 </td> <td data = '{"field": "name", "dataType": "String", "Render": "Innertext"}'> WorkingService </td> <td. Data = '{"Feld": "Beschreibung", "DataType": "String", "Render": "InnerHtml"}'> WorkingService </td> <td> <button type = "button" button "capture =" removerow "> delete </td> </tr> </table> <script type =" text = "texte =" text/javaScript "> </tr> </table> <script type =" texte "/javaScript"> </tr> </table> <script type = "texte"/javascript " document.getElementById ("table_demo"); var g = new Grid (Tabelle, {OnDatabinding: Funktion (Feld, Wert) {Rückgabewert;}, onrowBinded: function (rowIndex, row) {}}); g.bind ([{id: 0, name: "kilin"}, {id: 1, name: "kilin1"}, {id: 2, name: "kilin2"}, {id: 3, name: "kilin3"}]); </script> </body> </html>