原生js仿浏览器滚动条效果

我们来详细讲解在原生 JavaScript 中如何实现仿浏览器滚动条效果。

1. 设计实现思路

在实现仿浏览器滚动条的效果时,需要考虑以下几个方面:

  1. 创建滚动条:根据需要创建一个滚动条,并设置它的高度和样式。
  2. 监听内容滚动:监听页面内容的滚动事件。
  3. 计算滑块位置:根据内容滚动的位置和内容高度,计算出滑块的位置。
  4. 移动滑块:根据计算得出的滑块位置,改变滑块的样式使其滑动。

2. 创建滚动条

创建滚动条时,需要创建两个 div 元素,一个作为滑道,另一个作为滑块,如下所示:

<div class="scrollbar">
  <div class="slider"></div>
</div>

然后为这两个元素设置样式,使它们能够正确地显示在页面上。需要注意的是,滑道的高度应该等于内容区域的高度,而滑块的高度应该是一个比例,比例的大小为滑块能够滑移的区域长度和滑道长度之比。

.scrollbar {
  position: relative;
  height: 200px; /* 设置滑道高度 */
  overflow-y: scroll; /* 开启垂直滚动条 */
}

.slider {
  position: absolute;
  top: 0;
  right: 0;
  width: 10px;
  height: calc(200px * 200px / 10000); /* 计算滑块高度 */
  background-color: #ccc;
  cursor: pointer;
  border-radius: 5px;
}

3. 监听内容滚动

使用原生 JavaScript,可以通过在内容区域上绑定 scroll 事件来监听内容的滚动。

const content = document.querySelector('.content');
const slider = document.querySelector('.slider');

content.addEventListener('scroll', e => {
  // do something
});

4. 计算滑块位置

计算滑块位置的核心是确定内容区域的滚动位置和内容区域的高度,然后通过它们来计算滑块位置。具体实现如下:

function calculateSliderPosition() {
  const content = document.querySelector('.content');
  const slider = document.querySelector('.slider');

  // 获取内容区域高度
  const contentHeight = content.scrollHeight;

  // 获取滑块能够滑动的最大距离
  const maxSliderDistance = slider.parentElement.offsetHeight - slider.offsetHeight;

  // 计算滑块位置
  const sliderPosition = (content.scrollTop / contentHeight) * maxSliderDistance;

  // 设置滑块位置
  slider.style.top = `${sliderPosition}px`;
}

5. 移动滑块

当计算出滑块位置后,还需要更新滑块的样式,让它能够滑动。这可以通过改变滑块的 top 样式来实现,如下所示:

function moveSlider() {
  const content = document.querySelector('.content');
  const slider = document.querySelector('.slider');

  // 获取内容区域高度
  const contentHeight = content.scrollHeight;

  // 获取滑块能够滑动的最大距离
  const maxSliderDistance = slider.parentElement.offsetHeight - slider.offsetHeight;

  // 计算滑块位置
  const sliderPosition = (content.scrollTop / contentHeight) * maxSliderDistance;

  // 移动滑块
  slider.style.top = `${sliderPosition}px`;
}

示例

我们可以利用以上的步骤,实现一个简单的仿浏览器滚动条效果,代码如下:

