天天看点

div拖拽左右移动

clientX 鼠标相对于浏览器左上角x轴的坐标; 不随滚动条滚动而改变;

clientWidth =width+左右padding

offsetWidth=width+左右padding+左右border

srollWidth:指定标签内容曾的真实宽度,包含可视区域和被隐藏区域

offsetLeft:当前元素 左边框 外边缘 到 最近的已定位父级(offsetParent) 左边框 内边缘的 距离。如果父级都没有定位,则分别是到body 顶部 和左边的距离

原生JS案例(面向对象)——按住鼠标实现左右拖动列表

JS中的位置和宽度:clientWidth、offsetWidth、scrollWidth等区别

html

<div class="history-header">
        <div class="progress-bar">
          <div v-for="(item, index) in dateData" :key="index">
            <div
              class="node"
              @click="activeClick(index)"
              :class="nodeIndex == index ? 'active' : 'node'"
            >
              <div class="node-text">{{ item.date }}</div>
              <div class="node-icon"></div>
            </div>
            <div
              class="line"
              :class="index == 7 ? 'line_active' : 'line'"
            ></div>
          </div>
          <!-- 渐变线 -->
          <div class="line line_gradual"></div>
          <div class="more el-icon-arrow-right" @click="nextClick()"></div>
        </div>
      </div>
      
      <div class="history-content">
        <div class="history-list" @mousedown="slidDown($event)">
          <div
            class="history-item"
            v-for="item in historyitem"
            :key="item.time"
          >
            <div class="time">{{ item.time }}</div>
            <div class="list">
              <div>{{ item.text1 }}</div>
              <div>{{ item.text2 }}</div>
            </div>
          </div>
        </div>
      </div>
           

css

<style>
  &-content {
    width: 85%;
    height: 300px;
    max-width: 1640px;
    margin: auto;
    margin-top: 48px;
    text-align: left;
    position: relative;
    overflow: hidden;
    .history-list {
      width: 80%;
      position: absolute;
      display: flex;
    }

    .history-item {
      margin-right: 16px;
      display: inline-block;
      .list {
        width: 400px;
      }

      .time {
        margin-bottom: 24px;
        font-size: 32px;
        font-weight: bold;
        line-height: 32px;
        color: #1f364d;
      }
    }
  }
</style>
           

页面效果:

并且拖动时,上方的点跟着移动

div拖拽左右移动

js

<script>
    slidDown(e) {
      // 取消默认行为
      if (e.preventDefault) {
        e.preventDefault();
      } else {
        return false;
      }
      // 获取dom元素=_wrap
      this.box = document.querySelector(`.history-content`);
      // =_list
      this.list = this.box.querySelector(".history-list");
      // =_lis
      this.item = this.list.querySelector(".history-item");
      // 设置w为list的宽度, list的宽度跟随item的数量动态变化
      let w = this.item.offsetWidth * this.historyitem.length;
      console.log(this.historyitem.length,'jjjjj');
      // 获取当前距离及最大移动距离
      let disX = e.clientX;
      let oldLeft = this.list.offsetLeft;
      let maxL = w - this.box.offsetWidth;
      // list没有比content长的情况下
      if (maxL <= 0) return;
      this.list.style.width = w + "px";
      // 鼠标移动时
      document.onmousemove = (e) => {
        e = e || window.event;
        //移动的距离
        let nowL = oldLeft + e.clientX - disX;
        // 取到移动的item的index值,判断与icon的index值,改变样式
        let nowindex = -parseInt(nowL / this.item.offsetWidth);
        // console.log(nowindex);
        if (nowindex !== this.nodeIndex) {
          this.nodeIndex = nowindex;
        }
        console.log(nowL);
        //向左移动,保持第一个不动
        if (nowL >= 0) nowL = 0;
        // 向右移动
        if (-1 * nowL >= maxL) {
          nowL = -1 * maxL;
        }
        this.list.style.left = nowL + "px";

        // 比较index值,增删样式
      };
      // 鼠标弹起时
      document.onmouseup = () => {
        document.onmousemove = null;
      };
    },
</script>
           

考虑3种情况:

(1)list没有充满content

(2)list向左,直到最左

(3)list向右,直到最有

div拖拽左右移动

继续阅读