首頁 >web前端 >js教程 >javascript實作表格排序 編輯 拖曳 縮放_javascript技巧

javascript實作表格排序 編輯 拖曳 縮放_javascript技巧

WBOY
WBOY原創
2016-05-16 16:22:451012瀏覽

簡單表格排序

 可以雙擊編輯 自訂編輯後的 規則

 可拖曳列進行列替換

 可推動邊框進行列寬度的縮放

 

複製程式碼 程式碼如下:

 http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
http://www.w3.org/1999/xhtml">


Table




 
  
      
      
      
      
      
   
   
   
   
   
 
 
   
   
   
   
       
 
 
   
   
   
   
       
 
 
   
   
   
   
       
 
 
   
   
   
   
       
 
 
   
   
   
   
       
 
 
   
   
   
   
       
 
 
   
   
   
   
       
 
 
   
   
   
   
       
 
 
   
   
   
   
       
 
 
   
   
   
   
       
                         
 
表>

(函數(窗口,未定義){
window.Sys = 函數 (ua){
    var b = {
        即: /msie/.test(ua) && !/opera/.test(ua),
        歌劇:/opera/.test(ua),
        Safari: /webkit/.test(ua) && !/chrome/.test(ua),
        火狐:/firefox/.test(ua),
        鉻:/chrome/.test(ua)
    },vMark = "";
    for (var i in b) {
        if (b[i]) { vMark = "safari" == i ? 「版本」:我;休息; }
    }
    b.version = vMark && RegExp("(?:" vMark ")[\/: ]([\d.] )").test(ua) ? RegExp.$1 : "0";
    b.ie6 = b.ie && parseInt(b.version, 10) == 6;
    b.ie7 = b.ie && parseInt(b.version, 10) == 7;
    b.ie8 = b.ie && parseInt(b.version, 10) == 8;  
    回 b;
}(window.navigator.userAgent.toLowerCase());

window.Sys.ie6&&document.execCommand("BackgroundImageCache", false, true);

視窗.$ = 函數(Id){
    return document.getElementById(Id);
};
window.addListener = function(element,e,fn){
    !element.events&&(element.events = {});
    element.events[e]&&(element.events[e][addListener.guid ]=fn)||(element.events[e] = {'0':fn});
    element.addEventListener?element.addEventListener(e,fn,false):element.attachEvent("on" e,fn);
};
window.addListener.guid = 1;
window.removeListener = function(element,e,fn){
    var handlers = element.events[e],type;
    如果(fn){
        for(輸入處理程序)
            if(handlers[type]===fn){
                element.removeEventListener?element.removeEventListener(e,fn,false):element.detachEvent("on" e,fn);
                移除處理程序[型別];
            }
    }其他{
        for(輸入處理程序){
            element.removeEventListener?element.removeEventListener(e,handlers[type],false):element.detachEvent("on" e,handlers[type]);
            移除處理程序[型別];
        }
    }       
};
window.setStyle = function(e,o){
    if(typeof o=="string")
        e.style.cssText=o;
    否則   
        for(var i in o)
            e.style[i] = o[i];
};

var slice = Array.prototype.slice;
window.Bind = function(object, fun) {
    var args = slice.call(arguments).slice(2);
    回傳函數() {
            return fun.apply(object, args);
    };
};
window.BindAsEventListener = function(object, fun,args) {
    var args = slice.call(arguments).slice(2);
    返回函數(事件){
        return fun.apply(object, [event || window.event].concat(args));
    }
};
//從jQ
複製 window.Extend = function(){
 var 目標 = 參數[0] || {}, i = 1, length = argument.length, deep = true, options;
 if ( typeof target === "boolean" ) {
  深度=目標;
  目標=參數[1] || {};
  我 = 2;
 }
 if ( typeof target !== "object" && Object.prototype.toString.call(target)!="[object Function]")
  目標 = {};
 for(;i   if ( (options = argument[ i ]) != null )
   for(選項中的變數名稱){
    var src = target[ name ], copy = options[ name ];
    if ( 目標 === 複製 )
     繼續;
    if ( deep && copy && typeof copy === "object" && !copy.nodeType ){
     target[ name ] = argument.callee( deep, src || ( copy.length != null ? [ ] : { } ), copy );
    } 
    else if(複製!==未定義)
     目標[名稱]=複製;      
   }
 }
 返回目標;   
};
window.objPos = function(o){
 var x = 0, y = 0;
 do{x = o.offsetLeft;y = o.offsetTop;}while((o=o.offsetParent));
 return {'x':x,'y':y};
}
window.Class = 函數(屬性){
var _class = function(){return (arguments[0] !== null && this.initialize && typeof(this.initialize) == 'function') ? this.initialize.apply(this, 參數) : this;};
    _class.prototype = 屬性;
    回傳_class;
};
window.hasClass = 函數(元素,類別名稱){
 return element.className.match(new RegExp('(\s|^)' className '(\s|$)'));
} ;
window.addClass  = function(element, className) {
 !this.hasClass(element, className)&&(element.className = " " className);
}
window.removeClass = function(element, className) {
hasClass(element, className)&&(element.className = element.className.replace(new RegExp('(\s|^)' className '(\s|$)'),' ')) ;
}
})(視窗);

