原生JS使用Canvas实现拖拽式绘图功能


Posted in Javascript onJune 05, 2019

一、实现的功能

1、基于oop思想构建,支持坐标点、线条(由坐标点组成,包含方向)、多边形(由多个坐标点组成)、圆形(包含圆心坐标点和半径)等实体

2、原生JavaScript实现,不依赖任何第三方js库和插件

3、多图形绘制(支持画笔、线条、箭头、三角形、矩形、平行四边形、梯形以及多边形和圆形绘制)

4、拖拽式绘制(鼠标移动过程中不断进行canvas重绘)

5、图片绘制(作为背景图片时重绘会发生闪烁现象,暂时有点问题,后面继续完善)

5、清空绘制功能

6、新版本优化绘制性能(使用共享坐标变量数组,减少了大量的对象创建操作)

7、新版本支持箭头绘制功能

二、完整实现代码

DrawingTools =(function(){
//公共方法
      var getDom=function(id){return document.getElementById(id)};
      var isNull=function(s){return s==undefined||typeof(s)=='undefined'||s==null||s=='null'||s==''||s.length<1};
      var hideDefRM=function(){document.oncontextmenu=function(){return false}};//屏蔽浏览器默认鼠标事件
      /**绘图容器*/
      var cbtCanvas;
      /**绘图对象*/
      var cxt;
      /**绘制的图形列表*/
      var shapes=new Array();
      var graphkind={'cursor':0,'pen':1,'line':2,'trian':3,'rect':4,'poly':5,'circle':6,'arrow':21,'parallel':41,'trapezoid':42};
      //背景图片绘制配置
      var bgPictureConfig={
        pic:null,//背景图片地址或路径
        repaint:true,//是否作为永久背景图,每次清除时会进行重绘
      };
      //加载并绘制图片(src:图片路径或地址),默认重绘背景图
      var loadPicture=function(src){
        if(isNull(bgPictureConfig.repaint)||bgPictureConfig.repaint){bgPictureConfig.pic=src}
        var img = new Image();
        img.onload = function(){cxt.drawImage(img,0,0)}
        img.src =src;
      }
      //绘图基础配置
      var paintConfig={lineWidth:1,//线条宽度,默认1
        strokeStyle:'red',//画笔颜色,默认红色
        fillStyle:'red',//填充色
        lineJoin:"round",//线条交角样式,默认圆角
        lineCap:"round",//线条结束样式,默认圆角
      };
      //重新载入绘制样式
      var resetStyle=function(){
        cxt.strokeStyle=paintConfig.strokeStyle;
        cxt.lineWidth=paintConfig.lineWidth;
        cxt.lineJoin=paintConfig.lineJoin;
        cxt.lineCap=paintConfig.lineCap;
        cxt.fillStyle=paintConfig.fillStyle;
      }
      //鼠标图形
      var cursors=['crosshair','pointer'];
      /** 切换鼠标样式*/
      var switchCorser=function(b){
        cbtCanvas.style.cursor=((isNull(b)?isDrawing():b)?cursors[0]:cursors[1]);
      }
      //操作控制变量组
      var ctrlConfig={
        kind:0,//当前绘画分类
        isPainting:false,//是否开始绘制
        startPoint:null,//起始点
        cuGraph:null,//当前绘制的图像
        cuPoint:null,//当前临时坐标点,确定一个坐标点后重新构建
        cuAngle:null,//当前箭头角度
        vertex:[],//坐标点
      }
      /**获取当前坐标点*/
      var getCuPoint=function(i){
        return ctrlConfig.cuPoint[i];
      }
      /**设置当前坐标点*/
      var setCuPoint=function(p,i){
        return ctrlConfig.cuPoint[i]=p;
      }
      /**设置当前临时坐标点值*/
      var setCuPointXY=function(x,y,i){
        if(isNull(ctrlConfig.cuPoint)){
          var arr=new Array();
          arr[i]=new Point(x,y);
          ctrlConfig.cuPoint=arr;
        }else if(isNull(ctrlConfig.cuPoint[i])){
          setCuPoint(new Point(x,y),i);
        }else{
          ctrlConfig.cuPoint[i].setXY(x,y);
        }
        return getCuPoint(i);
      }
      /**是否正在绘制*/
      var isDrawing=function (){
        return ctrlConfig.isPainting;
      }
      /**开始绘制状态*/
      var beginDrawing=function(){
        ctrlConfig.isPainting=true;
      }
      /**结束绘制状态*/
      var stopDrawing=function(){
        ctrlConfig.isPainting=false;
      }
      /**是否有开始坐标点*/
      var hasStartPoint=function(){
        return !isNull(ctrlConfig.startPoint);
      }
      /**设置当前绘制的图形*/
      var setCuGraph=function(g){
        ctrlConfig.cuGraph=g;
      }
      /**获取当前绘制的图形*/
      var getCuGraph=function(){
        return ctrlConfig.cuGraph;
      }
      /**设置开始坐标点(线条的起始点,三角形的顶点,圆形的圆心,四边形的左上角或右下角,多边形的起始点)*/
      var setStartPoint=function(p){
        ctrlConfig.startPoint=p;
      }
      /**获取开始坐标点*/
      var getStartPoint=function(){
        return ctrlConfig.startPoint;
      }
      /**清空全部*/
      var clearAll=function(){
        cxt.clearRect(0,0,cbtCanvas.width,cbtCanvas.height);
      }
      /**重绘*/
      var repaint=function(){
        clearAll();
        /*
        if(bgPictureConfig.repaint){
          loadPicture(bgPictureConfig.pic);
        }*/
      }
      /**点(坐标,绘图的基本要素,包含x,y坐标)*/
      var Point=(function(x1,y1){
        var x=x1,y=y1;
        return{
          set:function(p){
            x=p.x,y=p.y;
          },
          setXY:function(x2,y2){
            x=x2;y=y2;
          },
          setX:function(x3){
            x=x3;
          },
          setY:function(y3){
            y=y3;
          },
          getX:function(){
            return x;
          },
          getY:function(){
            return y;
          }
        }
      });
      /**多角形(三角形、矩形、多边形),由多个点组成*/
      var Poly=(function(ps1){
        var ps=isNull(ps1)?new Array():ps1;
        var size=ps.length;
        return{
          set:function(ps2){
            ps=ps2;
          },
          getSize:function(){
            return size;
          },
          setPoint:function(p,i){
            if(isNull(p)&&isNaN(i)){
              return;
            }
            ps[i]=p;
          },
          setStart:function(p1){
            if(isNull(ps)){
              ps=new Array();
              return ps.push(p1);
            }else{
              ps[0]=p1;
            }
          },
          add:function(p){
            if(isNull(ps)){
              ps=new Array();
            }
            return ps.push(p);
          },
          pop:function(){
            if(isNull(ps)){
              return;
            }
            return ps.pop();
          },
          shift:function(){
            if(isNull(ps)){
              return;
            }
            return ps.shift;
          },
          get:function(){
            if(isNull(ps)){
              return null;
            }
            return ps;
          },
          draw:function(){
            cxt.beginPath();
            for(i in ps){
              if(i==0){
                cxt.moveTo(ps[i].getX(),ps[i].getY());
              }else{
                cxt.lineTo(ps[i].getX(),ps[i].getY());
              }
            }
            cxt.closePath();
            cxt.stroke();
          }
        }
      });
      /*线条(由两个点组成,包含方向)*/
      var Line=(function(p1,p2,al){
        var start=p1,end=p2,angle=al;
        var drawLine=function(){
          cxt.beginPath();
          cxt.moveTo(p1.getX(),p1.getY());
          cxt.lineTo(p2.getX(),p2.getY());
          cxt.stroke();
        }
        //画箭头
        var drawArrow=function() {
          var vertex =ctrlConfig.vertex;
          var x1=p1.getX(),y1=p1.getY(),x2=p2.getX(),y2=p2.getY();
          var el=50,al=15;
          //计算箭头底边两个点(开始点,结束点,两边角度,箭头角度)
          vertex[0] = x1,vertex[1] = y1, vertex[6] = x2,vertex[7] = y2;
          //计算起点坐标与X轴之间的夹角角度值
          var angle = Math.atan2(y2 - y1, x2 - x1) / Math.PI * 180;
          var x = x2 - x1,y = y2 - y1,length = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
          if (length < 250) {
            el/=2,al/2;
          }else if(length<500){
            el*=length/500,al*=length/500;
          }
          vertex[8] = x2 - el * Math.cos(Math.PI / 180 * (angle + al));
          vertex[9] = y2- el * Math.sin(Math.PI / 180 * (angle + al));
          vertex[4] = x2- el* Math.cos(Math.PI / 180 * (angle - al));
          vertex[5] = y2 - el * Math.sin(Math.PI / 180 * (angle - al));
          //获取另外两个顶点坐标
          x=(vertex[4]+vertex[8])/2,y=(vertex[5]+vertex[9])/2;
          vertex[2] = (vertex[4] + x) / 2;
          vertex[3] = (vertex[5] + y) / 2;
          vertex[10] = (vertex[8] +x) / 2;
          vertex[11] = (vertex[9] +y) / 2;
          //计算完成,开始绘制
          cxt.beginPath();
          cxt.moveTo(vertex[0], vertex[1]);
          cxt.lineTo(vertex[2], vertex[3]);
          cxt.lineTo(vertex[4], vertex[5]);
          cxt.lineTo(vertex[6], vertex[7]);
          cxt.lineTo(vertex[8], vertex[9]);
          cxt.lineTo(vertex[10], vertex[11]);
          cxt.closePath();
          cxt.fill();
          cxt.stroke();
        }
        return{
          setStart:function(s){
            start=s;
          },
          setEnd:function(e){
            end=e;
          },
          getStart:function(){
            return start;
          },
          getEnd:function(){
            return end;
          },
          draw:function(){
            if(angle){
              drawArrow();
            }else{
              drawLine();
            }
          }
        }
      });
      /**圆形(包含圆心点和半径)*/
      var Circle=(function(arr){
        //包含起始点(圆心)和结束点,以及圆半径
        var startPoint=arr.start,endPoint=arr.end,radius=arr.radius;
        /*绘制圆*/
        var drawCircle=function(){
          cxt.beginPath();
          var x=startPoint.getX();
          var y=startPoint.getY();
          if(isNull(radius)){
            radius=calculateRadius(startPoint,endPoint);
          }
          //x,y,半径,开始点,结束点,顺时针/逆时针
          cxt.arc(x,y,radius,0,Math.PI*2,false); // 绘制圆
          cxt.stroke();
        }
        //计算圆半径
        var calculateRadius=function(p1,p2){
          var width=p2.getX()-p1.getX();
          var height=p2.getY()-p1.getY();
          //如果是负数
          if(width<0||height<0){
            width=Math.abs(width);
          }
          //计算两点距离=平方根(width^2+height^2)
          c=Math.sqrt(Math.pow(width,2)+Math.pow(height,2));
          return c;
        }
        return{
          set:function(params){
            startPoint=params.start;
            endPoint=params.end;
            radius=params.radius;
          },
          setPoint:function(p1){
            p=p1;
          },
          getPoint:function(){
            return p;
          },
          setRadius:function(r1){
            radius=r1;
          },
          getRadius:function(){
            return radius;
          },
          calcRadius:calculateRadius,
          //绘制
          draw:drawCircle,
        }
      });
      /**绘制线条工具方法*/
      var drawLine=function(p){
        cxt.beginPath();
        cxt.moveTo(startPosition.getX(),startPosition.getY());
        cxt.lineTo(p.getX(),p.getY());
        cxt.stroke();
      }
      /**绘制三角形工具方法*/
      var drawTrian=function(ps){
        cxt.beginPath();
        var a=ps.get();
        cxt.moveTo(a[0].getX(),a[0].getY());
        cxt.lineTo(a[1].getX(),a[1].getY());
        cxt.lineTo(a[2].getX(),a[2].getY());
        cxt.closePath();
        cxt.stroke();
      }
      /**绘制矩形工具方法*/
      var drawRect=function(p2){
        var p=getStartPoint();
        var width=p.getX()-p2.getX();
        var height=p.getY()-p2.getY();
        cxt.beginPath();
        cxt.strokeRect(x,y,width,height);//绘制矩形
      }
      /*绘制多边形工具方法*/
      var drawpolygon=function(ps){
        if(ps.length>1){//保证只有两个坐标点才是矩形
          cxt.beginPath();
          var p=ctrlConfig.startPoint;
          var x=p.getX();
          var y=p.getY();
          cxt.moveTo(x,y);
          for(p1 in ps){
            cxt.lineTo(p1.getX(),p1.getY());
          }
          cxt.stroke();
        }
      }
      /*绘制圆角矩形工具方法*/
      var drawRoundedRect=function(x,y,width,height,radius){
        cxt.beginPath();
        cxt.moveTo(x,y+radius);
        cxt.lineTo(x,y+height-radius);
        cxt.quadraticCurveTo(x,y+height,x+radius,y+height);
        cxt.lineTo(x+width-radius,y+height);
        cxt.quadraticCurveTo(x+width,y+height,x+width,y+height-radius);
        cxt.lineTo(x+width,y+radius);
        cxt.quadraticCurveTo(x+width,y,x+width-radius,y);
        cxt.lineTo(x+radius,y);
        cxt.quadraticCurveTo(x,y,x,y+radius);
        cxt.stroke();
      }
      /*绘制圆工具方法*/
      var drawCircle=function(c){
        var p=c.getPoint();//坐标点
        var x=p.getX();
        var y=p.getY();
        var r=c.getRadius();
        cxt.beginPath();
        //x,y,半径,开始点,结束点,顺时针/逆时针
        cxt.arc(x,y,r,0,Math.PI*2,false); // 绘制圆
        cxt.stroke();
      }
      //计算圆半径工具方法
      var calculateRadius=function(p1,p2){
        var width=p2.getX()-p1.getX();
        var height=p2.getY()-p1.getY();
        //如果是负数
        if(width<0||height<0){
          width=Math.abs(width);
        }
        //计算两点距离=平方根(width^2+height^2)
        c=Math.sqrt(Math.pow(width,2)+Math.pow(height,2));
        return c;
      }
      //鼠标按键点击(首次点击确定开始坐标点,拖动鼠标不断进行图形重绘)
      var mouseDown = function(e){
        var btnNum = e.button;
        if(btnNum==0){
          console.log("选择:"+ctrlConfig.kind);
          //设置起始点
          switch(ctrlConfig.kind){
            case graphkind.pen://画笔(不松开鼠标按键一直画)
              beginDrawing();//开始绘制
              cxt.beginPath();
              cxt.moveTo(e.offsetX,e.offsetY);
              break;
            case graphkind.poly://多边形
              var p=new Point(e.offsetX,e.offsetY);
              if(isDrawing()){
                getCuGraph().add(p);//添加到
              }else{//第一次确定开始坐标
                beginDrawing();//开始绘制
                setStartPoint(p);
                var poly=new Poly();
                poly.add(p);
                setCuGraph(poly);//设置当前绘制图形
              }
              break;
            case graphkind.line://线条
            case graphkind.arrow://方向
            case graphkind.trian://三角形
            case graphkind.rect://矩形
            case graphkind.parallel://平行四边形
            case graphkind.trapezoid://梯形
              beginDrawing();//开始绘制
              var p=new Point(e.offsetX,e.offsetY);
              setStartPoint(p);
              var poly=new Poly();
              poly.add(p);
              setCuGraph(poly);//设置当前绘制图形
              break;
            case graphkind.circle://圆
              console.log("确定图形绘制开始坐标点:"+e.offsetX+","+e.offsetY);//点击确定图形的开始坐标点
              beginDrawing();//开始绘制
              var p=new Point(e.offsetX,e.offsetY);
              setStartPoint(p);
              var circle= new Circle({'start':p});
              setCuGraph(circle);
              break;
            case ctrlConfig.cursor: //手型鼠标
            default://默认是手型鼠标,不允许绘制
          }
        }else if(btnNum==2){
          console.log("右键由于结束多边形绘制");
          if(isDrawing()){
            if(ctrlConfig.kind==graphkind.poly){
              repaint();
              getCuGraph().draw();
              stopDrawing();//结束绘制
            }
          }
        }
        hideDefRM();//屏蔽浏览器默认事件
      }
      //鼠标移动(拖动,根据鼠标移动的位置不断重绘图形)
      var mouseMove = function(e){
        if(isDrawing()&&hasStartPoint()){//检查是否开始绘制,检查是否有开始坐标点
          //画笔不需要重绘
          if(ctrlConfig.kind>1){
            repaint();//重绘
          }
          var p=setCuPointXY(e.offsetX,e.offsetY,0);//设置共享的临时坐标点,用于防止重复创建对象
          switch(ctrlConfig.kind){
            case graphkind.pen://画笔(一直画)
              cxt.lineTo(e.offsetX,e.offsetY);
              cxt.stroke();
              break;
            case graphkind.poly://多边形
              var poly=getCuGraph(poly);
              var size=poly.getSize();
              poly.setPoint(p,(size-1));
              poly.draw();
              break;
            case graphkind.line://线条
              var line=new Line(getStartPoint(),p,false);
              ctrlConfig.cuGraph=line;
              line.draw();
              break;
            case graphkind.arrow://方向
              var line=new Line(getStartPoint(),p,true);
              ctrlConfig.cuGraph=line;
              line.draw();
              break;
            case graphkind.trian://三角形
              var lu=getStartPoint();
              var x2=p.getX();
              var x1=lu.getX();
              //三角形左边的点坐标计算方法:(x1-(x2-x1),y2)
              var x3=x1-(x2-x1);
              var l=setCuPointXY(x3,p.getY(),1);//设置共享的临时坐标点,用于防止重复创建对象
              var poly=getCuGraph();//获取当前图形
              poly.set([lu,p,l]);
              poly.draw();//即时绘制
              break;
            case graphkind.parallel://平行四边形
              var lu=getStartPoint();
              var x3=p.getX();
              var x1=lu.getX();
              //平行四边形两个未知坐标点计算方法:(x1-(x3-x1),y3),(x1+(x3-x1),y1)
              var x2=x3+(x3-x1);
              var x4=x1-(x3-x1);
              var ld=setCuPointXY(x2,lu.getY(),1);//设置共享的临时坐标点,用于防止重复创建对象
              var ru=setCuPointXY(x4,p.getY(),2);//设置共享的临时坐标点,用于防止重复创建对象
              var poly=getCuGraph();//获取当前图形
              poly.set([lu,ru,p,ld]);
              poly.draw();//即时绘制
              break;
            case graphkind.trapezoid://梯形
              var lu=getStartPoint();
              var x3=p.getX();
              var x1=lu.getX();
              //梯形两个未知坐标点计算方法:(x3-(x3-x1)/2,y1),(x1-(x3-x1)/2,y3)
              var x2=x3-(x3-x1)/2;
              var x4=x1-(x3-x1)/2;
              var ld=setCuPointXY(x2,lu.getY(),1);
              var ru=setCuPointXY(x4,p.getY(),2);
              var poly=getCuGraph();
              poly.set([lu,ru,p,ld]);
              poly.draw();
              break;
            case graphkind.rect://矩形
              var lu=getStartPoint();
              //矩形右上角和左上角坐标计算方法
              var ld=setCuPointXY(lu.getX(),p.getY(),1);
              var ru=setCuPointXY(p.getX(),lu.getY(),2);
              var poly=getCuGraph();
              poly.set([lu,ru,p,ld]);
              poly.draw();
              break;
            case graphkind.circle://圆
              var circle=getCuGraph();//获取当前图形
              circle.set({'start':getStartPoint(),'end':p});
              circle.draw();//即时绘制
              break;
          }
        }
      }
      //鼠标按键松开
      var mouseUp = function(e){
        if(isDrawing()){
          //console.log("松开鼠标按键:"+e.offsetX+","+e.offsetY);
          //画笔不需要重绘
          if(ctrlConfig.kind>1){
            repaint();
            getCuGraph().draw();
          }
          if(ctrlConfig.kind!=graphkind.poly){//多边形绘制鼠标按键松开不结束绘制,多边形只有右键点击才能结束绘制
            stopDrawing();//结束绘制
          }
        }
      }
      //鼠标移出
      var mouseOut = function(e){
        console.log("鼠标移出绘制区域"+e.offsetX+","+e.offsetY);
        if(isDrawing()){
          console.log("停止绘制");
          if(ctrlConfig.kind>1){
            repaint();
            getCuGraph().draw();
          }
          stopDrawing();//停止绘制
        }
      }
      return{
        isNull:isNull,
        getDom:getDom,
        clear:function(){
          stopDrawing();//停止绘制
          repaint();
        },
        /**初始化*/
        init:function(params){
          cbtCanvas=getDom(params.id);
          //浏览器是否支持Canvas
          if (cbtCanvas.getContext){
            /**绘图对象*/
            cxt=cbtCanvas.getContext("2d");
            cbtCanvas.onmousedown = mouseDown;
            cbtCanvas.onmouseup = mouseUp;
            cbtCanvas.onmousemove = mouseMove;
            cbtCanvas.onmouseout = mouseOut;
            resetStyle();//载入样式
            return true;
          }else{
            return false;
          }
        },
        /**设置背景图片*/
        setBgPic:loadPicture,
        /**选择图形类型*/
        begin:function(k){
          console.log("选择绘制图形:"+k);
          if(isNaN(k)){//如果不是数字,先转换为对应字符
            ctrlConfig.kind=kind[k];
          }else{
            ctrlConfig.kind=k;
          }
          switchCorser(true);//切换鼠标样式
        },
        /*手型,并停止绘图*/
        hand:function(){
          ctrlConfig.kind=0;
          stopDrawing();//停止绘制
          switchCorser(false);//切换鼠标样式
        }
      }
    })

