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

news2024/9/24 11:27:26

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

界面无滚动条

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

没有更好只有更合适

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

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

无滚动条设计

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

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

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

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

01.jpg

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

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

02.jpg

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

  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 是惰性加载的优化,只需要计算一次就可以了。 具体展现如下图:

03.jpg

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

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

比如:

const warp = this.$refs.wrap; // 或者使用documnet获取容器
const heightPercentage = (wrap.clientHeight * 100 / wrap.scrollHeight); // height
const 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值。

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

<template>
  <div
    ref="draggableRef"
    class="draggable"
    :style="style"
  >
    <slot />
  </div>
</template>

<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>

<style>
.draggable {
  position: fixed;
  z-index: 9;
}
</style>

咱们需要获取到画的滚动条的高度,然后根据拖动的距离算出来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

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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/710471.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【网络安全入门】001、基础入门-概念名词

文章目录 基础入门-概念名词1、域名&#xff08;1&#xff09;什么是域名&#xff08;2&#xff09;域名在哪里注册&#xff08;3&#xff09;什么是二级域名多级域名&#xff08;4&#xff09;域名发现对于安全测试的意义&#xff1f; 2、DNS&#xff08;1&#xff09;什么是D…

C语言编程:坐标系的平移和旋转

本文总结博主在工作中遇到的坐标系转换相关问题&#xff0c;以及C语言编程实现。 文章目录 1 问题场景2 公式推导2.1 旋转坐标系推导2.2 平移坐标系推导2.3 完整公式 3 C语言编程 1 问题场景 对于ADAS算法开发&#xff0c;在工作中遇到过很多需要坐标系转换的场景。例如&…

进制转换(十进制与十六进制互转)

之前的一家公司基本上都是基于单片机进行开发&#xff0c;一般与上位机的通信都是按照自定义的协议进行操作&#xff0c;测试的时候会经常都对协议进行修改并且涉及到进制之间的转换&#xff0c;例如获取版本是十六进制的需要转换成十进制的版本信息&#xff0c;例如修改时间需…

013-从零搭建微服务-认证中心(五)

写在最前 如果这个项目让你有所收获&#xff0c;记得 Star 关注哦&#xff0c;这对我是非常不错的鼓励与支持。 源码地址&#xff08;后端&#xff09;&#xff1a;https://gitee.com/csps/mingyue 源码地址&#xff08;前端&#xff09;&#xff1a;https://gitee.com/csps…

LoRa模块(SX1278)详解

LoRa模块&#xff08;SX1278&#xff09; 0. LoRa概述概念LoRa技术的主要特点LoRa技术的工作原理 1. 常见的LoRa模块2. Semtech SX12783. STM32使用SX1278方法示例代码 0. LoRa概述 概念 LoRa&#xff08;Long Range&#xff09;是一种长距离、低功耗的无线通信技术&#xff…

被劫持的礼物

根据题目其实也猜得到这道题的大致考察内容 下载好后得到一个wireshark的流量文件 根据提示&#xff0c;flag是账号和密码组合的MD5值&#xff0c;想到登录&#xff0c;其实就想到两个登录框 也就是POST请求方法 打开文件后会也会得到一些 http的包&#xff0c;过滤一下 查看到…

线性DP—入门篇

线性动态规划的主要特点是状态转移的推导是按照问题规模 从小到大依次推导&#xff0c;较大规模的问题的解依赖较小规模的问题的解。 数字三角形&#xff1a; [USACO1.5][IOI1994]数字三角形 Number Triangles - 洛谷https://www.luogu.com.cn/problem/P1216我们来看一道经典…

ModaHub魔搭社区:向量数据库Milvus产品问题(三)

目录 Milvus 的数据落盘逻辑是怎样的&#xff1f; Mishards 推荐的配置是什么&#xff1f; Mishards 支持 RESTful API 吗&#xff1f; 什么是归一化&#xff1f;Milvus 中为什么有时候需要归一化&#xff1f; 为什么欧氏距离和内积在计算向量相似度时的结果不一致&#x…

【Git原理与使用】-- 分支管理

目录 理解分支 创建分支 查看当前分支 创建本地分支 切换分支 合并分支 删除分支 合并冲突 分支管理策略 分支策略 bug 分支 不建议的合并方式 建议的合并方式 第一步 第二步 删除临时分支 理解分支 分支就是科幻电影里面的平行宇宙&#xff0c;当你正在电脑前…

