百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

JQ实现拖动选择时间段(jquery拖动div)

toyiye 2024-07-06 00:37 17 浏览 0 评论

示例简介

本文介绍利用JQ实现拖动选择时间段的示例,该实例可默认显示设置的时间段、可拖动多个时间段、可伸缩时间段、可合并时间段并能导出所有时间段的详细信息,效果如下:

实现过程

1、先实现页面效果,文件*.html和*.css代码如下:

Tips:css代码联合效果比较好理解。

<!DOCTYPE html>
<html>


<head>
  <meta charset="utf-8" />
  <title>拖动选择时间段</title>
  <link rel="stylesheet" type="text/css" href="css/style.css" />
</head>


<body>
  <div class="kaoqing" id="demo1"></div>
  <button id="getdata">获得数据</button>
  <div id="answer"></div>
  <script src="js/jquery-1.9.1.min.js"></script>
  <script src="js/drag.js"></script>
  <script>
  $(function() {
    // 开始时间和结束时间的日期应该是同一天,不支持跨天,
    // 日期格式要标准,yyyy-MM-dd hh:mm:ss
    // 已选择的时间段
    var data3 = [{
      startime: '2020-10-19 01:30:00',
      endtime: '2020-10-19 02:00:00'
    }, {
      startime: '2020-10-19 16:30:00',
      endtime: '2020-10-19 20:30:00'
    }];
    // data3 = [];
    var juicy = $("#demo1").initJuicy({
      height: 650,
      mondayDate: '2020-10-19',
      timedata: data3,
      status: true, //false表示不能编辑,true可以编辑
    });
    $("#getdata").click(function() {
      var backdata = juicy.getdata();
      $("#answer").html(JSON.stringify(backdata))
    })
  })
</script>
</body>


</html>
/*拖动时间段*/
.bar {
  background-color: #fff;
  border: 1px solid #555;
  position: relative;
  height: 601px;
  width: 770px;
  float: right;
}


/*刻度*/
.day {
  position: relative;
  height: 600px;
  box-sizing: border-box;
  width: 20px;
  float: left;
}


.day .hour {
  position: absolute;
  border-top: 1px solid red;
  width: 20px;
}


.day .halfhour {
  position: absolute;
  border-top: 1px solid #555;
  height: 7px;
  width: 20px;
  top: 12px;
}


.day .hour:after {
  position: absolute;
  top: 0;
  font: 11px/1 sans-serif;
}


.day .hour:nth-of-type(1):after {
  content: "0";
}


.day .hour:nth-of-type(2):after {
  content: "1";
}


.day .hour:nth-of-type(3):after {
  content: "2";
}


.day .hour:nth-of-type(4):after {
  content: "3";
}


.day .hour:nth-of-type(5):after {
  content: "4";
}


.day .hour:nth-of-type(6):after {
  content: "5";
}


.day .hour:nth-of-type(7):after {
  content: "6";
}


.day .hour:nth-of-type(8):after {
  content: "7";
}


.day .hour:nth-of-type(9):after {
  content: "8";
}


.day .hour:nth-of-type(10):after {
  content: "9";
}


.day .hour:nth-of-type(11):after {
  content: "10";
}


.day .hour:nth-of-type(12):after {
  content: "11";
}


.day .hour:nth-of-type(13):after {
  content: "12";
}


.day .hour:nth-of-type(14):after {
  content: "13";
}


.day .hour:nth-of-type(15):after {
  content: "14";
}


.day .hour:nth-of-type(16):after {
  content: "15";
}


.day .hour:nth-of-type(17):after {
  content: "16";
}


.day .hour:nth-of-type(18):after {
  content: "17";
}


.day .hour:nth-of-type(19):after {
  content: "18";
}


.day .hour:nth-of-type(20):after {
  content: "19";
}


.day .hour:nth-of-type(21):after {
  content: "20";
}


.day .hour:nth-of-type(22):after {
  content: "21";
}


.day .hour:nth-of-type(23):after {
  content: "22";
}


.day .hour:nth-of-type(24):after {
  content: "23";
}


