最新要闻

广告

手机

光庭信息跌4.57% 2021上市超募11亿2022扣非降74% 时快讯

光庭信息跌4.57% 2021上市超募11亿2022扣非降74% 时快讯

搜狐汽车全球快讯 | 大众汽车最新专利曝光:仪表支持拆卸 可用手机、平板替代-环球关注

搜狐汽车全球快讯 | 大众汽车最新专利曝光:仪表支持拆卸 可用手机、平板替代-环球关注

家电

记录--让整个网站界面无滚动条

来源:博客园

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

界面无滚动条

滚动条的优化也有很多种,比如随便再网上搜索美化浏览器滚动条样式,就会出现些用css去美化滚动条的方案。 那种更好呢?


(资料图片)

没有更好只有更合适

  • 像默认的滚动条的话,他能让你方便摁着往下滑动(他比较宽)特别省劲,不用担心美化过后变细摁不到问题。
  • 美化后的滚动条样式啊更贴合网站主题,让用户体验更好。
  • 无滚动条(鼠标放上去后出现)这种更适合像一个页面好多个块,每个块的话还很多内容(都有滚动条)。如果像这种都默认都出现滚动条的话,也太不美观了。

那咱们就从无滚动条展开说说!!!

无滚动条设计

比如像element ui组件内像input的自定义模块数据过多的时候出现的下拉框内的滚动条,如下图:

element-ui里面它其实是有内部组件el-scrollbar在的。那么它是怎么实现无滚动条呢?

如下图咱们先把:hover勾选上让滚动条一直处于显示得状态。然后咱们再分析他的实现。

当我把样式稍微修改下,咱们再观察下图:

这么看是不是就很明白了 他其实用margin值把整个容器扩大了点然后溢出隐藏,其实滚动条还在就是给界面上看不到了而已。

然后它自己用dom画了个滚动条,如下图:

经过上面分析,咱们已经很清楚得了解到一个无滚动条是从那个方面实现得了。

  1. 使用margin值把滚动条给溢出隐藏掉。
  2. 使用div自己画了一个滚动条。方便咱们隐藏、显示、更改样式等。

无滚动条实现

那咱们再从细节上拆分下具体实现要考虑那些点:

  1. 需要计算滚动条得宽度用来margin扩大得距离(每个界面上得滚动条得宽度是不一样得)。
  2. 需要计算画的div滚动条得高度(这个内容多少会影响滚动条的高度)。
  3. 需要根据滚动条去transform: translateY(19.3916%);移动咱们自己画的div滚动条的。
  4. 需要根据摁着画的div滚动条,去实际更改需要滚动的高度。
  5. 需要点击滚动轴的柱子支持跳到目标的滚动位置;

一 计算界面原本滚动条的宽度

计算下界面上原本滚动条的宽度如下:

let scrollBarWidth;export default function() {  if (scrollBarWidth !== undefined) return scrollBarWidth;  const outer = document.createElement("div");  outer.className = "el-scrollbar__wrap";  outer.style.visibility = "hidden";  outer.style.width = "100px";  outer.style.position = "absolute";  outer.style.top = "-9999px";  document.body.appendChild(outer);  const widthNoScroll = outer.offsetWidth;  outer.style.overflow = "scroll";  const inner = document.createElement("div");  inner.style.width = "100%";  outer.appendChild(inner);  const widthWithScroll = inner.offsetWidth;  outer.parentNode.removeChild(outer);  scrollBarWidth = widthNoScroll - widthWithScroll;  return scrollBarWidth;};

先创建了一个div, 设置成scroll, 然后再在里面嵌套一个没有滚动条的div设置宽度100%, 获取到两者的offsetWidth, 相减获取到scrollBarWidth赋值给scrollBarWidth是惰性加载的优化,只需要计算一次就可以了。 具体展现如下图:

二 计算画的滚动条的高度height

计算下画的div滚动条的高度height。是用当前容器的内部高度 / 容器整个滚动条的高度 * 100计算出百分比;

比如:

const warp = this.$refs.wrap; // 或者使用documnet获取容器const heightPercentage = (wrap.clientHeight * 100 / wrap.scrollHeight); // heightconst widthPercentage = (wrap.clientWidth * 100 / wrap.scrollWidth); // width

解析: 如当前容器高30px,内容撑起来总共高100px,那么滚动条的高度就是当前容器的30%;

三 计算滚动条需要移动的值

计算画的div需要滚动条的高度moveY是, 获取当前容器滚动的scrollTop/ 当前容器内部高度 * 100

算法一:

解析 使用transform: translateY(0%);是移动的是自己本身的百分比那么(容器滚动的scrollTop/ 当前容器内部高度 * 100)算法如下:

const warp = this.$refs.wrap; // 或者使用documnet获取容器this.moveY = ((wrap.scrollTop * 100) / wrap.clientHeight);this.moveX = ((wrap.scrollLeft * 100) / wrap.clientWidth);

