zoukankan      html  css  js  c++  java
  • 支持触屏的jQuery轮播图插件

    移动轮播图我看到两类,

    一款是无线天猫的m.tmall.com和携程,实现了无缝轮播。

    一款是蘑菇街的,没有实现无缝轮播。

    我自己重写一个,类似天猫。

    1.页面代码

     1 <!DOCTYPE html>
     2 <html xmlns="http://www.w3.org/1999/xhtml" lang="UTF-8">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>基于jQuery的移动轮播图(支持触屏)</title>
     6     <meta name="viewport" content="maximum-scale=1,initial-scale=1,user-scalable=0">
     7 
     8     <style type="text/css">
     9 
    10     img
    11     {
    12         border:0;
    13         *display:inline;
    14     }
    15     li
    16 {
    17     border:0;
    18     list-style-type :none;  
    19 }
    20 ul
    21 {
    22     list-style:none;
    23     margin:0;
    24     padding:0;
    25 }
    26     body{
    27         overflow-x:hidden;
    28         margin:0 auto;
    29         padding:0;
    30         width: 100%;
    31         height: 100%;
    32     }
    33     .WSCSlideWrapper{
    34         width:100%;
    35         position: relative;
    36         margin:0 auto;
    37         //cursor:move;
    38     }
    39     #WSCSlideWrapperTwo{
    40         width:50%;
    41         position: relative;
    42         margin:10px auto;
    43         //cursor:move;
    44     }
    45     
    46     </style>
    47     <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/jquery-1.8.2.min.js"></script>
    48 
    49     <script type="text/javascript" src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/touchslide-1.1.js"></script>
    50 </head>
    51 <body>
    52 
    53     
    54     <div class="WSCSlideWrapper" id="WSCSlideWrapper" >
    55     
    56         <div>
    57         
    58             <a  href="http://www.baidu.com"><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1.jpg" /></a>
    59       <a  href="http://m.tmall.com"><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/2.jpg" /></a>
    60      <a href="http://huaban.com"><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/3.jpg" /></a>            
    61        </div>
    62    
    63     </div>
    64 
    65      <div class="WSCSlideWrapper" id="WSCSlideWrapperTwo" >
    66         <div>
    67              <a><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1 (1).jpg" /></a> 
    68              <a><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1 (2).jpg" /></a>    
    69              <a><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1 (3).jpg" /></a> 
    70              <a><img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1 (4).jpg" /></a>             
    71         </div>
    72       
    73     </div>
    74 <script type="text/javascript">
    75  
    76 $(document).ready(function(){
    77 
    78     $('.WSCSlideWrapper').height($('.WSCSlideWrapper').width()*0.3);
    79     $('#WSCSlideWrapperTwo').height($('#WSCSlideWrapperTwo').width()*1.5);
    80     $('.WSCSlideWrapper').touchslide({timecontrol:3000,animatetime:300,direction:'left',navshow:true,canvassuport:true});
    81 });
    82 
    83     
    84 </script>
    85 </body>
    86 </html>
    View Code

    2.js插件代码

      1 /* 
      2 * touchslide 1.1 
      3 * Copyright (c) 2014 BowenLuo http://www.luobo.com/ 
      4 * Date: 2014-06-08
      5 * Example:$('.WSCSlideWrapper').touchslide({timecontrol:3000,animatetime:300,direction:'left',navshow:true,canvassuport:true});
      6 * Update:增加对IE9+等非Safari内核浏览器的鼠标拖动图片功能
      7 */ 
      8 (function($){ 
      9 $.fn.touchslide = function(options){ 
     10 var defaults = { 
     11     timecontrol:3000,//图片停留时间
     12     animatetime:300, //图片滑动所需时间
     13     direction:'left', //轮播方向
     14     navshow:true,//是否显示图片导航栏
     15     canvassuport:true//图片导航栏是否开启cavas绘制圆
     16 } 
     17 var options = $.extend(defaults, options); 
     18 var timecontrol = options.timecontrol||3000;
     19 var animatetime = options.animatetime||300;
     20 var direction = options.direction||'left';
     21 var navshow = options.navshow;
     22 this.each(function(){ 
     23     var slideWrapper=$(this);
     24     var slideImgWrapper = slideWrapper.children('div:first');
     25     var slideAs = slideImgWrapper.children('a');
     26     var slideImgs = slideAs.children('img');
     27     var imgcount = slideImgs.length;
     28     var imgcountrealy = slideImgs.length;
     29     var navimgs;
     30     var circlewrapper;
     31     var circles;
     32     var canvassuport = true;
     33     var circler = 0;
     34     if(imgcount>1){
     35         $((slideImgWrapper.html().split("/a>")[0]+"/a>"+slideImgWrapper.html().split("/a>")[1]+"/a>")).insertAfter(slideAs.last());
     36         if(navshow){
     37             $("<div class='navimgs'></div>").insertAfter(slideImgWrapper);
     38             navimgs = slideWrapper.children('div:last');
     39             navimgs.append("<div class='circlewrapper'></div>");
     40             circlewrapper = navimgs.children('div:first');
     41             for(var i=0;i<imgcountrealy;i++){
     42                 circlewrapper.append("<canvas class='circle' width='15' height='15'></canvas>");
     43             }
     44             circles = circlewrapper.children('canvas');
     45             var myCanvas = circles[1];
     46             if (!myCanvas.getContext) 
     47             { 
     48                 canvassuport =false;
     49             }else 
     50             { 
     51                 canvassuport =options.canvassuport;            
     52             }         
     53         }
     54     }    
     55     slideAs =  slideImgWrapper.children('a');
     56     slideImgs = slideAs.children('img');    
     57     imgcount = slideImgs.length;
     58     var slideWrapperWidth = slideWrapper.width();    
     59     var slideWrapperHeight = slideWrapper.height();
     60     slideWrapper.css({"overflow":"hidden","width":slideWrapperWidth,"height":slideWrapperHeight});
     61     slideImgWrapper.css({'position':"absolute","z-index":"1","overflow":"hidden","width":slideWrapperWidth*imgcount,"height":slideWrapperHeight});    
     62     slideAs.css({'position':"relative","overflow":"hidden","float":"left","width":slideWrapperWidth,"height":slideWrapperHeight});    
     63     slideImgs.css({'position':"relative","z-index":"1","width":slideWrapperWidth,"height":slideWrapperHeight});
     64     if(typeof(navimgs)!=='undefined'){
     65         if(navshow){
     66         navimgs.css({"position":"absolute","z-index":"3","overflow":"hidden","display":"block","width":slideWrapperWidth,"height":slideWrapperWidth*0.05,"bottom":"0"});
     67         if(slideWrapperWidth*0.05>15){
     68             navimgs.height(24);
     69         }
     70         circlewrapper.css({"position":"relative","overflow":"hidden","width":(slideWrapperWidth*0.05*imgcountrealy),"height":slideWrapperWidth*0.04,"margin":"auto"});        
     71         circles.css({'position':"relative","float":"left","max-width":15,"max-height":15,"margin-left":slideWrapperWidth*0.01});
     72         if(slideWrapperWidth*0.03>15){
     73             circler=15;
     74         }else{
     75             circler = slideWrapperWidth*0.03;
     76         }                
     77         circles.attr("width",circler);
     78         circles.attr("height",circler);
     79         canvacircle(0);        
     80         for(var i=0;i<circles.length;i++){
     81             navclick(i);
     82         }    
     83         }else{
     84             navimgs.css({"display":"none"});
     85         }
     86     }        
     87     if(imgcount<4){
     88         return;
     89     }
     90     slideImgWrapper.css({'left':-slideWrapperWidth});
     91     var st;
     92     var sts;
     93     sts = setTimeout(function(){
     94         timedCount();
     95     },timecontrol);    
     96     
     97     slideWrapper.hover(function(){
     98             stopAll();
     99         },
    100         function(){
    101         sts = setTimeout(function(){
    102             timedCount();
    103         },timecontrol);
    104     });
    105     mouseDrag(slideWrapper);
    106     touchDrag(slideWrapper);
    107         
    108     function timedCount()
    109     {
    110         if(direction=='left'){
    111             turnleft();
    112         }if(direction=='right'){
    113             turnright();
    114         }        
    115         clearTimeout(st);
    116         st=setTimeout(function(){
    117             timedCount();        
    118         },timecontrol);
    119     }
    120 
    121     function stopCount()
    122     {
    123         if (st !=""){
    124             clearTimeout(st);
    125         }
    126     }
    127     
    128     function stopAll()
    129     {
    130         stopCount();
    131         clearTimeout(sts);
    132         slideImgWrapper.stop(true);
    133     }
    134     
    135     function navclick(navnum){
    136         circlewrapper.children('canvas:eq('+navnum+')').click(function(e){
    137                 scideimgskip(navnum+1);
    138         })
    139     }
    140     
    141     function scideimgskip(imgnum){
    142         stopAll();
    143         turnleftwidth = imgnum*slideWrapperWidth;
    144         slideImgWrapper.stop(true).animate({left:-turnleftwidth},animatetime,function(){
    145             var imgnum = turnleftwidth/slideWrapperWidth-1;
    146             if(imgnum==0){
    147                 imgnum=imgcountrealy;
    148             }
    149             if((imgnum-imgcountrealy)==0){
    150                 imgnum=0;
    151             }
    152             canvacircle(imgnum);
    153         });    
    154     }
    155     
    156     function canvacircle(canvanum){
    157         circles.attr("width",circler);
    158         circles.attr("height",circler);
    159         for(var i=0;i<circles.length;i++){
    160             if(canvassuport){
    161                 var navCanvas=circles[i];
    162                 var cxt=navCanvas.getContext("2d");
    163                 if(i==canvanum){
    164                     cxt.fillStyle="#0182D7";    
    165                 }else{
    166                     cxt.fillStyle="#ddd";    
    167                 }                
    168                 cxt.arc(circler*0.5,circler*0.5,circler*0.5,0,Math.PI*2,true);
    169                 cxt.closePath();
    170                 cxt.fill(); 
    171             }else{
    172                 circles.css("background","#ddd");                
    173                 circlewrapper.children('canvas:eq('+canvanum+')').css("background","#0182D7");                
    174             }
    175             
    176         }
    177     }
    178     
    179     var turnleftwidth = slideWrapperWidth;
    180     function turnleft(){
    181         turnleftwidth = turnleftwidth+slideWrapperWidth;    
    182         if(turnleftwidth>(imgcount-2)*slideWrapperWidth){        
    183             slideImgWrapper.css({'left':0});
    184             turnleftwidth = slideWrapperWidth;
    185         }
    186         slideImgWrapper.stop(true).animate({left:-turnleftwidth},animatetime,function(){
    187             var imgnum = turnleftwidth/slideWrapperWidth-1;
    188             if(imgnum==0){
    189                 imgnum=imgcountrealy;
    190             }
    191             if((imgnum-imgcountrealy)==0){
    192                 imgnum=0;
    193             }
    194             canvacircle(imgnum);
    195         });                
    196     }
    197     function turnright(){     
    198         turnleftwidth = turnleftwidth-slideWrapperWidth;    
    199         if(turnleftwidth==0){        
    200             slideImgWrapper.css({'left':-slideWrapperWidth*(imgcount-1)});
    201             turnleftwidth = slideWrapperWidth*(imgcount-2);
    202         }
    203         slideImgWrapper.stop(true).animate({left:-turnleftwidth},animatetime,function(){
    204             var imgnum = turnleftwidth/slideWrapperWidth-1;
    205             if(imgnum==0){
    206                 imgnum=imgcountrealy;
    207             }
    208             if((imgnum-imgcountrealy)==0){
    209                 imgnum=0;
    210             }
    211             canvacircle(imgnum);
    212         });                
    213     }
    214     
    215     var distanceX=0;        
    216         
    217     function toLeft(){
    218         if(turnleftwidth>(imgcount-3)*slideWrapperWidth){
    219             slideImgWrapper.css({"left":distanceX});
    220                 turnleftwidth = 0;
    221             }
    222         turnleft(); 
    223         sts = setTimeout(function(){
    224             timedCount();
    225         },timecontrol);    
    226     }    
    227     
    228     function toRight(){
    229         if(turnleftwidth==slideWrapperWidth){
    230             slideImgWrapper.css({'left':-slideWrapperWidth*(imgcount-1)+distanceX});
    231             turnleftwidth = slideWrapperWidth*(imgcount-1);
    232         }
    233         turnright();    
    234         sts = setTimeout(function(){
    235             timedCount();
    236         },timecontrol);        
    237     }
    238         
    239     function mouseDrag($element) {
    240         var eventEle = $element;
    241         var stx = etx = curX = 0;
    242         var MAction = false;
    243         var ahrefs = [];        
    244         for(var i=0;i<slideAs.length;i++){
    245             if(typeof(slideImgWrapper.children('a:eq('+i+')').attr('href'))!=='undefined'){
    246                 ahrefs.push(slideImgWrapper.children('a:eq('+i+')').attr('href'));
    247             }        
    248         }        
    249         eventEle.mouseover(function(){
    250             for(var i=0;i<slideAs.length;i++){
    251                 if(typeof(slideImgWrapper.children('a:eq('+i+')').attr('href'))!=='undefined'){
    252                     slideImgWrapper.children('a:eq('+i+')').attr('href',ahrefs[i]);
    253                 }        
    254             }
    255         });
    256         eventEle.mousemove(function(event){            
    257             if(MAction){
    258             var changeX = event.pageX-stx;    
    259             slideImgWrapper.css({"left":-turnleftwidth+changeX});
    260             distanceX = changeX;
    261             }
    262              event.preventDefault();
    263         }).mousedown(function(event){
    264             stopAll();
    265             MAction = true;
    266             stx = event.pageX;                
    267              event.preventDefault();
    268         });
    269         eventEle.mouseup(function(event){
    270             etx = event.pageX;
    271             curX = etx-stx;
    272             MAction = false;
    273             if(curX>5){
    274                 slideAs.attr("href","javascript:void(0)");
    275                 toRight();
    276             }
    277             if(curX<-5){
    278                 slideAs.attr("href","javascript:void(0)");
    279                 toLeft();
    280             }
    281              event.preventDefault();
    282         });
    283     }
    284     
    285     function touchDrag($element) {
    286         var gundongX = 0;
    287         var gundongY = 0;
    288         var moveEle = $element;
    289         var stx = sty = etx = ety = curX = curY = 0;
    290         
    291         var ImgWidth_arr = [];
    292         for (var i = 0; i < imgcount; i++) {
    293             ImgWidth_arr.push(i * slideWrapperWidth);
    294         }    
    295         
    296         moveEle.on("touchstart", function(event) { //touchstart
    297             stopAll();
    298             var event = event.originalEvent;
    299             gundongX = 0;
    300             gundongY = 0;
    301             // 元素当前位置
    302             etx = parseInt(getT3d(moveEle, "x"));
    303             ety = parseInt(getT3d(moveEle, "y"));
    304             // 手指位置
    305             stx = event.touches[0].pageX;
    306             sty = event.touches[0].pageY;
    307         });
    308         moveEle.on("touchmove", function(event) {
    309             var event = event.originalEvent;
    310             // 防止拖动页面
    311             event.preventDefault();
    312 
    313             // 手指位置 减去 元素当前位置 就是 要移动的距离
    314             gundongX = event.touches[0].pageX - stx;
    315             gundongY = event.touches[0].pageY - sty;
    316 
    317             // 目标位置 就是 要移动的距离 加上 元素当前位置
    318             curX = gundongX + etx;
    319             curY = gundongY + ety;            
    320             slideImgWrapper.css({"left":-turnleftwidth+curX});
    321             distanceX = curX;
    322         });
    323         moveEle.on("touchend", function(event) {
    324             //alert(gundongX);
    325          if(Math.abs(gundongX)>5){
    326             event.preventDefault();
    327             
    328            // 手指接触屏幕的位置
    329             var oriX = etx;
    330             var oriY = ety;
    331             // 手指离开屏幕的位置
    332             etx = curX;
    333             ety = curY;
    334             var slidePosition = 0;
    335             for (var i = 0; i < imgcount - 1; i++) {
    336                 if (Math.abs(etx) > ImgWidth_arr[i]) {
    337 
    338                     if (oriX > etx) {
    339                         // 左滑
    340                         toLeft();
    341                     } else {
    342                         // 右滑
    343                         toRight();                
    344                    }
    345                 }
    346             }
    347          }
    348             
    349          });
    350 
    351         function getT3d(elem, ename) {
    352             var elem = elem[0];
    353             var str1 = elem.style.webkitTransform;
    354             if (str1 == "") return "0";
    355             str1 = str1.replace("translate3d(", "");
    356             str1 = str1.replace(")", "");
    357             var carr = str1.split(",");
    358 
    359             if (ename == "x") return carr[0];
    360             else if (ename == "y") return carr[1];
    361             else if (ename == "z") return carr[2];
    362             else return "";
    363         }
    364     }
    365 }); 
    366 }; 
    367 })(jQuery); 
    View Code

     在线演示

    3.整体思路

    a.创建显示窗口,显示容器大小位置自定义;

    b.创立图片容器,通过改变图片容器的位置来改变显示窗口中展示的图片。

      难点在于如何改变图片容器位置来显示需要的图片和无缝轮播。可以想象一下以前的胶带式电影,如果放映速度慢下来就跟图片轮播类似了。所以可以把图片容器看成胶带,图片就是其中的一帧图像,显示窗口就是电影屏幕。

      如果以一个显示窗口的宽为一个单位,我们把图片水平排放在图片容器中,每张图片恰好占用一个显示窗口的宽高,有多少张图片,图片容器的宽就为多少个单位宽。然后使图片向左移动一个单位的距离,就可以展示下一张图片了。为了使图片展示效果更美观,我用了jquery的动画效果animate()来改变图片容器的位置。如果设定间隔多少时间图片容器左移一个单位,达到最后一张图片时,图片容器恢复到原始位置,进行下一轮移动。这样,就可以实现图片的水平轮播了。至于无缝轮播,我采取的做法是把前两张图片复制一份,放到所有图片的最后面。首次显示第二张图片,当移动到倒数第二张图片时,在下一次移动时先改变容器的left,让第一张图片被显示出来,因为这个动作很快,看起来好像并没有进行任何操作(达到欺骗眼球的效果,呵呵),然后使用animate显示第二张图片,在视觉上实现无缝轮播。从第二张图片右移时也与此类似。这样做的主要目的是为了确保左右都有能被展示的图片,确保不会显示空白,以实现无缝切换。这里,会用到的主要知识点有:

      (1).setTimeout和clearTimeout:

      用于延迟执行、循环执行和终止循环。setTimeout延迟执行确定图片的显示时间,循环执行为了自动展示下一张图片。当需要停止轮播的时候就可以用clearTimeout来终止循环了。关于setTimeout和clearTimeout的具体用法,可以参照代码,这里就不再赘述了。

      (2).jquery选择器:

      无需多说,所有jquery动作的基础。

      (3).jquery操作css:

      为了保证使用的简单性,只需确定显示容器的样式(需确保overflow:hidden;插件中已设置),其子元素包括图片容器(这里只支持div标签slideWrapper.children('div:eq(0)'))和图片及其链接的样式都在插件中确定,包括:保证图片水平排列,大小恰好为显示窗口的大小;确定图片容器的大小恰好容下所有图片。

      (4).jquery添加元素insertAfter:

      复制前两张图片到所有图片的最后面$((slideImgWrapper.html().split("/div>")[0]+"/div>"+slideImgWrapper.html().split("/div>")[1]+"/div>")).insertAfter(slideAWra.last())。

      (5).jquery动画效果animate: 

     1 var turnleftwidth = slideWrapperWidth;
     2     function turnleft(){
     3         turnleftwidth = turnleftwidth+slideWrapperWidth;    
     4         if(turnleftwidth>(imgcount-2)*slideWrapperWidth){        
     5             slideImgWrapper.css({'left':0});
     6             turnleftwidth = slideWrapperWidth;
     7         }
     8         slideImgWrapper.stop(true).animate({left:-turnleftwidth},animatetime);                
    18     }
    19     function turnright(){     
    20         turnleftwidth = turnleftwidth-slideWrapperWidth;    
    21         if(turnleftwidth==0){        
    22             slideImgWrapper.css({'left':-slideWrapperWidth*(imgcount-1)});
    23             turnleftwidth = slideWrapperWidth*(imgcount-2);
    24         }
    25         slideImgWrapper.stop(true).animate({left:-turnleftwidth},animatetime);                
    35     }

      其中imgcount为进行图片复制后图片的元素个数,slideWrapperWidth为显示窗口的宽。 turnleft()用于无缝左移,turnright()用于无缝右移。

      现在来说说触屏支持。主要是用了jquery的on方法监听touch事件。具体怎么写,无非就是设置初始触摸位置,然后监听滑动的位置,根据水平滑动的具体实时改变图片容器的left,实现拖拽的效果。滑动结束后根据结束时的位置与初始位置的差判断左滑还是右滑,再来改变图片容器的left,使图片正好居中显示。跟PC端的鼠标拖拽类似。说到鼠标拖拽,不得不喷俩句。一般拖拽元素,基本都是mousedown、mousemove、mouseup三部曲。但是碰上图片就头疼了,特别是这图片的父亲还是a标签。mousedown没问题,mousemove能一个三五步,mousemove出问题mouseup也就失效了。弄了半天,终于通过 event.preventDefault()实现了对大部分浏览器的支持。废话不多说,让大家一起纠结下。

     1 <!DOCTYPE html>
     2 <html xmlns="http://www.w3.org/1999/xhtml" lang="UTF-8">
     3 <head>
     4 <meta charset="UTF-8">
     5 <style>
     6     body{
     7         overflow-x:hidden;
     8         margin:0 auto;
     9         padding:0;
    10         width: 100%;
    11         height: 100%;
    12     }
    13     .aWrapper{            
    14         position: relative;
    15         margin:0 auto;
    16         width:400px;
    17         height:600px;
    18         overflow:hidden;
    19         //float:left;
    20     }
    21     .testa{            
    22         position: relative;
    23         margin:0 auto;
    24         width:400px;
    25         height:600px;
    26         //float:left;
    27     }
    28     .testimg{            
    29         position: absolute;
    30         width:400px;
    31         height:600px;
    32         z-index:0;
    33     }
    34     .imgmask{            
    35         position: relative;
    36         width:400px;
    37         height:600px;
    38         z-index:1;
    39         opacity:0.2;
    40         background:#333;
    41     }
    42 </style>
    43 </head>
    44 <body>
    45     <div  class="aWrapper">
    46     <a href="http://www.baidu.com"  class="testa">
    47         <img src="http://sandbox.runjs.cn/uploads/rs/215/auboqjjr/1 (1).jpg" class="testimg"/>
    48         <div class='imgmask'></div>
    49     </a>
    50     </div>
    51 </body>
    52 </html>

      上面测试页面只有在Safari内核的浏览器(如Chrome)下才能够拖拽的,而且当图片遮罩层的position设置为absolute或者a标签设置float时都会失效,实在是搞不明白。而且要说一下可以很容易的阻止事件向上冒泡,有什么办法触发父元素事件是不要触发子元素的该事件么?还是以上面的测试页面为例,要拖拽aWrapper的div,就要设置该元素的mousedown、mousemove、mouseup事件。但是这里有一个问题,在mousedown和mouseup之后会触发click事件,导致触发子元素a标签的click而跳转页面。如果仅仅在mouseup时设置a标签的click返回false,那么这个链接就永远失效了。具体处理方法,大家还是看代码吧,反正被我搞得复杂得很,说多了都是泪。

      最后说说这个导航栏,就是下面的方方圈圈,用来显示第几张和点击跳转的。如果直接在页面上编写,问题倒还简单。在JS中就复杂多了。为了确保插件的独立性,除了对jquery的依赖外,我不想它有任何其他依赖。所以一般用图片来表示状态的方法就行不通了。我用的是html5的canvas绘制圆形。如果浏览器不支持或者担心浏览器消耗的话,可以关闭掉,直接用背景色表示,只是只能为方块块了。反正我觉得我自己弄的既不美观又不优雅,大家就当参照吧。

      

  • 相关阅读:
    PHP中pack、unpack的详细用法
    Rbac
    composer
    tp5+workman
    apache
    Vs2005安装后没有模板的解决方法
    java中使用mysqldump 备份数据库
    java中文件上传下载将file转为MultipartFile
    hibernate中的schema
    Java之 1.8新特性
  • 原文地址:https://www.cnblogs.com/crookie/p/3776670.html
Copyright © 2011-2022 走看看