原生table實現輪詢+css修改默認滾動條樣式

最近作項目(vue系列)遇到兩個需求,這裏作一個記錄,分享給你們。css

原生Table列表實現輪詢

需求:
  1. 當table列表數量較少時不輪詢,超過必定高度才輪詢;
  2. 鼠標移入暫停輪詢,移出繼續輪詢

首先,原型圖長下面這樣:
原型圖
右下角有個分頁,用的是elementUI的分頁組件,改了下樣式,主體就是一個原生table
輪詢有好幾種實現方式,網上搜一搜不少,我這裏使用js的方式實現,大概的思路就是:經過控制margin-top,好比margin-top=-1px,margin-top=-2px;margin-top=-3px;...,當這個值大於行高時,說明這條數據已經滾動完畢了,這時恢復margin-top=0,而且將它插入到tbody底部,從而實現輪詢。直接上代碼:vue

HTML
<div class="network-container">
    <div class="network-center">
      <img src="./imgs/img_map_bg_02.png" />
      <img src="./imgs/img_map_bg_04.png" />
      <div class="network-center-content">
        <table class="deviceInfoBox">
          <thead>
            <tr>
              <th class="name">設備類型</th>
              <th class="name">設備大類</th>
              <th class="code">設備編號</th>
              <th class="pos">設備位置</th>
              <th class>任務延時</th>
              <th class="sysState">設備狀態</th>
              <th class="pro">任務完成進度</th>
              <th class="pro">任務開始時間</th>
              <th class="pro">任務結束時間</th>
              <th class="pro">任務時長</th>
            </tr>
          </thead>
        </table>
        <div class="scroll-box" ref="scrollBox">
          <table
            class="tab-scroll"
            ref="scroll"
            @mouseenter="activeEve(false)"
            @mouseleave="activeEve(true)"
          >
            <tbody>
              <tr v-for="(si,idx) in deviceInfoList" :key="idx">
                <td class="name">{{si.name || '-'}}</td>
                <td class="type">{{si.type || '-'}}</td>
                <td class="code">
                  <a
                    @click="handleClick(si)"
                    :class="{'isDisabled':(si.name !== '混凝土天花打磨') || si.sysState !== '3'}"
                  >{{si.deviceCode || '-'}}</a>
                </td>
                <td class="pos">{{si.posistion || '-'}}</td>
                <td class="pos" v-if="si.sysState == '3'">{{Number(si.delayedTime)+'ms'}}</td>
                <td class="pos" v-else>{{si.delayedTime || '-'}}</td>
                <td
                  class="sysState"
                  :class="{'yellow': si.sysState == '2', 'green': si.sysState == '3'}"
                >{{deviceStateArr[si.sysState] || '-'}}</td>
                <td v-if="si.sysState == '3'">
                  <el-progress :percentage="si.progress || 0"></el-progress>
                </td>
                <td v-else>{{si.progress || '-'}}</td>
                <td>{{si.workStartTime || '-'}}</td>
                <td>{{si.workEndTime || '-'}}</td>
                <td>{{si.duration}}</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
      <div class="page-bar">
        <el-pagination
          background
          layout="prev,pager, next"
          :current-page="page"
          :page-size="pageSize"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        ></el-pagination>
      </div>
    </div>
  </div>
</template>
CSS
<style scoped lang='scss'>
table {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
}
th,
td {
  line-height: 35px;
  color: #ffffff;
  text-align: center;
  word-break: keep-all; /* 不換行 */
  white-space: nowrap; /* 不換行 */
  overflow: hidden; /* 內容超出寬度時隱藏超出部分的內容 */
  text-overflow: ellipsis; /* for IE */
}
.scroll-box {
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: relative;
}
.tab-scroll {
  table-layout: fixed;
  font-size: 16px;
  position: absolute;
  left: 0;
  top: 0;
  border-top: none;
  padding-left: 60px;
  .isDisabled {
    pointer-events: none;
    cursor: not-allowed;
  }
  .yellow {
    color: #dada09;
  }
  .green {
    color: #04ba19;
  }
}
.left-button {
  position: absolute;
  left: 4px;
  padding: 24px 14px;
  top: 50%;
  transform: translate(0, -50%);
  width: 46px;
  height: 221px;
  color: #fff;
  text-align: center;
  line-height: 26px;
  font-size: 18px;
  z-index: 100;
  border: solid 1px #31467d;
  border-left: none;
  color: #65c6e7;
}
.show {
  background: url('../../../assets/dashboard/icon_packup.png');
  width: 12px;
  height: 14px;
  transform: rotate(180deg);
  display: inline-block;
  background-size: contain;
}

.hide {
  background: url('../../../assets/dashboard/icon_packup.png');
  width: 12px;
  height: 14px;
  display: inline-block;
  background-size: contain;
}

