拖拽选择时间

<template>

  <div class="byted-weektime" @mousedown="dian" @mousemove="yi" @mouseup="li">

    <div class="calendar">

      <table class="calendar-table" style="width:610px">

        <thead class="calendar-head">

          <tr>

            <th rowspan="6" class="week-td">星期/时间</th>

            <th colspan="24">00:00 - 12:00</th>

            <th colspan="24">12:00 - 24:00</th>

          </tr>

          <tr>

            <td colspan="2" v-for="(item, index) in tableHeader" :key="index">{{ item }}</td>

          </tr>

        </thead>

        <tbody id="tableBody">

          <div id="kuang"

            :style="{ width: kuangObj.width + 'px', height: kuangObj.height + 'px', top: kuangObj.top + 'px', left: kuangObj.left + 'px', bottom: kuangObj.bottom + 'px', right: kuangObj.right + 'px' }">

          </div>

          <tr>

            <td>星期一</td>

            <td @mousedown.prevent="handleMouseDown(i, 0)" @mouseup.prevent="handleMouseUp(i, 0)"

              class="calendar-atom-time" :class="item.class" v-for="(item, i) in rowUnit[0]" :key="i"></td>

          </tr>

          <tr>

            <td>星期二</td>

            <td @mousedown.prevent="handleMouseDown(i, 1)" @mouseup.prevent="handleMouseUp(i, 1)"

              class="calendar-atom-time" :class="item.class" v-for="(item, i) in rowUnit[1]" :key="i"></td>

          </tr>

          <tr>

            <td>星期三</td>

            <td @mousedown.prevent="handleMouseDown(i, 2)" @mouseup.prevent="handleMouseUp(i, 2)"

              class="calendar-atom-time" :class="item.class" v-for="(item, i) in rowUnit[2]" :key="i"></td>

          </tr>

          <tr>

            <td>星期四</td>

            <td @mousedown.prevent="handleMouseDown(i, 3)" @mouseup.prevent="handleMouseUp(i, 3)"

              class="calendar-atom-time" :class="item.class" v-for="(item, i) in rowUnit[3]" :key="i"></td>

          </tr>

          <tr>

            <td>星期五</td>

            <td @mousedown.prevent="handleMouseDown(i, 4)" @mouseup.prevent="handleMouseUp(i, 4)"

              class="calendar-atom-time" :class="item.class" v-for="(item, i) in rowUnit[4]" :key="i"></td>

          </tr>

          <tr>

            <td>星期六</td>

            <td @mousedown.prevent="handleMouseDown(i, 5)" @mouseup.prevent="handleMouseUp(i, 5)"

              class="calendar-atom-time" :class="item.class" v-for="(item, i) in rowUnit[5]" :key="i"></td>

          </tr>

          <tr>

            <td>星期日</td>

            <td @mousedown.prevent="handleMouseDown(i, 6)" @mouseup.prevent="handleMouseUp(i, 6)"

              class="calendar-atom-time" :class="item.class" v-for="(item, i) in rowUnit[6]" :key="i"></td>

          </tr>

          <tr>

            <td colspan="49" class="td-table-tip">

              <div class="clearfix">

                <span class="pull-left tip-text">请用鼠标点选时间段</span>

                <a @click="clear" class="pull-right">清空</a>

              </div>

            </td>

          </tr>

          <tr style="text-align: center;">

            <td colspan="49" class="timeContent">

              已选时间段

              <div v-for="(item, index) in timeStr" :key="index" v-show="item.length">

                <span>{{ weekDate[index + 1] }}:</span>

                <strong>

                  <span>{{ item }}</span>

                </strong>

              </div>

            </td>

          </tr>

        </tbody>

      </table>

    </div>

    <!-- 鼠标的画框的效果 -->

    <div id="container" v-bind:style="{

      backgroundColor: back,

      height: h + 'px',

      width: w + 'px',

      position: 'absolute',

      left: left + 'px',

      top: top + 'px',

      opacity: 0.2,

      border: len + 'px dashed #000',

      zIndex: -1

    }"></div>

  </div>

</template>

<script>