var Table = new Class({
    options :{
        minWidth : 62
    },
    initialize : function(tab,set){
        this.table      = tab;
        this.rows       = [];             //已在其中所記錄下所有tr中的引用
        this.sortCol    = null;           //記錄哪一列正在排序
        this.inputtd    = null;           //記錄哪個td正在編輯了
        this.editconfig = {};             //編輯表格中的規則與提示
        this.thead      = tab.getElementsByTagName('thead')[0];
        this.theadTds   = tab.getElementsByTagName('thead')[0].getElementsByTagName('td'); //常用到的dom集合可以用個屬性來引用
        this.tbodyTds   = tab.getElementsByTagName('tbody')[0].getElementsByTagName('td');
        this.closConfig = {
   on    : false,
            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)
         //記錄那些checkbox,radio被選中了   ie6在做dom操作的時候不會記住這些狀態
        if(Sys.ie6){
            this.checkbox = {};         
            var checkboxs = tab.getElementsByTagName('input'),i=0,l=checkboxs.length;
            for(;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('tdthis'),length=document,tabTads.length;
        //編輯使用的input
  this.input = d.createElement('input'); 
        this.input.type = "text";
        this.input.className = 'edit';
        //用來顯示正在拖曳的div
        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";
  //遍歷set 做一些設定                          
        for(;i             //給予需要排序的獵頭綁定事件
            addListener(this.theadTds[set[i].id],'click',Bind(this,this.sortTable,this.theadTds[set[i].id],set[i].type));
            //定義需要編輯的表格給列定義所需設定
            set[i].edit&&(this.editconfig[set[i].id]={rule:set[i].edit.rule,message:set[i].edit.message});
;
;
;
;
;
        }
        // 將 所有的tr放到一個陣列 用於排序   
        for( i=0,l=rows.length;i             this.rows[i]=rows[i];
        
                   //遍歷所有的td 做一些設定    
        for( i=0,l=tabTads.length;i             //將頭部的td全部做標記 拖曳的時候要用到
            i             //將需要編輯的td新增edit屬性
            i>=length&&this.editconfig[i%length]&&tabTads[i].setAttribute('edit',i%length);
        }
       
        //綁定 拖曳與縮放的操作
        addListener(this.thead,'mousedown',BindAsEventListener(this,this.dragOrWidth));
       
        //拖曳的時候 記錄移動到了那列td上
        addListener(this.thead,'mouseover',BindAsEventListener(this,this.theadHover));
  
  //唉
  addListener(this.thead,'mouseout',BindAsEventListener(this,this.theadOut));
       
        //綁定編輯事件 根據e.srcElement or e.target去判斷哪個表格被編輯   
        addListener(tab,'dblclick',BindAsEventListener(this,this.edit));   
       
        //離開input時候儲存下修改的內容
        addListener(this.input,'blur',Bind(this,this.save,this.input));                   },
    sortTable :function(td,type){ //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(td.getAttribute('clos'),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             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;   //記錄一哪一列正在排序中         
    },
    比較:函數(n,類型){
  返回函數 (a1,a2){
   var 轉換 ={
    int    : function(v){return parseInt(v)},
    float :函數(v){返回parseFloat(v)},
    日期   : function(v){return v.toString()},
    字串 : 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);
   返回a1==a2?0:a1   };
    },
    編輯:函數(e){
        var elem = this.inputtd=e.srcElement || e.目標;
        if(!elem.getAttribute('edit'))return;
        this.input.value = elem.innerHTML;
        elem.innerHTML = "";
        elem.appendChild(this.input);
        this.input.focus();
    },
    儲存:函數(elem){
  var editinfo=this.editconfig[elem.parentNode.getAttribute('edit')],status={
   "[object Function]" : editinfo.rule&&editinfo.rule(this.input.value) 中的「長度」||false,       
   "[object RegExp]"   : editinfo.rule&&editinfo.rule.test(this.input.value) 中的「測試」||false
  }[Object.prototype.toString.call(editinfo.rule)],_self=this;
  //修改如果不符合條件提示訊息
  typeof status != "boolean"&&(editinfo.message = status);
  if(狀態===true){
   this.inputtd.innerHTML = this.input.value;
   this.inputtd=null;
  }其他{
   警報(editinfo.message);
   //firefox下 直接用input.focus()不會執行 使用setTimeout可以執行
   setTimeout(function(){_self.input.focus()},0);
  }                    
    },
    theadHover : 函數(e){
        var elem = e.srcElement || e.目標;
        if(elem.nodeName.toLowerCase() ==='td'&&this.closConfig.on){
            this.closConfig.totd = elem.getAttribute('clos');
   !hasClass(elem,'thover')&&addClass(elem,'thover');
  }        
    },
 theadOut : 函數(e){
        var elem = e.srcElement || e.目標;
        if(elem.nodeName.toLowerCase() ==='td'&&this.closConfig.on)removeClass(elem,'thover')
 },
    DragOrWidth : 函數(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));
   this.closConfig.on = true;
   Sys.ie?this.thead.setCapture(false):e.preventDefault();
        }
                  
  //支援縮放
  if(elem.nodeName.toLowerCase()==='div'){
   Sys.ie?(e.cancelBubble=true):e.stopPropagation();
   //如果是最後一個td裡面的div不進行縮放
   if(this.theadTds[this.theadTds.length-1]===elem.parentNode)return
   Sys.ie?this.thead.setCapture(false):e.preventDefault();
   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));                                               
  }
    },
    拖曳:函數(e){
        window.getSelection ?         setStyle(this.div,{display:"block",left:e.clientX 9 "px",top:e.clientY 20 "px"});
    },
    遊標向上:函數(){
        var closConfig = this.closConfig,rows = this.table.getElementsByTagName('tr'),td,n,o,i=0,l=rows.length;
  this.div.style.display = "無";
        removeListener(document,'mousemove');
        removeListener(document,'mouseup');
  Sys.ie&&this.thead.releaseCapture();
  關閉配置.on = false; 
  if(closConfig.totd===null)return;
  removeClass(this.theadTds[closConfig.totd],'thover');
        //在同一列不進行列替換
        if(closConfig.td === closConfig.totd)return;
  
  //如果
進行列替換   if(closConfig.td*1 1===closConfig.totd*1){
   n = closConfig.totd;
   o = closConfig.td;
  }其他{
   n = closConfig.td;
   o = closConfig.totd;
  }
        for(;i             td = rows[i].getElementsByTagName('td');
            rows[i].insertBefore(td[n],td[o]);
        }                
                  
        //重新標識表頭
        for(i=0,l=this.theadTds.length;i             this.theadTds[i].setAttribute('clos',i);
  closConfig.totd=closConfig.td=null;     
    },
 widthMove : 函數(e){
  window.getSelection ?   var widthConfig = this.widthConfig,x = e.clientX - widthConfig.x,left = e.clientX,clientX=left;
  if(clientXwidthConfig.tdwidth-this.minWidth){
   left = widthConfig.x - widthConfig.tdwidth this.minWidth;
  }
  if(clientX>widthConfig.x&&clientX - widthConfig.x>widthConfig.nexttdwidth-this.minWidth){
   左=widthConfig.x widthConfig.nexttdwidth-this.minWidth;       
  }
  setStyle(this.line,{display:"block",left:left "px"});   
 },
 widthUp : 函數(){
  this.line.style.display = "無";
  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';
  Sys.ie&&this.thead.releaseCapture();
  removeListener(document,'mousemove');
  removeListener(document,'mouseup');
 }           
});
window.onload = function(){
    function checkName(val){
        if(val.replace(/^s $/g,'')==='') return '姓名輸入不能為空';
        if(val.replace(/^s |s $/,'').length>10) return '姓名長度不能大於10個字';
        if(!/^[u4e00-u9fa5a-z] $/i.test(val)) return '姓名只能輸入中文或字母';
        return true;
    };
 function checkRemark(val){
  if(val.replace(/^s $/g,'')==='') return '備註輸入不能為空';
  if(val.replace(/^s |s $/,'').length>15) return '備註長度不能大於15個字元';
  if(!/^[u4e00-u9fa5ws] $/i.test(val)) return '備註只能輸入中文數字下劃線空格';
  return true;
 }
    var set = [
        {id:0,type:"int"},
        {id:2,type:"string",edit:{rule:checkName,message:''}},
{id:3,type:"date",edit:{rule:/^d{4}-d{2}-d{2}$/,message:"按這中格式輸入日期1985-02-30" }},
        {id:4,type:"string",edit:{rule:checkRemark,message:''}}
    ];
    new Table($("tab"),set);
}

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
ID
选中
姓名
生日
备注

  
  頭>
 
 
1 小三 1982-05-27 杯具,全是杯具
3 李四 1983-06-27 恩恩我魔獸技術不錯
2 王五 1987-05-27 波斯王子時之刃還好
4 趙六 1988-05-27 我叫趙六
5 朱八 1984-05-27 洗睡吧
6 阿斯多夫 1984-06-27 阿斯多夫暗房逢燈
7 杯具 1984-06-27 很多杯具
8 餐具 1984-02-27 許多器具
8 盥洗用品 1984-08-27 許多盥洗用品
9 內牛滿面 1984-12-27 10快一晚
10 犀利哥 1984-12-21 嘿嘿