三、使用方式

1、图形类型

0:鼠标,1:画笔,2:线条,3:三角形,4:矩形,5:多边形,6:圆形,21:箭头,41:平行四边形,42:梯形

var graphkind={'cursor':0,'pen':1,'line':2,'trian':3,'rect':4,'poly':5,'circle':6,'arrow':21,'parallel':41,'trapezoid':42};

2、初始化以及使用背景图片和画笔选择

var drawUtil=new DrawingTools();
//初始化,(如果浏览器不支持H5,会初始化失败,返回false)
if(drawUtil.init({'id':'calibrationCanvas'})){
//加载图片
var imgsrc='图片地址';
if(!drawUtil.isNull(imgsrc)){
  drawUtil.setBgPic(imgsrc,true);//设置背景图片(异步加载图片)
}
}
drawUtil.begin(1);//选择画笔

2、绘制箭头

drawUtil.begin(21);

总结

以上所述是小编给大家介绍的原生JS使用Canvas实现拖拽式绘图功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
用Javascript数组处理多个字符串的连接问题
Aug 20 Javascript
javascript 语法基础 想学习js的朋友可以看看
Dec 16 Javascript
Jquery replace 字符替换实现代码
Dec 02 Javascript
js获取指定日期周数以及星期几的小例子
Jun 27 Javascript
使用JS获取当前地理位置方法汇总
Dec 18 Javascript
javascript bom是什么及bom和dom的区别
Nov 26 Javascript
jQuery实现摸拟alert提示框
May 22 Javascript
jQuery下拉框的简单应用
Jun 24 Javascript
bootstrap多种样式进度条展示
Dec 20 Javascript
vue拦截器实现统一token,并兼容IE9验证功能
Apr 26 Javascript
layui复选框限制选择个数的方法
Sep 18 Javascript
vue.js实现二级菜单效果
Oct 19 Javascript
Node.js 路由的实现方法
Jun 05 #Javascript
JS实现动态添加外部js、css到head标签的方法
Jun 05 #Javascript
JS函数动态传递参数的方法分析【基于arguments对象】
Jun 05 #Javascript
jQuery操作cookie的示例代码
Jun 05 #jQuery
JS实现从对象获取对象中单个键值的方法示例
Jun 05 #Javascript
微信小程序如何实现全局重新加载
Jun 05 #Javascript
JS数组Object.keys()方法的使用示例
Jun 05 #Javascript
You might like
JAVA/JSP学习系列之二
2006/10/09 PHP
PHP的fsockopen、pfsockopen函数被主机商禁用的解决办法
2014/07/08 PHP
整理php防注入和XSS攻击通用过滤
2015/09/13 PHP
PHP文件缓存类实现代码
2015/10/26 PHP
2017年最好用的9个php开发工具推荐(超好用)
2017/10/23 PHP
用户注册常用javascript代码
2009/08/29 Javascript
extjs中grid中嵌入动态combobox的应用
2011/01/01 Javascript
如何用jQuery实现ASP.NET GridView折叠伸展效果
2015/09/26 Javascript
如何实现JavaScript动态加载CSS和JS文件
2020/12/28 Javascript
JS实现网页每隔3秒弹出一次对话框的方法
2015/11/09 Javascript
JavaScript对象数组排序实例方法浅析
2016/06/15 Javascript
JavaScript实现移动端滑动选择日期功能
2016/06/21 Javascript
深入理解JavaScript中的块级作用域、私有变量与模块模式
2016/10/31 Javascript
Node学习记录之cluster模块
2017/05/31 Javascript
[原创]js实现保存文本框内容为本地文件兼容IE,chrome,火狐浏览器
2018/02/14 Javascript
JS实现点击按钮随机生成可拖动的不同颜色块示例
2019/01/30 Javascript
微信小程序嵌入腾讯视频源过程详解
2019/08/08 Javascript
javascript二维数组和对象的深拷贝与浅拷贝实例分析
2019/10/26 Javascript
多页vue应用的单页面打包方法(内含打包模式的应用)
2020/06/11 Javascript
在vue中使用回调函数,this调用无效的解决
2020/08/11 Javascript
[08:44]DOTA2发布会群星聚首 我们都是刀塔人
2014/03/21 DOTA
浅谈python中的正则表达式(re模块)
2017/10/17 Python
python+matplotlib实现鼠标移动三角形高亮及索引显示
2018/01/15 Python
Python堆排序原理与实现方法详解
2018/05/11 Python
Python闭包和装饰器用法实例详解
2019/05/22 Python
对Python 检查文件名是否规范的实例详解
2019/06/10 Python
win10安装tensorflow-gpu1.8.0详细完整步骤
2020/01/20 Python
Python生成器常见问题及解决方案
2020/03/21 Python
基于Python实现2种反转链表方法代码实例
2020/07/06 Python
python不同版本的_new_不同点总结
2020/12/09 Python
html5应用缓存_动力节点Java学院整理
2017/07/13 HTML / CSS
俄罗斯和世界各地的酒店预订:Hotels.com俄罗斯
2016/08/19 全球购物
一些Solaris面试题
2013/03/22 面试题
安全责任书范文
2014/03/12 职场文书
2014年财务部工作总结
2014/11/11 职场文书
小学生暑假安全保证书
2015/07/13 职场文书