export default {

  name: "timeSelect",

  data() {

    return {

      tableHeader: [

        "00",

        "01",

        "02",

        "03",

        "04",

        "05",

        "06",

        "07",

        "08",

        "09",

        "10",

        "11",

        "12",

        "13",

        "14",

        "15",

        "16",

        "17",

        "18",

        "19",

        "20",

        "21",

        "22",

        "23"

      ],

      weekDate: {

        "1": "星期一",

        "2": "星期二",

        "3": "星期三",

        "4": "星期四",

        "5": "星期五",

        "6": "星期六",

        "7": "星期日"

      },

      rowUnit: [], //每一个单元格

      timeContent: [], //选中的时间段原始数据

      timeSection: [], //时间段,可以返回给后台的数据

      timeStr: [], //时间段,前端显示的数据

      beginDay: 0,

      beginTime: 0,

      downEvent: false,

      kuangObj: {

        width: 0,

        height: 0,

        top: 0,

        left: 0,

        bottom: 0,

        right: 0,

        oldLeft: 0,

        oldTop: 0,

        flag: false

      },

      py: "",

      px: "",

      back: "#31676f",

      h: "",

      w: "",

      top: "",

      left: "",

      len: 0,

      list:''

    };

  },

  created() {

    this.init();

  },

  mounted() { },

  methods: {

    init() {

      for (let i = 0; i < 7; i++) {

        let arr = [];

        for (let j = 0; j < 48; j++) {

          arr.push({ class: null, timeData: j });

        }

        this.rowUnit.push(arr);

        this.timeContent.push({ arr: [] });

        this.timeSection.push([]);

        this.timeStr.push("");

      }

    },

    handleMouseDown(i, day) {

      this.downEvent = true; //按下时鼠标不在范围内则不算

      this.beginDay = day;

      this.beginTime = i;

    },

    dian(event) {

      // console.log(event);

      this.px = event.pageX; //获取x坐标

      this.py = event.pageY;

    },

    yi(event) {

      if (this.px == "" || this.py == "") {

        return;

      }

      var px1 = this.px;

      var px2 = this.py;

      this.left = event.pageX;

      this.top = event.pageY;

      this.h = this.top - this.py;

      this.w = this.left - this.px;

      var hc = -this.h;

      var wc = -this.w;

      this.len = 1;

      this.back = "#31676f";

      if (this.h < 0 && this.w >= 0) {

        // console.log(1);

        this.h = hc;

        this.left = px1;

      } else if (this.h >= 0 && this.w < 0) {

        // console.log(2);

        this.w = wc;

        this.top = px2;

      } else if (this.h < 0 && this.w < 0) {

        // console.log(3);

        this.h = hc;

        this.w = wc;

      } else {

        // console.log(4);

        this.left = this.px;

        this.top = this.py;

      }

      if (this.w < 0) {

        this.w = 0 - this.w;

      }

      if (this.h < 0) {

        this.h = 0 - this.h;

      }

    },

    li() {

      this.px = "";

      this.py = "";

      this.h = "";

      this.w = "";

      this.top = "";

      this.left = "";

      this.len = 0;

      this.back = "";

    },

    handleMouseUp(i, day) {

      let _this = this;

      let begin = this.beginTime;

      let start = begin <= i ? begin : i; //x轴 起点

      let length = Math.abs(begin - i);

      let end = start + length; //x轴 终点

      let dayStart = this.beginDay <= day ? this.beginDay : day; //y轴 起点

      let dayLength = Math.abs(this.beginDay - day);

      let dayEnd = dayStart + dayLength; //y轴 终点

      //当框选范围内所有块都是选中状态时,执行反选

      function isAdd() {

        for (let x = dayStart; x < dayEnd + 1; x++) {

          for (let y = start; y < end + 1; y++) {

            if (_this.rowUnit[x][y].class == null) return true;

          }

        }

        return false;

      }

      //当点击事件是在table内才触发选取数据操作

      if (this.downEvent) {

        //选时间段

        if (isAdd()) {

          //没选中的全都选上

          for (let x = dayStart; x < dayEnd + 1; x++) {

            for (let y = start; y < end + 1; y++) {

              if (this.rowUnit[x][y].class == null) {

                this.rowUnit[x][y].class = "ui-selected";

                this.timeContent[x].arr.push(this.rowUnit[x][y].timeData);

              }

            }

          }

        } else {

          //反选

          for (let x = dayStart; x < dayEnd + 1; x++) {

            for (let y = start; y < end + 1; y++) {

              if (this.rowUnit[x][y].class == "ui-selected") {

                this.rowUnit[x][y].class = null;

                var c = this.rowUnit[x][y].timeData;

                var kong = "";

                for (let i = 0; i < this.timeContent[x].arr.length; i++) {

                  if (c == this.timeContent[x].arr[i]) {

                    kong = i;

                  }

                }

                this.timeContent[x].arr.splice(kong, 1);

              }

            }

          }

        }

        //过滤时间段,将临近的时间段合并

        this.filterTime(dayStart, dayEnd);

      }

      this.downEvent = false;

    },

    filterTime(start, end) {

      //选中的x,y坐标信息 x:0-47  y:0-6

      function sortCut(arr) {

        //提取连续的数字

        var result = [];

        arr.forEach(function (v, i) {

          var temp = result[result.length - 1];

          if (!i) {

            result.push([v]);

          } else if (v % 1 === 0 && v - temp[temp.length - 1] == 1) {

            temp.push(v);

          } else {

            result.push([v]);

          }

        });

        return result;

      }

      function toStr(num) {

        if (Number.isInteger(num)) {

          let str = num < 10 ? "0" + num : num.toString();

          return str + ":00";

        } else {

          let str =

            Math.floor(num) < 10

              ? "0" + Math.floor(num)

              : Math.floor(num).toString();

          return str + ":30";

        }

      }

      function timeToStr(arr) {

        //把数组转成方便人看到字符串

        let str = "";

        arr.forEach((arr, index) => {

          let str1 = "";

          if (index == 0) {

            str1 = toStr(arr[0]) + "~" + toStr(arr[1]);

          } else {

            str1 = " , " + toStr(arr[0]) + "~" + toStr(arr[1]);

          }

          str += str1;

        });

        return str;

      }

      //排序,分割成

      for (let i = start; i < end + 1; i++) {

        let arr1 = sortCut(this.timeContent[i].arr.sort((a, b) => a - b));

        let arr2 = [];

        arr1.forEach(arr => {

          //转成带小数点的时间段,以及供前端显示的字符串

          let arr3 = [];

          arr3.push(arr[0] / 2);

          arr3.push(arr[arr.length - 1] / 2 + 0.5);

          arr2.push(arr3);

        });

        this.timeStr[i] = timeToStr(arr2);

        this.timeSection[i] = arr2;

      }

      let list = []

      for (let i = 0; i < 7; i++) {

        let str = ''

        for (let j = 0; j < 48; j++) {

          str += '0'

        }

        list.push(str)

      }

      this.timeSection.forEach((item, index) => {

        let str=list[index].split('')

        item.forEach((itm, idx) => {

          for(let i=0;i<str.length;i++){

            if(i>=itm[0]*2&&i<itm[1]*2){

              str[i]=1

            }

          }

        })

        list[index]=str.join('')

      })

      this.list=list.join('')

    },

    clear() {

      this.rowUnit.forEach(item => {

        item.forEach(item1 => {

          item1.class = null;

        });

      });

      this.timeContent.forEach(item => {

        item.arr = [];

      });

      this.timeSection.forEach(item => {

        //赋值成空数组[]出问题

        item.length = 0;

      });

      //遍历赋值成'',不管用

      this.timeStr.length = 0;

      for (let i = 0; i < 7; i++) {

        this.timeStr.push("");

      }

      //this.initState = true

    },

  }

};

</script>

<style scoped>

.byted-weektime .calendar {

  -webkit-user-select: none;

  position: relative;

  display: inline-block;

}

#tableBody {

  /* position: relative; */

}

/*.byted-weektime .calendar .schedule{background:#2F88FF;width:0;height:0;position:fixed;display:none;top:0;left:0;pointer-events:none;-webkit-transition:all 400ms ease;-moz-transition:all 400ms ease;-ms-transition:all 400ms ease;transition:all 400ms ease}*/

.byted-weektime .calendar .calendar-table {

  border-collapse: collapse;

  border-radius: 4px;

}

.byted-weektime .calendar .calendar-table tr .calendar-atom-time:hover {

  background: #ccc;

}

.byted-weektime .calendar .calendar-table tr .ui-selected {

  background: #2f88ff;

}

.byted-weektime .calendar .calendar-table tr .ui-selected:hover {

  background: #2f88ff;

}

.byted-weektime .calendar .calendar-table tr,

.byted-weektime .calendar .calendar-table td,

.byted-weektime .calendar .calendar-table th {

  border: 1px solid #ccc;

  font-size: 12px;

  text-align: center;

  background-color: #fff;

  color: #000;

  line-height: 1.8em;

  -webkit-transition: background 200ms ease;

  -moz-transition: background 200ms ease;

  -ms-transition: background 200ms ease;

  transition: background 200ms ease;

}

.byted-weektime .calendar .calendar-table tbody tr {

  height: 30px;

}

.byted-weektime .calendar .calendar-table tbody tr td:first-child {

  background: #f8f9fa;

}

.byted-weektime .calendar .calendar-table thead th,

.byted-weektime .calendar .calendar-table thead td {

  background: #f8f9fa;

}

.byted-weektime .calendar .calendar-table .td-table-tip {

  line-height: 2.4em;

  padding: 0 12px 0 19px;

  background: #fff !important;

}

.byted-weektime .calendar .calendar-table .td-table-tip .clearfix {

  display: flex;

  justify-content: space-between;

  height: 46px;

  line-height: 46px;

}

.byted-weektime .calendar .calendar-table .td-table-tip .pull-left {

  font-size: 14px;

  color: #333333;

}

.byted-weektime .week-td {

  width: 75px;

  padding: 20px 0;

}

.byted-weektime a {

  cursor: pointer;

  color: #2f88ff;

  font-size: 14px;

}

#kuang {

  position: absolute;

  background-color: blue;

  opacity: 0.3;

}

</style>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容

  • git add .$ git pull origin feature/V8.30 可以从其他的分支拉当前的分支名$...
    言辞渐觉乏味阅读 546评论 0 0
  • client,page和screen的区别? clientX,clientY是触摸点相对于viewport视口x,...
    change_22fa阅读 1,625评论 1 1
  • PNG 有PNG8和truecolor PNG PNG8类似GIF颜色上限为256,文件小,支持alpha透明度,...
    hudaren阅读 1,498评论 0 0
  • 请参看我github中的wiki,不定期更新。https://github.com/ivonzhang/Front...
    zhangivon阅读 7,087评论 2 19
  • 前端面试题的简单整理,都只是大概回答,具体某些问题的具体理解后续会补上。 前端页面有哪三层构成,分别是什么?作用是...
    李欢li阅读 469评论 0 2