一个牛人写的拖拽,求高手注解……
<script type="text/javascript">var Class = {//创建类create: function () {return function () {this.initialize.apply(this, arguments);};}};var $A = function (a) {//转换数组return a ? Array.apply(null, a) : new Array;};var $ = function (id) {//获取对象return document.getElementById(id);};Object.extend = function (a, b) {//追加方法for (var i in b) a[i] = b[i];return a;};Object.extend(Object, {addEvent : function (a, b, c, d) {//添加函数if (a.attachEvent) a.attachEvent(b[0], c);else a.addEventListener(b[1] || b[0].replace(/^on/, ""), c, d || false);return c;},delEvent : function (a, b, c, d) {if (a.detachEvent) a.detachEvent(b[0], c);else a.removeEventListener(b[1] || b[0].replace(/^on/, ""), c, d || false);return c;},reEvent : function () {//获取Eventreturn window.event ? window.event : (function (o) {do {o = o.caller;} while (o && !/^\[object[ A-Za-z]*Event\]$/.test(o.arguments[0]));return o.arguments[0];})(this.reEvent);}});Function.prototype.bind = function () {//绑定事件var wc = this, a = $A(arguments), o = a.shift();return function () {wc.apply(o, a.concat($A(arguments)));};};var Table = Class.create();Table.prototype = {initialize : function () {//初始化var wc = this;wc.cols = new Array; //创建列},addCols : function (o) {//添加列var wc = this, cols = wc.cols, i = cols.length;return cols[i] = {id : i, div : o, rows : new Array, //创建行addRow : wc.addRow, chRow : wc.chRow, inRow : wc.inRow, delRow : wc.delRow};},addRow : function (o) {//添加行var wc = this, rows = wc.rows, i = rows.length;return rows[i] = {id : i, div : o, cols : wc};},inRow : function (a, b) {//插入行var wc = b.cols = this, rows = wc.rows, i;if (a < rows.length) {for (i = a ; i < rows.length ; i ++) rows[i].id ++;rows.splice(a, 0, b);b.id = a;return b;} else {b.id = rows.length;return rows[b.id] = b;}},delRow : function (a) {//删除列var wc = this, rows = wc.rows, i, r;if (a >= rows.length) return;r = rows[a];rows.splice(a, 1);for (i = a ; i < rows.length ; i ++) rows[i].id = i;return r;}};var CDrag = Class.create();CDrag.IE = /MSIE/.test(window.navigator.userAgent);CDrag.prototype = {initialize : function () {//初始化成员var wc = this;wc.table = new Table; //建立表格对象wc.iFunc = wc.eFunc = null;wc.obj = { on : { a : null, b : "" }, row : null, left : 0, top : 0 };wc.temp = { row : null, div : document.createElement("div") };wc.temp.div.setAttribute(CDrag.IE ? "className" : "class", "CDrag_temp_div");wc.temp.div.innerHTML = " ";},reMouse : function (a) {//获取鼠标位置var e = Object.reEvent();return {x : document.documentElement.scrollLeft + e.clientX,y : document.documentElement.scrollTop + e.clientY};},rePosition : function (o) {//获取元素绝对位置var $x = $y = 0;do {$x += o.offsetLeft;$y += o.offsetTop;} while ((o = o.offsetParent) && o.tagName != "BODY");return { x : $x, y : $y };},sMove : function (o) {//当拖动开始时设置参数var wc = this;if (wc.iFunc || wc.eFinc) return;var mouse = wc.reMouse(), obj = wc.obj, temp = wc.temp, div = o.div, position = wc.rePosition(div);obj.row = o;obj.on.b = "me";obj.left = mouse.x - position.x;obj.top = mouse.y - position.y;temp.row = document.body.appendChild(div.cloneNode(true)); //复制预拖拽对象with (temp.row.style) {//设置复制对象position = "absolute";left = mouse.x - obj.left + "px";top = mouse.y - obj.top + "px";zIndex = 100;opacity = "0.3";filter = "alpha(opacity:30)";}with (temp.div.style) {//设置站位对象height = div.clientHeight + "px";width = div.clientWidth + "px";}/*div.parentNode.insertBefore(temp.div, div);div.style.display = "none"; //隐藏预拖拽对象*/div.parentNode.replaceChild(temp.div, div);wc.iFunc = Object.addEvent(document, ["onmousemove"], wc.iMove.bind(wc));wc.eFunc = Object.addEvent(document, ["onmouseup"], wc.eMove.bind(wc));document.onselectstart = new Function("return false");},iMove : function () {//当鼠标移动时设置参数var wc = this, cols = wc.table.cols, mouse = wc.reMouse(), obj = wc.obj, temp = wc.temp, row = obj.row, div = temp.row,t_position, t_cols, t_rows, i, j;with (div.style) {left = mouse.x - obj.left + "px";top = mouse.y - obj.top + "px";}for (i = 0 ; i < cols.length ; i ++) {t_cols = cols[i];t_position = wc.rePosition(t_cols.div);if (t_position.x < mouse.x && t_position.x + t_cols.div.offsetWidth > mouse.x) {if (t_cols.rows.length > 0) { //如果此列行数大于0if (wc.rePosition(t_cols.rows[0].div).y + 20 > mouse.y) {//如果鼠标位置大于第一行的位置即是最上。。//向上obj.on.a = t_cols.rows[0];obj.on.b = "up";obj.on.a.div.parentNode.insertBefore(temp.div, obj.on.a.div);} else if (t_cols.rows.length > 1 && t_cols.rows[0] == row &&wc.rePosition(t_cols.rows[1].div).y + 20 > mouse.y) {//如果第一行是拖拽对象而第鼠标大于第二行位置则,没有动。。//向上obj.on.b = "me";t_cols.rows[1].div.parentNode.insertBefore(temp.div, t_cols.rows[1].div);} else {for (j = t_cols.rows.length - 1 ; j > -1 ; j --) {//重最下行向上查询t_rows = t_cols.rows[j];if (t_rows == obj.row) continue;if (wc.rePosition(t_rows.div).y < mouse.y) {//如果鼠标大于这行则在这行下面if (t_rows.id + 1 < t_cols.rows.length && t_cols.rows[t_rows.id + 1] != obj.row) {//如果这行有下一行则重这行下一行的上面插入t_cols.rows[t_rows.id + 1].div.parentNode.insertBefore(temp.div, t_cols.rows[t_rows.id + 1].div);obj.on.a = t_rows;obj.on.b = "down";} else if (t_rows.id + 2 < t_cols.rows.length) {//如果这行下一行是拖拽对象则插入到下两行,即拖拽对象返回原位t_cols.rows[t_rows.id + 2].div.parentNode.insertBefore(temp.div, t_cols.rows[t_rows.id + 2].div);obj.on.b = "me";} else {//前面都没有满足则放在最低行t_rows.div.parentNode.appendChild(temp.div);obj.on.a = t_rows;obj.on.b = "down";}return;}}}} else {//此列无内容添加新行t_cols.div.appendChild(temp.div);obj.on.a = t_cols;obj.on.b = "new";}}}},eMove : function () {//当鼠标释放时设置参数var wc = this, obj = wc.obj, temp = wc.temp, row = obj.row, div = row.div, o_cols, n_cols;if (obj.on.b == "up") {//向最上添加o_cols = obj.row.cols;n_cols = obj.on.a.cols;n_cols.inRow(0, o_cols.delRow(obj.row.id));} else if (obj.on.b == "down") {//相对向下添加o_cols = obj.row.cols;n_cols = obj.on.a.cols;n_cols.inRow(obj.on.a.id + 1, o_cols.delRow(obj.row.id));} else if (obj.on.b == "new") {//向无内容列添加o_cols = obj.row.cols;n_cols = obj.on.a;n_cols.inRow(0, o_cols.delRow(obj.row.id));}temp.div.parentNode.replaceChild(div, temp.div);temp.row.parentNode.removeChild(temp.row);delete temp.row;Object.delEvent(document, ["onmousemove"], wc.iFunc);Object.delEvent(document, ["onmouseup"], wc.eFunc);document.onselectstart = wc.iFunc = wc.eFunc = null;},add : function (o) {//添加对象var wc = this;Object.addEvent(o.div.childNodes[CDrag.IE ? 0 : 1], ["onmousedown"], wc.sMove.bind(wc, o));},parse : function (o) {//初始化成员var wc = this, table = wc.table, cols, i, j;for (i = 0 ; i < o.length ; i ++) {cols = table.addCols(o[i].cols);for (j = 0 ; j < o[i].rows.length ; j ++)wc.add(cols.addRow(o[i].rows[j]));}}};Object.addEvent(window, ["onload"], function () {var wc = new CDrag;wc.parse([{cols : $("m_1"), rows : [$("m_1_1"), $("m_1_2"), $("m_1_3"), $("m_1_4")]},{cols : $("m_2"), rows : [$("m_2_1"), $("m_2_2"), $("m_2_3"), $("m_2_4")]},{cols : $("m_3"), rows : [$("m_3_1"), $("m_3_2"), $("m_3_3"), $("m_3_4")]},{cols : $("m_4"), rows : [$("m_4_1"), $("m_4_2"), $("m_4_3"), $("m_4_4")]}]);});</script>