<html>
  <head>
    <style>
      .wrapper {
        position: relative;
        height: 200px;
        width: 200px;
        overflow: hidden;
      }

      .content {
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        padding-right: 10px;
        overflow-y: scroll;
      }

      .scrollbar {
        position: absolute;
        top: 0;
        bottom: 0;
        right: 0;
        width: 10px;
      }

      .slider {
        position: absolute;
        top: 0;
        right: 0;
        width: 10px;
        background-color: #ccc;
        border-radius: 5px;
        cursor: pointer;
      }
    </style>
  </head>

  <body>
    <div class="wrapper">
      <div class="content">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius ipsum sed faucibus consectetur. Cras fringilla sapien et felis vehicula consectetur. Nam eu ex lectus. Curabitur auctor fermentum lectus. Aliquam nec mollis odio, in tincidunt tellus. Sed bibendum justo a sapien euismod accumsan. Quisque tincidunt sapien ante, eget consectetur erat aliquet vehicula. Etiam convallis posuere justo, in pretium nulla maximus eu. Suspendisse eget justo faucibus, molestie tortor et, feugiat odio.</p>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius ipsum sed faucibus consectetur. Cras fringilla sapien et felis vehicula consectetur. Nam eu ex lectus. Curabitur auctor fermentum lectus. Aliquam nec mollis odio, in tincidunt tellus. Sed bibendum justo a sapien euismod accumsan. Quisque tincidunt sapien ante, eget consectetur erat aliquet vehicula. Etiam convallis posuere justo, in pretium nulla maximus eu. Suspendisse eget justo faucibus, molestie tortor et, feugiat odio.</p>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius ipsum sed faucibus consectetur. Cras fringilla sapien et felis vehicula consectetur. Nam eu ex lectus. Curabitur auctor fermentum lectus. Aliquam nec mollis odio, in tincidunt tellus. Sed bibendum justo a sapien euismod accumsan. Quisque tincidunt sapien ante, eget consectetur erat aliquet vehicula. Etiam convallis posuere justo, in pretium nulla maximus eu. Suspendisse eget justo faucibus, molestie tortor et, feugiat odio.</p>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius ipsum sed faucibus consectetur. Cras fringilla sapien et felis vehicula consectetur. Nam eu ex lectus. Curabitur auctor fermentum lectus. Aliquam nec mollis odio, in tincidunt tellus. Sed bibendum justo a sapien euismod accumsan. Quisque tincidunt sapien ante, eget consectetur erat aliquet vehicula. Etiam convallis posuere justo, in pretium nulla maximus eu. Suspendisse eget justo faucibus, molestie tortor et, feugiat odio.</p>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius ipsum sed faucibus consectetur. Cras fringilla sapien et felis vehicula consectetur. Nam eu ex lectus. Curabitur auctor fermentum lectus. Aliquam nec mollis odio, in tincidunt tellus. Sed bibendum justo a sapien euismod accumsan. Quisque tincidunt sapien ante, eget consectetur erat aliquet vehicula. Etiam convallis posuere justo, in pretium nulla maximus eu. Suspendisse eget justo faucibus, molestie tortor et, feugiat odio.</p>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius ipsum sed faucibus consectetur. Cras fringilla sapien et felis vehicula consectetur. Nam eu ex lectus. Curabitur auctor fermentum lectus. Aliquam nec mollis odio, in tincidunt tellus. Sed bibendum justo a sapien euismod accumsan. Quisque tincidunt sapien ante, eget consectetur erat aliquet vehicula. Etiam convallis posuere justo, in pretium nulla maximus eu. Suspendisse eget justo faucibus, molestie tortor et, feugiat odio.</p>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius ipsum sed faucibus consectetur. Cras fringilla sapien et felis vehicula consectetur. Nam eu ex lectus. Curabitur auctor fermentum lectus. Aliquam nec mollis odio, in tincidunt tellus. Sed bibendum justo a sapien euismod accumsan. Quisque tincidunt sapien ante, eget consectetur erat aliquet vehicula. Etiam convallis posuere justo, in pretium nulla maximus eu. Suspendisse eget justo faucibus, molestie tortor et, feugiat odio.</p>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius ipsum sed faucibus consectetur. Cras fringilla sapien et felis vehicula consectetur. Nam eu ex lectus. Curabitur auctor fermentum lectus. Aliquam nec mollis odio, in tincidunt tellus. Sed bibendum justo a sapien euismod accumsan. Quisque tincidunt sapien ante, eget consectetur erat aliquet vehicula. Etiam convallis posuere justo, in pretium nulla maximus eu. Suspendisse eget justo faucibus, molestie tortor et, feugiat odio.</p>
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam varius ipsum sed faucibus consectetur. Cras fringilla sapien et felis vehicula consectetur. Nam eu ex lectus. Curabitur auctor fermentum lectus. Aliquam nec mollis odio, in tincidunt tellus. Sed bibendum justo a sapien euismod accumsan. Quisque tincidunt sapien ante, eget consectetur erat aliquet vehicula. Etiam convallis posuere justo, in pretium nulla maximus eu. Suspendisse eget justo faucibus, molestie tortor et, feugiat odio.</p>
      </div>

      <div class="scrollbar">
        <div class="slider"></div>
      </div>
    </div>

    <script>
      function calculateSliderPosition() {
        const content = document.querySelector('.content');
        const slider = document.querySelector('.slider');

        const contentHeight = content.scrollHeight;
        const maxSliderDistance = slider.parentElement.offsetHeight - slider.offsetHeight;

        const sliderPosition = (content.scrollTop / contentHeight) * maxSliderDistance;

        slider.style.top = `${sliderPosition}px`;
      }

      const content = document.querySelector('.content');
      const slider = document.querySelector('.slider');

      content.addEventListener('scroll', () => {
        calculateSliderPosition();
      });

      slider.addEventListener('mousedown', e => {
        const startY = e.clientY;
        const startTop = parseInt(slider.style.top);

        const onMouseMove = e => {
          const distance = e.clientY - startY;
          const sliderPosition = Math.min(Math.max(0, startTop + distance), slider.parentElement.offsetHeight - slider.offsetHeight);
          const content = document.querySelector('.content');
          const contentHeight = content.scrollHeight;
          const maxSliderDistance = slider.parentElement.offsetHeight - slider.offsetHeight;
          const scrollTop = (sliderPosition / maxSliderDistance) * contentHeight;

          content.scrollTop = scrollTop;
          slider.style.top = `${sliderPosition}px`;
        };

        const onMouseUp = () => {
          document.removeEventListener('mousemove', onMouseMove);
          document.removeEventListener('mouseup', onMouseUp);
        };

        document.addEventListener('mousemove', onMouseMove);
        document.addEventListener('mouseup', onMouseUp);
      });
    </script>
  </body>
</html>

此代码模拟出一个包含滚动条的内容区域,在滑动滑块时会自动滚动内容区域,并且滑块位置也会随着内容区域的滚动而变化。同时,在鼠标按下滑块、拖动滑块和松开鼠标等过程中,滑块也能够正确地响应。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:原生js仿浏览器滚动条效果 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • javascript+css3开发打气球小游戏完整代码

    下面我来详细讲解“Javascript+CSS3开发打气球小游戏完整代码”的完整攻略。 准备工作 在开始前,我们需要准备以下工具和技术: HTML、CSS、Javascript基础知识 编辑器:推荐使用Visual Studio Code等代码编辑器 Firefox或Chrome浏览器 开始开发 第一步:构建游戏场景 我们首先需要构建游戏场景,包括背景、气球…

    css 2023年6月10日
    00
  • 彻底弄明白CSS3的Media Queries(跨平台设计)

    下面就为大家详细讲解“彻底弄明白CSS3的Media Queries(跨平台设计)”的完整攻略。 什么是 Media Queries Media Queries 是 CSS3 中的一个新特性,它允许我们在不同的设备、分辨率以及屏幕方向下,对网页的样式进行不同的设计和呈现。Media Queries 的出现,使得我们可以更加精细的设计网站,让网页在不同的设备上…

    css 2023年6月10日
    00
  • React 中使用 Redux 的 4 种写法小结

    React 中使用 Redux 的 4 种写法小结指的是在 React 中集成 Redux 的四种不同的方法。这四种方法分别是: 1.传统的用法(Traditional Way) 2.React-Redux 库的用法(Using React-Redux Library) 3.Redux Hooks 的用法(Using Redux Hooks) 4.Redux…

    css 2023年6月10日
    00
  • Webpack中雪碧图插件使用详解

    我为您详细介绍「Webpack中雪碧图插件使用详解」的完整攻略。 简介 在前端开发中,为了加快网站速度和优化用户体验,常常会使用雪碧图技术来减少图片请求次数。Webpack作为当前最流行的前端构建工具之一,提供了多个处理雪碧图的插件,本篇攻略将详细讲解如何使用Webpack中的雪碧图插件。 雪碧图插件介绍 Webpack中的雪碧图插件通常可以分为两类,分别是…

    css 2023年6月9日
    00
  • 完美解决jQuery fancybox ie 无法显示关闭按钮的问题

    针对这个问题,我将提供以下完整攻略来解决: 问题背景 当使用jQuery fancybox插件来展示图片或其他内容时,有时在IE浏览器中会出现无法显示关闭按钮的问题,即使已经给插件设置了相应参数。 解决方案 方案一:修改fancybox默认样式 使用Fancybox时,插件会自动添加一些样式到页面中。其中一个为“fancybox-close”样式,但是由于I…

    css 2023年6月9日
    00
  • 跟我学习javascript的prototype使用注意事项

    当使用JavaScript的面向对象编程时,prototype在实现继承和方法重载等方面起着关键作用。下面是跟我学习JavaScript的prototype使用注意事项的完整攻略。 什么是prototype? 在JavaScript中,每个对象都有一个prototype,原型链的顶端是Object.prototype对象。prototype对象定义了该对象的…

    css 2023年6月9日
    00
  • php制作动态随机验证码

    制作动态随机验证码是一个常见的网站验证码应用,它可以防止恶意攻击和机器批量注册。下面是实现该功能的完整攻略: 1. 生成随机字符串 首先需要生成一个随机的字符串作为验证码。可以使用PHP内置的md5()函数生成一个32位的随机字符串,也可以通过mt_rand()、rand()等随机数函数生成6~10位的随机字符串。 $code = substr(str_sh…

    css 2023年6月10日
    00
  • IE6/IE7下绝对定位position:absolute和margin的冲突问题解决

    针对IE6/IE7下绝对定位position:absolute和margin的冲突问题,一般可以采取以下三种解决方式: 解决方式一:使用相对定位做包裹层 首先,我们可以为需要布局的元素外层再套一层div,设置这个包裹层为position:relative; <div style="position:relative;"> &l…

    css 2023年6月9日
    00
合作推广
合作推广
分享本页
返回顶部