.day .hour:nth-of-type(25):after {
  content: "24";
}


.day .hour:after {
  text-indent: -0.5em;
}


.weekday {
  position: relative;
  padding-right: 10px;
  height: 650px;
  width: 800px;
}


.bar div {
  display: inline-block;
}


.item {
  position: absolute;
  top: 0;
  height: 100%;
  background-color: blue;
  width: 100%;
}


.bdown {
  width: 100%;
  height: 10px;
  background: transparent;
  position: absolute;
  bottom: -5px;
  left: 0;
  z-index: 1;
}


.bup {
  width: 100%;
  height: 10px;
  background: transparent;
  position: absolute;
  top: -5px;
  left: 0;
  z-index: 1;
}

2、接下来实现交互逻辑,文件*.js代码实现如下:

Tips:函数作用已有备注,可自行调试理解。

/**
 * 按格子移动,数据格式为日期
 */
(function($) {
  'use strict';
  $.fn.initJuicy = function(data) {
    return new MyinitJuicy(data, this);
  };
  var perheight = 0;
  var MyinitJuicy = function(data, that) {
    var me = this;
    me.init(data, that);
    me.offsettop = $(that).offset().top;
  };


  // 返回选择的日期
  MyinitJuicy.prototype.getdata = function() {
    var backdata = [];
    var monday = $(".kaoqing").data("monday");
    $.each($(".weekday"), function(i, obj) {
      var thisday = getNextDate(monday, i);
      $.each($(obj).find(".item"), function(j, obj1) {
        var x = parseFloat($(obj1).css("top")) / perheight;
        var y = parseFloat($(obj1).css("height")) / perheight + x;
        var startime = Math.round(x) % 2 == 0 ? (thisday + " " +  ("0"+Math.round(x) / 2).slice(-2) + ":00:00") : (thisday + " " + ("0"+ parseInt(Math.round(x) / 2)).slice(-2) + ":30:00");
        var endtime = Math.round(y) % 2 == 0 ? (thisday + " " + ("0"+Math.round(y) / 2).slice(-2) + ":00:00") : (thisday + " " + ("0"+parseInt(Math.round(y) / 2)).slice(-2) + ":30:00");
        backdata.push({
          startime: startime,
          endtime: endtime
        });
      });


    })
    return backdata;
  }
  // 初始化
  MyinitJuicy.prototype.init = function(data, that) {
    var me = this;
    me.current = 0; //新增编号
    me.cando = true; //当前位置是否允许新增
    me.nowmove = -1; //当前拖动的序号
    me.newcreate = true;
    me.opts = $.extend(true, {}, { //用于设弹窗默认值
      height: 900,
      mondayDate: '',
      timedata: [], //[{startime:,endtime:},]
      status: true,
      data1: [{
        "type": "周一",
        "timeSlot": []
      }, {
        "type": "周二",
        "timeSlot": []
      }, {
        "type": "周三",
        "timeSlot": []
      }, {
        "type": "周四",
        "timeSlot": []
      }, {
        "type": "周五",
        "timeSlot": []
      }, {
        "type": "周六",
        "timeSlot": []
      }, {
        "type": "周日",
        "timeSlot": []
      }]
    }, data);
    me.mousedown = false;
    //初始化
    var str = '';
    var boxheight = me.opts.height;
    var navheight = me.opts.height - 50;
    me.perheight = perheight = navheight / 48;
    $(that).css("height", boxheight + "px");
    $(that).attr("data-monday", me.opts.mondayDate);
    var data3 = me.opts.timedata;
    var timedata = me.opts.data1;
  
    for(var i = 0; i < 7; i++) {
      timedata[i]["type"] += getNextDay(me.opts.mondayDate, i);
    }
    
    $.each(data3, function(i, obj) {
      var day = new Date(obj.startime.replace(/-/g,"/")).getDay() - 1;
      if(day == -1) day = 6;
      timedata[day]["timeSlot"].push([getMytime(obj.startime), getMytime(obj.endtime)]);
    });


    for(var i = 0; i < 1; i++) {
      str += '<div class="weekday">' +
        '<div>' +
        '<div class="day">';
      for(var j = 0; j < 24; j++) {
        str += '<div class="hour" style="top:'+me.perheight * 2 * j+'px;"><div class="halfhour"></div></div>';
      }
      str += '<div class="hour" style="top:'+me.perheight * 2 * 24+'px;"></div></div><div class="bar">';
      if(timedata.length == 0) {
        str += '</div></div></div>';
      } else {
        for(var t = 0; t < timedata[i].timeSlot.length; t++) {
          var top = navheight * timedata[i].timeSlot[t][0] / 24;
          var height = navheight * (timedata[i].timeSlot[t][1] - timedata[i].timeSlot[t][0]) / 24;
          str += '<div class="item item' + me.current + '" style="top:' + top + 'px;height:' + height + 'px" data-num="' + me.current + '">' +
            '<div class="bup"></div><div class="bdown"></div></div>';
          me.current++;
        }
        str += '</div></div></div>';
      }
    }


    var $str = $(str);
    $(that).append($str);
    //点在蓝条条上就禁止它新建了
    if(me.opts.status) {
      $(".bup").css("cursor", "n-resize");
      $(".bdown").css("cursor", "s-resize");
      $str.find(".item").on('mousedown', function(e) {
        me.cando = false;
        return false;
      })
      $str.find(".bar").on('mousedown', function(e) {
        if(me.cando) {
          me.mousedown = true;
          me.newcreate = true;
          fnstart(e, me, this);
        }
        return false; //防止事件冒泡
      });
      $("body").on('mouseup', function(e) {
        me.cando = true;
        if(me.mousedown) {
          me.mousedown = false;
          fnend(me);
          me.nowmove = -1;
        }
        return false; //防止事件冒泡
      });


      $str.find(".bdown").on('mousedown', function(e) {
        me.mousedown = true;
        me.newcreate = false;
        me._startY = e.pageY;
        me.direction='down';
        me.height = parseFloat($(this).parent().css("height")); //会实时变化
        me.top = parseFloat($(this).parent().css("top")); //会实时变化
        me.startheight = parseFloat($(this).parent().css("height")); //是个常数
        me.starttop = parseFloat($(this).parent().css("top")); //是个常数
        me.nowmove = parseFloat($(this).parent().data("num"));
        return false;
      })
      $str.find(".bup").on('mousedown', function(e) {
        me.mousedown=true;
        me.newcreate = false;
        me._startY = e.pageY;
        me.direction='up';
        me.height = parseFloat($(this).parent().css("height")); //会实时变化
        me.top = parseFloat($(this).parent().css("top")); //会实时变化
        me.startheight = parseFloat($(this).parent().css("height")); //是个常数
        me.starttop = parseFloat($(this).parent().css("top")); //是个常数
        me.nowmove = parseFloat($(this).parent().data("num"));
        return false; 
      })
      //注意:move事件一定要绑在body上,当鼠标移动过快可能移除那个div区域
      $("body").on('mousemove', function(e) {
        if(me.mousedown && me.newcreate) {
          fnmove(e, me);
        } else if(me.mousedown && !me.newcreate) {
          if(me.direction&&me.direction=='up'){
            fnmoveup(e, me);
          }else if(me.direction&&me.direction=='down'){
            fnmovedown(e, me);
          }
        } else {
          e.preventDefault()
        }


      });
    } else {
      $(".bdown,.bup").css("cursor", "default");
    }


  };
  function fnmoveup(e, me) {
    me._curX = e.pageX;
    me._curY = e.pageY;
    me._moveY = me._startY - me._curY;
    var item = ".item" + me.nowmove;
    var top= me.starttop-me._moveY;
    var height = me.startheight + me._moveY;
    //左边的向左拉,不超过左边边界
    if(me._moveY > 0 && me._moveY < me.starttop) {
      $(item).css({
        "height": height + 'px',
        "top": top + 'px'
      })
      me.height = height;
      me.top = top;
    } else if(me._moveY > 0 && me._moveY >= me.starttop) { //左边的向左拉,超过左边边界
      $(item).css({
        "height": (me.starttop+me.startheight) + 'px',
        "top": 0
      })
      me.height = me.starttop+me.startheight;
      me.top = 0;
    } else if(me._moveY < 0 && -me._moveY <= me.startheight) { //左边的向右拉,不能超过当前右边的0.5小时
      $(item).css({
        "height": height + 'px',
        "top": top + 'px'
      })
      me.height = height;
      me.top = top;
    } else if(me._moveY < 0 && -me._moveY > me.startheight) { //左边的向右拉,超过最右边
      $(item).css({
        "height": 0,
        "top": (me.startheight + me.starttop)+ 'px'
      })
      me.height = 0;
      me.top = me.startheight + me.starttop;
    }
  }
  function fnmovedown(e, me) {
    me._curX = e.pageX;
    me._curY = e.pageY;
    me._moveY = me._curY - me._startY;
    var item = ".item" + me.nowmove;
    var top = me.starttop;
    var height = me.startheight + me._moveY;
    //右边的向右拉,不超过右边边界
    if(me._moveY > 0 && me._moveY < me.perheight * 48 - me.starttop - me.startheight) {
      $(item).css({
        "height": height + 'px',
        "top": top + 'px'
      })
      me.height = height;
    } else if(me._moveY > 0 && me._moveY >= me.perheight * 48 - me.starttop - me.startheight) { //右边的向右拉,超过右边边界
      $(item).css({
        "height": (me.perheight * 48 - top) + 'px',
        "top": top + 'px'
      })
      me.height = me.perheight * 48 - top;
    } else if(me._moveY < 0 && -me._moveY <= me.startheight) { //右边的向左拉,不能超过当前左边的0.5小时
      $(item).css({
        "height": height + 'px',
        "top": top + 'px'
      })
      me.height = height;
    } else if(me._moveY < 0 && -me._moveY > me.startheight) { //右边的向左拉,超过最左边
      $(item).css({
        "height": 0,
        "top": top + 'px'
      })
      me.height = 0;
    }
  }
  
  function fnstart(e, me, that) {
    me._startY = e.pageY;
    var top = me._startY - me.offsettop;
    me.top = nearest(top);
    me.starttop = nearest(top);
    me.nowmove = me.current;
    var str = '<div class="item item' + me.current + '" style="top:' + me.top + 'px;height:1px"  data-num="' + me.current + '">' +
      '<div class="bup"></div><div class="bdown"></div></div>';
    me.current++;
    var item = ".item" + (me.current - 1);
    $(that).append($(str));
    if(me.opts.status) {
      $(".bup").css("cursor", "n-resize");
      $(".bdown").css("cursor", "s-resize");
      $(item).on('mousedown', function(e) {
        me.cando = false;
        return false;
      })


      $(item).find(".bdown").on('mousedown', function(e) {
        me.mousedown = true;
        me.newcreate = false;
        me._startY = e.pageY;
        me.direction='down';
        me.height = parseFloat($(this).parent().css("height")); //会实时变化
        me.top = parseFloat($(this).parent().css("top")); //会实时变化
        me.startheight = parseFloat($(this).parent().css("height")); //是个常数
        me.starttop = parseFloat($(this).parent().css("top")); //是个常数
        me.nowmove = parseFloat($(this).parent().data("num"));
        return false;
      })
      $(item).find(".bup").on('mousedown', function(e) {
        me.mousedown=true;
        me.newcreate = false;
        me._startY = e.pageY;
        me.direction='up';
        me.height = parseFloat($(this).parent().css("height")); //会实时变化
        me.top = parseFloat($(this).parent().css("top")); //会实时变化
        me.startheight = parseFloat($(this).parent().css("height")); //是个常数
        me.starttop = parseFloat($(this).parent().css("top")); //是个常数
        me.nowmove = parseFloat($(this).parent().data("num"));
        return false; 
      })
    } else {
      $(".bup,.bdown").css("cursor", "default");
    }


  }


  function fnmove(e, me) {
    me._curX = e.pageX;
    me._curY = e.pageY;
    me._moveY = me._curY - me._startY;
    var item = ".item" + (me.current - 1);
    if(me._moveY > 0 && me._moveY < me.perheight * 48 - me.starttop) {
      me.height = me._moveY;
      $(item).css("height", me._moveY + 'px');
//      $(item).css("height", me._moveY + 'px')
    } else if(me._moveY > 0 && me._moveY >= me.perheight * 48 - me.starttop) {
      me.height = me.perheight * 48 - me.starttop;
      $(item).css("height", (me.perheight * 48 - me.starttop) + 'px')
    } else {
      me.height = 0;
      $(item).css("height", 0)
    }
  }


  function fnend(me, i) {
    var height = me.height;
    var top = me.top;
    var item = ".item" + me.nowmove;
    if(height == 0) {
      $(item).remove();
    } else {
      $(item).css("height", nearest(height) + "px");
      $(item).css("top", nearest(top) + "px");
      var result = xiaoxiannvbianshen(item);
      var items = $(item).parent().find(".item");
      if(result.length < items.length) {
        $.each(items, function(i, obj) {
          if(i < result.length) {
            $(obj).css({
              "top": result[i][0] + 'px',
              "height": result[i][1] + 'px'
            })
          } else {
            $(obj).remove();
          }
        });
      }
    }
    //松手后才能修改值
  }


  // 计算贴近的位置
  function nearest(top) {
    var yu = top % perheight;
    if(yu < perheight / 2) {
      return top - yu;
    } else {
      return top + (perheight - yu);
    }
  }


  function getMytime(date) {
    if(date.split(" ")[1] == "24:00:00") {
      return 24;
    } else {
      var time = new Date(date.replace(/-/g,"/"));
      if(time.getMinutes() > 10) {
        return time.getHours() + 0.5;
      } else {
        return time.getHours();
      }
    }


  }


  // 返回月日
  function getNextDay(d, i) {
    var monday = new Date(d.replace(/-/g,"/"));
    monday = monday.getTime() + 1000 * 60 * 60 * 24 * i;
    monday = new Date(monday);
    return (monday.getMonth() + 1) + "/" + monday.getDate();
  }


  // 返回年月日
  function getNextDate(d, i) {
    var monday = new Date(d.replace(/-/g,"/"));
    monday = monday.getTime() + 1000 * 60 * 60 * 24 * i;
    monday = new Date(monday);
    return monday.getFullYear() + "-" + ("0"+(monday.getMonth() + 1)).slice(-2) + "-" + ("0"+monday.getDate()).slice(-2);
  }


  function xiaoxiannvbianshen(item) {
    var array = [];
    var arrayresult = [];
    var $item = $(item).parent().find(".item");
    $.each($item, function(i, obj) {
      var top = parseFloat($(obj).css("top"));
      var height = parseFloat($(obj).css("height"));
      array.push([top, top + height]);
    });
    var sortarray = bubbleSort(array);
    //var sortarray = array.sort();
    var temp = sortarray[0];
    for(var i = 0; i < sortarray.length; i++) {
      if(!sortarray[i + 1]) {
        arrayresult.push(temp);
        break
      }
      if(temp[1] < sortarray[i + 1][0]) {
        arrayresult.push(temp);
        temp = sortarray[i + 1];
      } else {
        if(temp[1] <= sortarray[i + 1][1]) {
          temp = [temp[0], sortarray[i + 1][1]];
        } else {
          temp = [temp[0], temp[1]];
        }
      }
    }
    var huanyuan = [];
    for(var j = 0; j < arrayresult.length; j++) {
      huanyuan.push([arrayresult[j][0], arrayresult[j][1] - arrayresult[j][0]]);
    }
    return huanyuan;
  }


  function bubbleSort(array) {
    for(var unfix = array.length - 1; unfix > 0; unfix--) {
      for(var i = 0; i < unfix; i++) {
        if(array[i][0] > array[i + 1][0]) {
          var temp = array[i];
          array.splice(i, 1, array[i + 1]);
          array.splice(i + 1, 1, temp);
        }
      }
    }
    return array;
  }
})(window.Zepto || window.jQuery)

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码