冒个泡.....
简单操作
水平不够  请多指教.................
传送门Code:
var Table = new Class({
    options :{
        minWidth : 62
    },
    initialize : function(tab,set){
        this.table      = tab;
        this.rows       = [];             
        this.sortCol    = null;          
        this.inputtd    = null;           
        this.editconfig = {};           
        this.thead      = tab.getElementsByTagName('thead')[0];
        this.theadTds   = tab.getElementsByTagName('thead')[0].getElementsByTagName('td'); 
        this.tbodyTds   = tab.getElementsByTagName('tbody')[0].getElementsByTagName('td');
        this.closConfig = {
            td    : null,
            totd  : null
        };
this.widthConfig = {
td          : null,
nexttd      : null,
x           : 0,
tdwidth     : 0,
nexttdwidth : 0
};
Extend(this,this.options);
(Sys.ie6||Sys.chrome)&&(tab.width=tab.offsetWidth)
        if(Sys.ie6){
            this.checkbox = {};          
            var checkboxs = tab.getElementsByTagName('input'),i=0,l=checkboxs.length;
            for(;i<l;i++)
                (checkboxs[i].type=="checkbox"||checkboxs[i].type=="radio")&&
                addListener(checkboxs[i],"click",Bind(this,function(elm,i){
                    elm.checked==true?(this.checkbox[i] = elm):(delete this.checkbox[i]);
                },checkboxs[i],i));        
        };
        var i=0,l=set.length,rows =tab.tBodies[0].rows,d=document,tabTads=tab.getElementsByTagName('td'),length=this.theadTds.length;
this.input = d.createElement('input');  
        this.input.type = "text";
        this.input.className = 'edit';
        this.div = d.body.appendChild(d.createElement('div'));
        this.div.className ="div";
this.line = d.body.appendChild(d.createElement('div'));
this.line.className = 'line';
this.line.style.top = objPos(tab).y +"px";                   
        for(;i<l;i++){
            addListener(this.theadTds[set[i].id],'click',Bind(this,this.sortTable,this.theadTds[set[i].id],set[i].id,set[i].type));            set[i].edit&&(this.editconfig[set[i].id]={rule:set[i].edit.rule,message:set[i].edit.message});
        }
        for( i=0,l=rows.length;i<l;i++)
            this.rows[i]=rows[i];  
        for( i=0,l=tabTads.length;i<l;i++){
            i<length&&tabTads[i].setAttribute('clos',i);
            i>=length&&this.editconfig[i%length]&&tabTads[i].setAttribute('edit',i%length);
        }
        addListener(this.thead,'mousedown',BindAsEventListener(this,this.dragOrWidth));
        addListener(this.thead,'mouseover',BindAsEventListener(this,this.theadHover)); 
        addListener(tab,'dblclick',BindAsEventListener(this,this.edit));    
        addListener(this.input,'blur',Bind(this,this.save,this.input));                  
    },
    sortTable :function(td,n,type){ 
        var frag=document.createDocumentFragment(),span=td.getElementsByTagName('span')[0],str= span.innerHTML;
        if(td===this.sortCol){
            this.rows.reverse();
            span.innerHTML =str.replace(/.$/,str.charAt(str.length-1)=="↓"?"↑":"↓") ;
        }else{
            this.rows.sort(this.compare(n,type));
            span.innerHTML = span.innerHTML + "↑";
            this.sortCol!=null&&(this.sortCol.getElementsByTagName('span')[0].innerHTML = this.sortCol.getElementsByTagName('span')[0].innerHTML.replace(/.$/,''));
        };
        for(var i=0,l=this.rows.length;i<l;i++)
            frag.appendChild(this.rows[i]);
        this.table.tBodies[0].appendChild(frag);
        if(Sys.ie6){
            for(var s in this.checkbox)
                this.checkbox[s].checked = true;
        }
        this.sortCol = td;           
    },
    compare :function(n,type){
return function (a1,a2){
var convert ={
int    : function(v){return parseInt(v)},
float  : function(v){return parseFloat(v)},
date   : function(v){return v.toString()},
string : function(v){return v.toString()}
};
!convert[type]&&(convert[type]=function(v){return v.toString()});
a1 =convert[type](a1.cells[n].innerHTML);
a2 =convert[type](a2.cells[n].innerHTML);
return a1==a2?0:a1<a2?-1:1;           
};
    },
    edit: function(e){
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
        var elem = this.inputtd=e.srcElement || e.target;
        if(!elem.getAttribute('edit'))return;
        this.input.value = elem.innerHTML;
        elem.innerHTML = "";
        elem.appendChild(this.input);
        this.input.focus();
    },
    save : function(elem){
var editinfo=this.editconfig[elem.parentNode.getAttribute('edit')],status={
"[object Function]" : 'length' in editinfo.rule&&editinfo.rule(this.input.value)||false,        
"[object RegExp]"   : 'test' in editinfo.rule&&editinfo.rule.test(this.input.value)||false
}[Object.prototype.toString.call(editinfo.rule)];
typeof status != "boolean"&&(editinfo.message = status);
if(status===true){
this.inputtd.innerHTML = this.input.value;
this.inputtd=null;
}else{
alert(editinfo.message);
this.input.focus();
}                     
    },
    theadHover  : function(e){
        var elem = e.srcElement || e.target;
        if(elem.nodeName.toLowerCase() ==='td')
            this.closConfig.totd = elem.getAttribute('clos');        
    },
    dragOrWidth : function(e){
        var elem = e.srcElement || e.target,widthConfig=this.widthConfig;
        if(elem.nodeName.toLowerCase()==='td'){
            this.closConfig.td = elem.getAttribute('clos');
            addListener(document,'mousemove',BindAsEventListener(this,this.dragMove));
            addListener(document,'mouseup',Bind(this,this.dragUp));
        }
if(elem.nodeName.toLowerCase()==='div'){
Sys.ie?(e.cancelBubble=true):e.stopPropagation();
if(this.theadTds[this.theadTds.length-1]===elem.parentNode)return
widthConfig.x = e.clientX;
widthConfig.td = elem.parentNode;
widthConfig.nexttd = widthConfig.td.nextSibling;
while(widthConfig.nexttd.nodeName.toLowerCase()!="td"){
 widthConfig.nexttd = widthConfig.nexttd.nextSibling;
};
widthConfig.tdwidth     = widthConfig.td.offsetWidth;
widthConfig.nexttdwidth = widthConfig.nexttd.offsetWidth;
this.line.style.height  = this.table.offsetHeight +"px";
addListener(document,'mousemove',BindAsEventListener(this,this.widthMove));
addListener(document,'mouseup',Bind(this,this.widthUp));                                                
}
    },
    dragMove : function(e){
        window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
        setStyle(this.div,{display:"block",left:e.clientX+9+"px",top:e.clientY+20+"px"});
    },
    dragUp :function(){
        var closConfig = this.closConfig,rows = this.table.getElementsByTagName('tr'),td,n,o,i=0,l=rows.length;
this.div.style.display = "none";
        removeListener(document,'mousemove');
        removeListener(document,'mouseup');
        if(closConfig.td === closConfig.totd)return;
if(closConfig.td*1+1===closConfig.totd*1){
n = closConfig.totd;
o = closConfig.td;
}else{
n = closConfig.td;
o = closConfig.totd;
}
        for(;i<l;i++){
            td = rows[i].getElementsByTagName('td');
            rows[i].insertBefore(td[n],td[o]);
        }                 
        for(i=0,l=this.theadTds.length;i<l;i++)
            this.theadTds[i].setAttribute('clos',i);      
    },
widthMove : function(e){
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
var widthConfig = this.widthConfig,x = e.clientX - widthConfig.x,left = e.clientX,clientX=left;
if(clientX<widthConfig.x&&widthConfig.x - clientX>widthConfig.tdwidth-this.minWidth){
left = widthConfig.x - widthConfig.tdwidth+this.minWidth;
}
if(clientX>widthConfig.x&&clientX - widthConfig.x>widthConfig.nexttdwidth-this.minWidth){
left =widthConfig.x + widthConfig.nexttdwidth-this.minWidth;        
}
setStyle(this.line,{display:"block",left:left+"px"});    
},
widthUp : function(){
this.line.style.display = "none";
var widthConfig = this.widthConfig,x= parseInt(this.line.style.left) - widthConfig.x;  
widthConfig.nexttd.style.width = widthConfig.nexttdwidth -x -1 +'px';
widthConfig.td.style.width = widthConfig.tdwidth + x -1 +'px';
removeListener(document,'mousemove');
removeListener(document,'mouseup');
}            
});

解决方案 »

  1.   

    代码写得很漂亮```测试的时候有点小bug把第一列拉到第二,点排序会乱掉.
      

  2.   

    http://download.csdn.net/source/2565320 我上传了,不用分。 你看看对你有用不?
      

  3.   

    差不多和EXTJS里的功能近似了  很NB  
      

  4.   

    lz代码风格不错啊问题:
    1.拖动,在浏览器外放开,有时候会不正确。没仔细看你代码,不知道你有没有用捕获
    2.Chrome上问题。建议:
    拖得时候,在放入的位置这里加入淡淡的模拟拖动块用户体验会更好
      

  5.   

    有个小bug,点排序时checkbox和radio出现不一致
      

  6.   

    1.之前离开浏览器时没有进行捕获 现在加上去了 
    不过在ie下 拖拽的时候不能用setCapture  因为无法获取到thead的鼠标事件  
    这个到是没想到好的解决办法2.不知道是什么问题  说出来研究下拖得时候,在放入的位置这里加入淡淡的模拟拖动块用户体验会更好 
    加了............能说说步骤吗  我研究下...............
      

  7.   

    晕  直接用thead来执行setCapture方法就可以正确释放捕获了.......