算法二:

解析:使用定位top值,这个比较好理解滚动条的滚动 / 容器的滚动总高度 * 100得到百分比,如下:

const warp = this.$refs.wrap; // 或者使用documnet获取容器this.moveY = ((wrap.scrollTop * 100) / wrap.scrollHeight);this.moveX = ((wrap.scrollLeft * 100) / wrap.scrollWidth);

把计算出来的moveYmoveX的方法 绑定给scroll滚动事件就可以了。

四 摁着画的div滚动条 经行拖动

滚动条都是支持拖着上下左右移动的,那咱们也要支持下:

  • 获取当前滚动条的高度或者宽度可以使用getBoundingClientRect()如下图:
  • 获取拖着移动的距离 就是再鼠标摁下先计一个当前的x1、y1监听movex2、y2相减就是拖动的距离了。
  • 获取到拖动的距离后转成transform || top值。

一个简单的拖动组件如下:

<script>export default {  name: "DraggableComponent",  props: {    initialValue: {      type: Object,      required: false,      default: () => ({ x: 0, y: 0 }),    },  },  data() {    return {      currentValue: { x: 0, y: 0 },      isDragging: false,      startX: 0,      startY: 0,      diffX: 0,      diffY: 0,    };  },  computed: {    style() {      return `left: ${this.currentValue.x + this.diffX}px; top: ${this.currentValue.y + this.diffY}px`;    },  },  watch: {    initialValue: {      handler(val) {        this.currentValue = val;      },      immediate: true,    },  },  mounted() {    this.$nextTick(() => {      const { draggableRef } = this.$refs;      if (draggableRef) {        draggableRef.addEventListener("mousedown", this.startDrag);        document.addEventListener("mousemove", this.moveDrag);        document.addEventListener("mouseup", this.endDrag);      }    });  },  beforeDestroy() {    const { draggableRef } = this.$refs;    draggableRef.removeEventListener("mousedown", this.startDrag);    document.removeEventListener("mousemove", this.moveDrag);    document.removeEventListener("mouseup", this.endDrag);  },  methods: {    startDrag({ clientX: x1, clientY: y1 }) {      this.isDragging = true;      document.onselectstart = () => false;      this.startX = x1;      this.startY = y1;    },    moveDrag({ clientX: x2, clientY: y2 }) {      if (this.isDragging) {        this.diffX = x2 - this.startX;        this.diffY = y2 - this.startY;      }    },    endDrag() {      this.isDragging = false;      document.onselectstart = () => true;      this.currentValue.x += this.diffX;      this.currentValue.y += this.diffY;      this.diffX = 0;      this.diffY = 0;    },  },};</script>

咱们需要获取到画的滚动条的高度,然后根据拖动的距离算出来transform: translateY(0%);或者top值;如上面拖动组件 拖动部分代码就不在重复了 咱们直接用diffX、diffY、lastX、lastY来用了。

  • diffX、diffY是拖动差的值
  • lastX、lastY是上一次也就是未拖动前的值translateY || top

算法一(transform)

const thumb = document.querySelector("el-scrollbar__thumb"); // element ui  el-scrollbar 的滚动条const { height: thumbHeight } = thumb?.getBoundingClientRect() || {};const diffY = 10;const lastY = "300"; // transform: translateY(300%);`const moveY = (diffY / thumbHeight) + lastY;
算法二(top)
const thumb = document.querySelector("el-scrollbar__thumb"); // element ui  el-scrollbar 的滚动条const { height: thumbHeight } = thumb?.getBoundingClientRect() || {};const diffY = 10;const lastY = 30; // top: 30%`const moveY = (diffY / wrap.scrollWidth * 100) + lastY;

五 点击滚动轴使滚动条跳转到该位置

  • getBoundingClientRect 的 top 是获取到距离浏览器顶部的距离。 写一个点击事件如下
function clickTrackHandler(event) {  const wrap = this.$refs.wrap;  // 1. 减去clientX  正好能获取到需要滚动到的位置 const offset = Math.abs(e.target.getBoundingClientRect().top - e.clientX); // 2. 利用offset 的到画的滚动条的实际位置 两种算法transform || top  const thumb = document.querySelector("el-scrollbar__thumb"); // element ui  el-scrollbar 的滚动条  const { height: thumbHeight } = thumb?.getBoundingClientRect() || {};  const translateY = offset / height * 100; // transform   const top = offset / wrap.scrollHeight * 100; // top  // 3、计算实际需要滚动的高度 使界面滚动到该位置。两种算法transform(scrollTop2) || top(scrollTop1)  const scrollTop1 = top * wrap.scrollHeight; // top  const scrollTop2 = translateY * wrap.clientHeight; // transform}

本文转载于:

https://juejin.cn/post/7227033124856135738

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

关键词: