原生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日

相关文章

  • Vue 监听元素前后变化值实例

    下面是Vue监听元素前后变化值实例的完整攻略。 1. 监听Vue中元素的前后变化值 在Vue中,我们可以利用watch属性来监听元素的前后变化值。实现方式如下: watch: { value: function (newVal, oldVal) { console.log(`Value 值由 ${oldVal} 变为 ${newVal}`) } } 上述代码…

    css 2023年6月11日
    00
  • FF浏览器下float换行的问题解决方法(IE和Chrome正常)

    以下是针对“FF浏览器下float换行的问题解决方法”完整攻略: 问题描述 在浏览器中使用CSS中的float属性进行布局时,往往会出现在Firefox浏览器中,因为宽度不足导致两个块无法并列,而被迫换行的问题。而在IE和Chrome中则会正常显示。针对这种情况,需要进行特别的处理。 解决方法 方法1:增加可用宽度 在Firefox浏览器下,当宽度不足时会出…

    css 2023年6月9日
    00
  • CSS字体属性全解析

    CSS字体属性全解析 在CSS中,字体属性是一组用于控制文本字体的属性。本攻略将详细讲解CSS字体属性,包括基本原理、使用方法和示例说明。 1. 基本原理 CSS字体属性是一组用于控制文本字体的属性,包括字体类型、字体大小、字体样式、字体粗细等。具体来说,CSS字体属性包括以下几个: font-family:字体类型。 font-size:字体大小。 fon…

    css 2023年5月18日
    00
  • 几种响应式文字详解

    几种响应式文字详解 在响应式设计中,文字也是一个重要的组成部分。为了让不同大小的屏幕都能正常显示,需要采用一些响应式的文本技巧,下面是几种响应式文字的详细介绍。 1. 使用媒体查询 媒体查询是一种可以根据屏幕宽度等参数来改变样式的代码。在响应式设计中,我们可以利用媒体查询来改变字体的大小和行距等属性,以适应不同屏幕大小。 @media screen and …

    css 2023年6月10日
    00
  • 纯css实现更改图片颜色的技巧

    当我们需要更改图片颜色时,往往可以使用Photoshop等工具来进行编辑,但在一些特殊场景下,使用纯CSS来进行图片颜色更改是非常方便和实用的。接下来,我将为大家介绍纯CSS实现更改图片颜色的技巧。 目录 需要注意的事项 CSS filter CSS blend-mode 示例说明 使用CSS filter更改图片颜色 使用CSS blend-mode更改图…

    css 2023年6月9日
    00
  • js 提交form表单和设置form表单请求路径的实现方法

    JS提交Form表单和设置Form表单请求路径的实现方法是前端开发中比较基础的一个功能,本文将详细讲解实现的方法和步骤。 首先,我们需要了解Form表单的结构以及JS如何调用Form表单提交功能。Form表单的结构通常包含form标签、input标签、button标签等,其各属性分别为:form标签的action属性表示表单提交请求的路径;method属性表…

    css 2023年6月11日
    00
  • ie6 position:fixed解决方案

    “ie6 position:fixed解决方案”是针对Internet Explorer 6浏览器下不支持CSS中position属性值为fixed的解决方法。该方案基于JavaScript实现,通过在网页加载时给需要固定位置的元素赋值一个绝对位置,并在浏览器滚动时不断调整元素位置,从而达到与position:fixed相似的效果。 下面是实现该方案的完整攻…

    css 2023年6月9日
    00
  • 第一次接触神奇的Bootstrap

    Bootstrap是一种用于创建响应式、移动设备优先的Web应用程序的强大框架。对于新手来说,初次接触Bootstrap可能会感到有些挑战,但只要您按照以下步骤操作,就可以在不到几个小时内学会使用Bootstrap。 步骤一:准备工作 在开始学习Bootstrap之前,您需要执行以下准备工作:1. 确定您的开发环境:您需要一个文本编辑器,一个Web服务器和一…

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