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


Posted in Javascript onJanuary 02, 2015

简单表格排序

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

 可拖动列进行列替换

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

 

 <!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浏览器下点击运行好像问题很大  拿到本地测试会比较好

Javascript 相关文章推荐
tbody元素支持嵌套的注意方法
Mar 24 Javascript
javascript 框架小结 个人工作经验
Jun 13 Javascript
一个JQuery操作Table的代码分享
Mar 30 Javascript
前台js对象在后台转化java对象的问题探讨
Dec 20 Javascript
jquery通过ajax加载一段文本内容的方法
Jan 15 Javascript
JS实现漂亮的淡蓝色滑动门效果代码
Sep 23 Javascript
jQuery事件绑定用法详解
Sep 08 Javascript
微信小程序自定义模态对话框实例详解
Aug 16 Javascript
js编写简单的聊天室功能
Aug 17 Javascript
Next.js实现react服务器端渲染的方法示例
Jan 06 Javascript
JavaScript(js)处理的HTML事件、键盘事件、鼠标事件简单示例
Nov 19 Javascript
JavaScript canvas实现跟随鼠标事件
Feb 10 Javascript
原生javascript实现DIV拖拽并计算重复面积
Jan 02 #Javascript
javascript使用smipleChart实现简单图表
Jan 02 #Javascript
原生javascript实现简单的datagrid数据表格
Jan 02 #Javascript
浅谈jQuery事件绑定原理
Jan 02 #Javascript
js+jquery实现图片裁剪功能
Jan 02 #Javascript
javascript 构造函数方式定义对象
Jan 02 #Javascript
深入探寻javascript定时器
Jan 02 #Javascript
You might like
Discuz!5的PHP代码高亮显示插件(黑暗中的舞者更新)
2007/01/29 PHP
php&amp;mysql 日期操作小记
2012/02/27 PHP
编写安全 PHP应用程序的七个习惯深入分析
2013/06/08 PHP
PHP在不同页面间传递Json数据示例代码
2013/06/08 PHP
PHP设计模式之调解者模式的深入解析
2013/06/13 PHP
PHP Cookei记录用户历史浏览信息的代码
2016/02/03 PHP
cakephp2.X多表联合查询join及使用分页查询的方法
2017/02/23 PHP
jQuery 数据缓存模块进化史详细介绍
2012/11/19 Javascript
jQuery点击自身以外地方关闭弹出层的简单实例
2013/12/24 Javascript
jquery 获取 outerHtml 包含当前节点本身的代码
2014/10/30 Javascript
window.onload与$(document).ready()的区别分析
2015/05/30 Javascript
javascript显示中文日期的方法
2015/06/18 Javascript
jQuery实现点击小图片淡入淡出显示大图片特效
2015/09/09 Javascript
jQuery插件Validate实现自定义校验结果样式
2016/01/18 Javascript
纯JS代码实现气泡效果
2016/05/04 Javascript
Js获取图片原始宽高的实现代码
2016/05/17 Javascript
详解nodejs 文本操作模块-fs模块(三)
2016/12/22 NodeJs
深入理解Angularjs中的$resource服务
2016/12/31 Javascript
js 实现省市区三级联动菜单效果
2017/02/20 Javascript
解决vue2.x中数据渲染以及vuex缓存的问题
2017/07/13 Javascript
jQuery实现火车票买票城市选择切换功能
2017/09/15 jQuery
Element-ui中元素滚动时el-option超出元素区域的问题
2019/05/30 Javascript
[02:30]辉夜杯主赛事第二日胜者组半决赛 CDEC.Y赛后采访
2015/12/26 DOTA
Python Tkinter简单布局实例教程
2014/09/03 Python
python编程实现希尔排序
2017/04/13 Python
Python字符串的修改方法实例
2019/12/19 Python
解决python3插入mysql时内容带有引号的问题
2020/03/02 Python
JAVA SWT事件四种写法实例解析
2020/06/05 Python
利用HTML5中的Canvas绘制一张笑脸的教程
2015/05/07 HTML / CSS
L*SPACE官网:比基尼、泳装和度假服装
2019/03/18 全球购物
HashMap和Hashtable的区别
2013/05/18 面试题
XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?
2016/01/12 面试题
信用社实习人员自我鉴定
2013/09/20 职场文书
工作岗位说明书模板
2014/05/09 职场文书
2014年驾驶员工作总结
2014/11/18 职场文书
大学生个人简历自荐信
2015/03/06 职场文书