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 相关文章推荐
js数组的操作详解
Mar 27 Javascript
用html+css+js实现的一个简单的图片切换特效
May 28 Javascript
jQuery中ready事件用法实例
Jan 19 Javascript
JS实现部分HTML固定页面顶部随屏滚动效果
Dec 24 Javascript
JavaScript切换搜索引擎的导航网页搜索框实例代码
Jun 11 Javascript
js学习总结之dom2级事件基础知识详解
Jul 27 Javascript
node.js-v6新版安装具体步骤(分享)
Sep 06 Javascript
vue路由拦截及页面跳转的设置方法
May 24 Javascript
微信小程序点击保存图片到本机功能
Dec 13 Javascript
javascript设计模式 ? 策略模式原理与用法实例分析
Apr 21 Javascript
Vue实现腾讯云点播视频上传功能的实现代码
Aug 17 Javascript
解决Vue项目中tff报错的问题
Oct 21 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
50个PHP程序性能优化的方法
2014/06/02 PHP
ThinkPHP单字母函数(快捷方法)使用总结
2014/07/23 PHP
浅析Yii2中GridView常见操作
2016/04/22 PHP
php中foreach结合curl实现多线程的方法分析
2016/09/22 PHP
PHP实现SMTP邮件的发送实例
2018/09/27 PHP
PHP基于curl实现模拟微信浏览器打开微信链接的方法示例
2019/02/15 PHP
js捕获鼠标右键菜单中的粘帖事件实现代码
2013/04/01 Javascript
火狐下table中创建form导致两个table之间出现空白
2013/09/02 Javascript
JSON格式化输出
2014/11/10 Javascript
javascript自动生成包含数字与字符的随机字符串
2015/02/09 Javascript
QQ登录背景闪动效果附效果演示源码下载
2015/09/22 Javascript
jquery可定制的在线UEditor编辑器
2015/11/17 Javascript
JS 通过系统时间限定动态添加 select option的实例代码
2016/06/09 Javascript
js封装成插件_Canvas统计图插件编写实例
2017/09/12 Javascript
详解 vue.js用法和特性
2017/10/15 Javascript
简单了解微信小程序的目录结构
2019/07/01 Javascript
Flutter实现仿微信底部菜单栏功能
2019/09/18 Javascript
在Chrome DevTools中调试JavaScript的实现
2020/04/07 Javascript
Vue中nprogress页面加载进度条的方法实现
2020/11/13 Javascript
[01:00:25]2018DOTA2亚洲邀请赛3月30日 小组赛A组 VG VS Liquid
2018/03/31 DOTA
[01:51]2018年度CS GO最具人气外援-完美盛典
2018/12/16 DOTA
Python实现115网盘自动下载的方法
2014/09/30 Python
Python网页解析利器BeautifulSoup安装使用介绍
2015/03/17 Python
使用基于Python的Tornado框架的HTTP客户端的教程
2015/04/24 Python
简单谈谈Python中的元祖(Tuple)和字典(Dict)
2017/04/21 Python
轻松理解Python 中的 descriptor
2017/09/15 Python
Python中使用__new__实现单例模式并解析
2019/06/25 Python
Python英文文章词频统计(14份剑桥真题词频统计)
2019/10/13 Python
Carter’s官方旗舰店:美国受欢迎的婴童服装品牌
2018/01/21 全球购物
Rentalcars.com中国:世界上最大的在线汽车租赁服务
2019/08/22 全球购物
C++如何引用一个已经定义过的全局变量
2014/08/25 面试题
计算机大学生职业生涯规划书范文
2014/02/19 职场文书
旅游活动总结
2014/08/27 职场文书
Python的这些库,你知道多少?
2021/06/09 Python
SpringBoot项目部署到阿里云服务器的实现步骤
2022/06/28 Java/Android
CSS中理解层叠性及权重如何分配
2022/12/24 HTML / CSS