当前位置: 首页 > 编程笔记 >

javascript实现表格排序 编辑 拖拽 缩放

计阳泽
2023-03-14
本文向大家介绍javascript实现表格排序 编辑 拖拽 缩放,包括了javascript实现表格排序 编辑 拖拽 缩放的使用技巧和注意事项,需要的朋友参考一下

简单表格排序

 可以双击编辑 自定义编辑后的 规则

 可拖动列进行列替换

 可推动边框进行列宽度的缩放

 


 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />

<title>Table</title>

</head>

<style type="text/css">

body{ font-size:12px}

#tab{ border-collapse: collapse;}

.edit{ height:16px; width:98%; background-color:#EFF7FF; font-size:12px; border:0px;}

#tab thead td{ background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/192373/r_t.bmp);color:#183C94;word-break:break-all}

#tab tbody td{overflow:hidden;word-break:break-all;}

#tab td{border: 1px solid #CECFCE;height:20px;line-height:20px;vertical-align:middle; }

#tab td.tc{text-align:center;}

.div{width:10px;height:6px; border:1px solid #999999; background-color:#FFFFFF; position:absolute; display:none;}

.line{ width:2px; background-color:#999999;  position:absolute; display:none}

.dr{height:100%;width:2px;background:#CECFCE;float:right;margin-right:-1px;cursor:sw-resize}

.r{float:right;}

.l{float:left;}

#tab thead td.thover{ background-image:url(http://album.hi.csdn.net/app_uploads/wtcsy/20081126/000054336.p.gif);background-repeat:repeat-x;}

</style>

<body >

<table id="tab"  border="0" cellspacing="1" cellpadding="0">

 <thead>

   <tr>

       <td width="80"class="tc" ><span class="l">ID</span><div class="r dr"></div></td>

       <td width="80"class="tc"><span class="l">选中</span><div class="r dr"></div></td>

       <td  width="130" class="tc"><span class="l">姓名</span><div class="r dr"></div></td>

       <td width="130" class="tc" ><span class="l">生日</span><div class="r dr"></div></td>

       <td width="220" class="tc" ><span class="l">备注</span><div class="r dr"></div></td>

   </tr>

  </thead>

  <tbody>

  <tr>

    <td height="16">1</td>

    <td><input type ="checkbox"><input name="ss" type="radio"  /></td>

    <td>小三</td>

    <td>1982-05-27</td>

    <td>杯具,全是杯具</td>

  </tr>

  <tr>

    <td>3</td>

    <td><input type ="checkbox"><input name="ss" type="radio"  /></td>

    <td>李四</td>

    <td>1983-06-27</td>

    <td>恩恩我魔兽技术不错</td>    

  </tr>

  <tr>

    <td>2</td>

    <td><input type ="checkbox"><input name="ss" type="radio"  /></td>

    <td>王五</td>

    <td>1987-05-27</td>

    <td>波斯王子 时之刃还不错</td>    

  </tr>

  <tr>

    <td>4</td>

    <td><input type ="checkbox"><input name="ss" type="radio"  /></td>

    <td>赵六</td>

    <td>1988-05-27</td>

    <td>我叫赵六</td>    

  </tr>

  <tr>

    <td>5</td>

    <td><input type ="checkbox"><input name="ss" type="radio"  /></td>

    <td>朱八</td>

    <td>1984-05-27</td>

    <td>洗洗睡吧</td>    

  </tr>

  <tr>

    <td>6</td>

    <td><input type ="checkbox"><input name="ss" type="radio"  /></td>

    <td>阿斯多夫</td>

    <td>1984-06-27</td>

    <td>阿斯多夫暗室逢灯</td>    

  </tr>

  <tr>

    <td>7</td>

    <td><input type ="checkbox"><input name="ss" type="radio"  /></td>

    <td>杯具</td>

    <td>1984-06-27</td>

    <td>很多的杯具</td>    

  </tr>

  <tr>

    <td>8</td>

    <td><input type ="checkbox"><input name="ss" type="radio"  /></td>

    <td>餐具</td>

    <td>1984-02-27</td>

    <td>很多的餐具</td>    

  </tr>

  <tr>

    <td>8</td>

    <td><input type ="checkbox"><input name="ss" type="radio"  /></td>

    <td>洗具</td>

    <td>1984-08-27</td>

    <td>很多的洗具</td>    

  </tr> 

  <tr>

    <td>9</td>

    <td><input type ="checkbox"><input name="ss" type="radio"  /></td>

    <td>内牛满面</td>

    <td>1984-12-27</td>

    <td>10快一晚</td>    

  </tr>

  <tr>

    <td>10</td>

    <td><input type ="checkbox"><input name="ss" type="radio"  /></td>

    <td>犀利哥</td>

    <td>1984-12-21</td>

    <td>嘿嘿</td>    

  </tr>                        

  </tbody>

</table>

<script language="javascript">

(function(window,undefined){

window.Sys = function (ua){

    var b = {

        ie: /msie/.test(ua) && !/opera/.test(ua),

        opera: /opera/.test(ua),

        safari: /webkit/.test(ua) && !/chrome/.test(ua),

        firefox: /firefox/.test(ua),

        chrome: /chrome/.test(ua)

    },vMark = "";

    for (var i in b) {

        if (b[i]) { vMark = "safari" == i ? "version" : i; break; }

    }

    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;   

    return b;

}(window.navigator.userAgent.toLowerCase());

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

window.$ = function(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;     if(fn){         for(type in handlers)             if(handlers[type]===fn){                 element.removeEventListener?element.removeEventListener(e,fn,false):element.detachEvent("on" + e,fn);                 delete handlers[type];             }     }else{         for(type in handlers){             element.removeEventListener?element.removeEventListener(e,handlers[type],false):element.detachEvent("on" + e,handlers[type]);             delete handlers[type];         }     }        }; window.setStyle = function(e,o){     if(typeof o=="string")         e.style.cssText=o;     else            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 function() {             return fun.apply(object, args);     }; }; window.BindAsEventListener = function(object, fun,args) {     var args = slice.call(arguments).slice(2);     return function(event) {         return fun.apply(object, [event || window.event].concat(args));     } }; //copy from jQ window.Extend = function(){  var target = arguments[0] || {}, i = 1, length = arguments.length, deep = true, options;  if ( typeof target === "boolean" ) {   deep = target;   target = arguments[1] || {};   i = 2;  }  if ( typeof target !== "object" && Object.prototype.toString.call(target)!="[object Function]")   target = {};  for(;i<length;i++){   if ( (options = arguments[ i ]) != null )    for(var name in options){     var src = target[ name ], copy = options[ name ];     if ( target === copy )      continue;     if ( deep && copy && typeof copy === "object" && !copy.nodeType ){      target[ name ] = arguments.callee( deep, src || ( copy.length != null ? [ ] : { } ), copy );     }      else if(copy !== undefined)      target[ name ] = copy;          }  }  return target;    }; 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 = function(properties){     var _class = function(){return (arguments[0] !== null && this.initialize && typeof(this.initialize) == 'function') ? this.initialize.apply(this, arguments) : this;};     _class.prototype = properties;     return _class; }; window.hasClass  = function(element, className){  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|$)'),' ')); } })(window);

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<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;         //编辑用的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<l;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<l;i++)             this.rows[i]=rows[i];                             //遍历所有的td 做一些设置             for( i=0,l=tabTads.length;i<l;i++){             //将头部的td全部做上标记 拖拽的时候要用到             i<length&&tabTads[i].setAttribute('clos',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<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){         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)],_self=this;   //如果不符合条件  修改提示信息   typeof status != "boolean"&&(editinfo.message = status);   if(status===true){    this.inputtd.innerHTML = this.input.value;    this.inputtd=null;   }else{    alert(editinfo.message);    //firefox下  直接用input.focus()不会执行  用setTimeout可以执行    setTimeout(function(){_self.input.focus()},0);   }                         },     theadHover  : function(e){         var elem = e.srcElement || e.target;         if(elem.nodeName.toLowerCase() ==='td'&&this.closConfig.on){             this.closConfig.totd = elem.getAttribute('clos');    !hasClass(elem,'thover')&&addClass(elem,'thover');   }             },  theadOut : function(e){         var elem = e.srcElement || e.target;         if(elem.nodeName.toLowerCase() ==='td'&&this.closConfig.on)removeClass(elem,'thover')  },     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));    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));                                                  }     },     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');   Sys.ie&&this.thead.releaseCapture();   closConfig.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;   }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);   closConfig.totd=closConfig.td=null;          },  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';   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-\u9fa5\w\s]+$/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); } </script> </body> </html>  

 已知BUG:

 ie6下 中文不自动换行

 非ie下字母和数字也不自动换行确实让人恼火

 chrome浏览器下点击运行好像问题很大  拿到本地测试会比较好

 类似资料:
  • 本文向大家介绍vue.draggable实现表格拖拽排序效果,包括了vue.draggable实现表格拖拽排序效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了vue.draggable实现表格拖拽排序效果展示的具体代码,供大家参考,具体内容如下 主要使用vuedraggable和sortablejs两个组件。 1、安装组件 2、引入组件 3、HTML 我的例子是给表格排序,项目整

  • 本文向大家介绍JavaScript实现拖拽和缩放效果,包括了JavaScript实现拖拽和缩放效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了JavaScript实现拖拽和缩放效果的具体代码,供大家参考,具体内容如下 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 本文向大家介绍vue实现列表拖拽排序的功能,包括了vue实现列表拖拽排序的功能的使用技巧和注意事项,需要的朋友参考一下   在日常开发中,特别是管理端,经常会遇到要实现拖拽排序的效果;这里提供一种简单的实现方案。   此例子基于vuecli3 首先,我们先了解一下js原生拖动事件:   在拖动目标上触发事件 (源元素): ondragstart - 用户开始拖动元素时触发 ondrag - 元素正

  • 本文向大家介绍php接口实现拖拽排序功能,包括了php接口实现拖拽排序功能的使用技巧和注意事项,需要的朋友参考一下 列表拖拽排序是一个很常见的功能,但是后端接口如何处理却是一个令人纠结的问题 如何实现才能达到效率最高呢? 先分析一个场景,假如有一个页面有十条数据,所谓的拖拽就是在这十条数据来来回回的拖,但是每次拖动都会影响到其他数据例如把最后一条拖到最前面,那么后面九条就自动往后移,反之也是,嗯~

  • 本文向大家介绍BootStrap table实现表格行拖拽效果,包括了BootStrap table实现表格行拖拽效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了BootStrap table实现表格行拖拽的具体代码,供大家参考,具体内容如下 不上图了 首先还是得添加三个文件,自己上网搜搜就行 前台,加在Bootstrap Table 属性里面   后台代码Controller

  • 请教大佬们个问题,vue2中我有一个基础的el-table表格,表格里分置顶区域和非置顶区域,需求是置顶区域之间可以互相拖拽排序,非置顶区域可以互相拖拽排序,非置顶和置顶之间不可拖拽排序, 比如1.2.3条数据是置顶的,可以互相拖拽排序,4.5.6是非置顶数据,可以拖拽排序,但1.2.3和4.5.6之间不可互相拖拽,感谢各位大佬解惑