.deviceInfoBox {
  table-layout: fixed;
  font-size: 16px;
  color: #fff;
  width: 100%;
  z-index: 50;
  text-align: center;
  transition: 500ms all ease-in;
  th {
    color: #65c6e7;
    white-space: nowrap;
  }
  td {
    color: #ffffff;
    white-space: nowrap;
  }
  .yellow {
    color: #dada09;
  }
  .green {
    color: #04ba19;
  }
}
.flex-row-center {
  display: flex;
  flex-direction: row;
  align-items: center;
}
.flex-row {
  display: flex;
  flex-direction: row;
}
.flex-col-center {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.network-container {
  height: 100%;
  overflow: auto;
  min-width: 38.4rem;
  background: url('./imgs/img_bg.png') no-repeat;
  background-size: 100% 100%;
  font-size: 50px;
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
  > div {
    width: 100%;
  }

  .network-center {
    position: relative;
    margin: 0.2rem 0.4rem 0 0.4rem;
    width: calc(100% - 0.8rem);
    min-height: 9.64rem;
    flex: 1;
    overflow: hidden;
    &:before {
      content: '';
      display: block;
      height: 0.5rem;
      width: 0.5rem;
      position: absolute;
      background: url('./imgs/img_map_bg_01.png') no-repeat;
      background-size: 100% 100%;
      left: 3px;
      top: 3px;
      z-index: 99;
    }
    img {
      position: absolute;
      background-size: 100% 100%;
      height: 0.5rem;
      width: 0.5rem;
      z-index: 99;
    }
    > img:nth-child(1) {
      right: 3px;
      top: 3px;
    }
    > img:nth-child(2) {
      right: 3px;
      bottom: 2px;
    }
    &:after {
      content: '';
      height: 0.5rem;
      width: 0.5rem;
      position: absolute;
      background: url('./imgs/img_map_bg_03.png') no-repeat;
      background-size: 100% 100%;
      bottom: 2px;
      left: 3px;
      z-index: 99;
    }
    .network-center-content {
      border: solid 0.02rem #31467d;
      width: calc(100% - 0.12rem);
      height: 100%;
      margin: 0.06rem;
      overflow: hidden;
      padding-left: 60px;
    }
    .page-bar {
      position: absolute;
      right: 0;
      bottom: 0;
      margin-right: 10px;
      margin-bottom: 10px;
      /deep/.el-pagination.is-background .btn-prev,
      /deep/.el-pagination.is-background .btn-next,
      /deep/.el-pagination.is-background .el-pager li {
        background-color: #04162a;
        border: solid 1px #31467d;
        color: #2bfaff;
        margin: 0 3px;
      }
      /deep/.el-pagination.is-background .el-pager li:not(.disabled).active {
        background-color: #43d5d7;
      }
    }
  }
}
</style>

JS

table輪詢的方法:web

methods: {
    activeEve(val) {
      this.scroll = val 
      const self = this,
        wrapH = this.$refs.scrollBox.clientHeight,
        sel = this.$refs.scroll,
        tbody = sel.children[0],
        tbodyH = tbody.clientHeight
      let timer_s = null,
        step = 0

      if (this.scroll && tbodyH > wrapH) {
        if (self.timer) clearTimeout(self.timer)
        cycle()
      } else {
        if (self.timer) clearTimeout(self.timer)
      }

      function cycle() {
        if (self.timer) clearTimeout(self.timer)
        self.timer = setTimeout(function() {
          scroll()
        }, 2000)
      }

      function scroll() {
        cancelAnimationFrame(timer_s)
        timer_s = requestAnimationFrame(function fn() {
          if (!tbody.children || !tbody.children.length) return
          const trH = tbody.children[0].clientHeight
          if (Math.abs(step) > trH) {
            cancelAnimationFrame(timer_s)
            step = 0
            sel.style.marginTop = 0
            tbody.appendChild(tbody.firstChild)
            cycle()
          } else {
            step--
            sel.style.marginTop = `${step}px`
            timer_s = requestAnimationFrame(fn)
          }
        })
      }
    }
  }

至此,table輪詢功能已經實現。
過了一段時間,老大又說先不用輪詢,用滾動條代替。app

css修改默認滾動條樣式

在原來的基礎上,只須要一點小改動就能夠實現,下面是css實現:ide

css

.scroll-box {
  width: 100%;
  height: 510px;
  overflow: hidden;
  overflow-y: scroll;
  position: relative;
  // 修改默認滾動條樣式
  // 修改默認滾動條樣式
  &::-webkit-scrollbar {/*滾動條總體樣式*/
    width: 6px;         /*高寬分別對應橫豎滾動條的尺寸*/
    height: 6px;
    background: transparent;
  }

  &::-webkit-scrollbar-thumb {/*滾動條裏面小方塊*/
    background: transparent;
    border-radius: 4px;
  }

  &:hover::-webkit-scrollbar-thumb {
    background: hsla(0, 0%, 53%, 0.4);
  }

  &:hover::-webkit-scrollbar-track {/*滾動條裏面軌道*/
    background: hsla(0, 0%, 53%, 0.1);
  }
  // 若是須要輪詢table,請註釋掉上面的,放開下面的
  width: 100%;
  height: 100%;
  overflow: hidden;
  position: relative;
}

好了,這樣就能夠了,鼠標移入的時候會出現,下面是效果:
滾動條.pngflex

相關文章
相關標籤/搜索