java 全局、局部异常处理详解及result结果封装

1、引入spring-boot-starter-web依赖和new-swagger依赖 <dependency><groupId>com.jjw</groupId><artifactId>new-swagger</artifactId><version>1.0-SNAPSHOT</version> </dependency> <dependency><groupId>or…

Linux系统编程:进程的替换

目录 一. 进程替换的原理 二. 进程替换的方法 2.1 进程替换的相关函数 2.2 进程替换为其它的C/C程序或其它语言编写的程序 三. 自主实现简单地命令行解释器 四. 总结 一. 进程替换的原理 进程替换&#xff0c;就是对进程所执行的代码进行替换&#xff0c;让正在运行的一个…

华为OD机试真题 Python 实现【简单的自动曝光】【2023Q1 100分】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述四、备注五、解题思路六、Python算法源码七、效果展示1、输入2、输出3、说明4、再输入5、输出6、说明 一、题目描述 一个图像有 n 个像素点&#xff0c;存储在一个长度为 n 的数组 img 里&#xff0c;每个像素点的取值范围[0,255]的…

HOT33-排序链表

leetcode原题链接&#xff1a;排序链表 题目描述 给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [4,2,1,3] 输出&#xff1a;[1,2,3,4]示例 2&#xff1a; 输入&#xff1a;head [-1,5,3,4,0] 输出…

html内盒子长宽增加溢出但是外盒子不自动向下延

自动扩展 问题描述 外盒子设置固定px&#xff0c;导致内盒子如图片长宽增加后&#xff0c;溢出但是外盒子不自动扩展&#xff08;向下延申&#xff09; 图片高230时正常 设置250后超出 问题解决 /*height: 660px;*/ /*设死就不能自动扩展&#xff0c;内块块长宽超出&#x…

vuex-persistedstate —— 数据持久化

在之前的篇目当中对于 Vuex 中的相关内容都讲得差不多&#xff0c;但是在项目中去使用vuex&#xff0c;虽然数据状态得到管理了&#xff0c;但数据在每一次都需要去重新加载&#xff0c;那么对于数据的持久化vue是没有给解决的&#xff0c;而是通过第三方的工具去进行数据的持久…

代码随想录算法训练营第17期第4天(5休息) | 24. 两两交换链表中的节点、19. 删除链表的倒数第 N 个结点、面试题 02.07. 链表相交、​​​​​​142. 环形链表 II

目录 24. 两两交换链表中的节点 19. 删除链表的倒数第 N 个结点 面试题 02.07. 链表相交 ​​​​​​142. 环形链表 II 这题不是很难&#xff0c;目前除了从【.】变成了【->】之外&#xff0c;python和C也没啥区别 另外就是对虚拟头结点的掌握了 /*** Definition for …

爬虫小白入门在服务器上-部署爬虫或者开服务接口并供给他人访问

目录 一、准备工作-服务器1、先准备一个服务器&#xff08;以阿里云为例子&#xff09;2、开通服务端口号访问权限 二、准备工作-Xshell登录服务器1、xshell基本登录操作2、xftp基本操作 三、部署代码到服务器上1、部署一个python爬虫脚本在服务器上定时运行等2、部署一个pytho…

Java-API简析_占位符类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/131504916 出自【进步*于辰的博客】 因为我发现目前&#xff0c;我对Java-API的学习意识比较薄弱…

区块链开发:JS/TS本地|项目环境搭建

区块链开发&#xff1a;JS/TS本地|项目环境搭建 本地环境搭建VSCode Solidity扩展全局安装Solc,corepackVSCode配置本地Solc安装Ganache搭建JS虚拟环境 项目测试安装依赖编写代码部署合约test_blockchain.ts 设置Script部署查看 报错说明1. Error&#xff1a;missing revert da…

【EasyX】使用C/C++实现 流星雨效果(配上详细注释解释)

&#x1f38a;专栏【​​​​​​​EasyX】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【Love Story】 &#x1f970;大一同学小吉&#xff0c;欢迎并且感谢大家指出我的问题&#x1f970; 文章目录 &#x1f354;效果&#x…