原生js封装自定义滚动条

下面我给你详细讲解“原生js封装自定义滚动条”的完整攻略。

步骤1:创建HTML结构

首先我们需要创建一个包含内容的元素和一个自定义滚动条的容器。

<div class="scroll-wrapper">
  <div class="scroll-content">
    <!-- 包含内容的元素 -->
  </div>
  <div class="scroll-track">
    <div class="scroll-bar"></div>
  </div>
</div>

其中,.scroll-wrapper是我们的自定义滚动条容器,.scroll-content是包含内容的元素,.scroll-track是滚动条轨道,.scroll-bar是滚动条。

步骤2:CSS样式

接下来我们需要设置各个元素的CSS样式。具体的样式可以根据自己的需要来调整,这里只展示一个基本的样式。

.scroll-wrapper {
  position: relative;
  overflow: hidden;
}

.scroll-content {
  width: 100%;
  height: 100%;
  overflow-y: scroll;
  padding-right: 16px; /* 减去滚动条的宽度 */
}

.scroll-track {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 10px; /* 滚动条的宽度 */
}

.scroll-bar {
  position: absolute;
  top: 0;
  width: 10px; /* 滚动条的宽度 */
  cursor: pointer;
  background-color: #ccc;
  border-radius: 5px;
}

步骤3:JS封装

使用原生JS封装自定义滚动条,大致的思路如下:

  1. 获取相关元素,包括内容元素、滚动条元素、滚动条轨道元素
  2. 计算滚动条的高度和位置
  3. 给滚动条绑定拖动事件,实现拖动滚动条滚动内容的效果
  4. 给内容元素绑定滚动事件,实现滚动内容时同时移动滚动条的效果

下面就是基本的JS代码:

function Scrollbar(container) {
  var content = container.querySelector('.scroll-content');
  var track = container.querySelector('.scroll-track');
  var bar = container.querySelector('.scroll-bar');

  var contentHeight = content.scrollHeight;
  var containerHeight = content.clientHeight;
  var trackHeight = track.clientHeight;
  var maxScrollTop = contentHeight - containerHeight;

  bar.style.height = (containerHeight / contentHeight) * trackHeight + 'px';

  var scrollRatio = maxScrollTop / (trackHeight - bar.clientHeight);

  bar.addEventListener('mousedown', function(e) {
    e.preventDefault();
    var startY = e.clientY;
    var startTop = parseInt(getComputedStyle(bar).top);

    document.addEventListener('mousemove', drag);
    document.addEventListener('mouseup', stopDrag);

    function drag(e) {
      var deltaY = e.clientY - startY;
      var newTop = startTop + deltaY;

      if (newTop < 0) {
        newTop = 0;
      }
      if (newTop + bar.clientHeight > trackHeight) {
        newTop = trackHeight - bar.clientHeight;
      }

      bar.style.top = newTop + 'px';
      content.scrollTop = newTop * scrollRatio;
    }

    function stopDrag() {
      document.removeEventListener('mousemove', drag);
      document.removeEventListener('mouseup', stopDrag);
    }
  });

  content.addEventListener('scroll', function() {
    bar.style.top = (content.scrollTop / scrollRatio) + 'px';
  });
}

var container = document.querySelector('.scroll-wrapper');
var scrollbar = new Scrollbar(container);

上述代码中,我们先获取了各个DOM元素,然后计算了滚动条的高度和滚动比例。接着给滚动条绑定了拖动事件,并且实现了拖动滚动条滚动内容的功能。最后给内容元素绑定了滚动事件,实现了滚动内容时同时移动滚动条的功能。

示例1:水平滚动条

如果需要创建一个水平滚动条的话,只需要修改一些CSS样式和JS代码即可。

首先是HTML结构:

<div class="scroll-wrapper horizontal">
  <div class="scroll-content">
    <!-- 包含内容的元素 -->
  </div>
  <div class="scroll-track">
    <div class="scroll-bar"></div>
  </div>
</div>

然后是CSS样式:

.scroll-wrapper.horizontal {
  overflow-x: scroll;
}

.scroll-wrapper.horizontal .scroll-content {
  white-space: nowrap;
  padding-bottom: 16px; /* 减去滚动条的高度 */
  padding-right: 0;
}

.scroll-wrapper.horizontal .scroll-track {
  height: 10px; /* 滚动条的高度 */
}

.scroll-wrapper.horizontal .scroll-bar {
  height: 10px; /* 滚动条的高度 */
  width: 100px;
}

最后是JS代码:

function Scrollbar(container) {
  var content = container.querySelector('.scroll-content');
  var track = container.querySelector('.scroll-track');
  var bar = container.querySelector('.scroll-bar');

  var contentWidth = content.scrollWidth;
  var containerWidth = content.clientWidth;
  var trackWidth = track.clientWidth;
  var maxScrollLeft = contentWidth - containerWidth;

  bar.style.width = (containerWidth / contentWidth) * trackWidth + 'px';

  var scrollRatio = maxScrollLeft / (trackWidth - bar.clientWidth);

  bar.addEventListener('mousedown', function(e) {
    e.preventDefault();
    var startX = e.clientX;
    var startLeft = parseInt(getComputedStyle(bar).left);

    document.addEventListener('mousemove', drag);
    document.addEventListener('mouseup', stopDrag);

    function drag(e) {
      var deltaX = e.clientX - startX;
      var newLeft = startLeft + deltaX;

      if (newLeft < 0) {
        newLeft = 0;
      }
      if (newLeft + bar.clientWidth > trackWidth) {
        newLeft = trackWidth - bar.clientWidth;
      }

      bar.style.left = newLeft + 'px';
      content.scrollLeft = newLeft * scrollRatio;
    }

    function stopDrag() {
      document.removeEventListener('mousemove', drag);
      document.removeEventListener('mouseup', stopDrag);
    }
  });

  content.addEventListener('scroll', function() {
    bar.style.left = (content.scrollLeft / scrollRatio) + 'px';
  });
}

var container = document.querySelector('.scroll-wrapper.horizontal');
var scrollbar = new Scrollbar(container);

示例2:带缓动效果的滚动条

如果需要让滚动条滚动的过程更加流畅,可以加上缓动效果。

首先是修改JS代码中的拖动事件:

function drag(e) {
  var deltaY = e.clientY - startY;
  var newTop = startTop + deltaY;

  if (newTop < 0) {
    newTop = 0;
  }
  if (newTop + bar.clientHeight > trackHeight) {
    newTop = trackHeight - bar.clientHeight;
  }

  var scrollTop = newTop * scrollRatio;

  animatedScroll(content, scrollTop);
}

function animatedScroll(element, scrollTop) {
  var start = element.scrollTop;
  var end = scrollTop;

  var startTime = performance.now();
  var duration = 500; // 滚动持续500ms

  requestAnimationFrame(function scroll(time) {
    var elapsed = time - startTime;

    if (elapsed < duration) {
      var position = easeInOutQuad(elapsed, start, end - start, duration);
      element.scrollTop = position;
      requestAnimationFrame(scroll);
    } else {
      element.scrollTop = end;
    }
  });
}

function easeInOutQuad(t, b, c, d) {
  t = t / (d / 2);
  if (t < 1) {
    return c / 2 * t * t + b;
  } else {
    t = t - 1;
    return -c / 2 * (t * (t - 2) - 1) + b;
  }
}

这里使用了requestAnimationFrame()performance.now()方法实现缓动效果。然后需要加上一个缓动函数easeInOutQuad(),这个函数可以根据需要修改,这里是一个缓慢开始,缓慢结束的二次函数。

最后是示例代码:

<div class="scroll-wrapper easing">
  <div class="scroll-content">
    <!-- 包含内容的元素 -->
  </div>
  <div class="scroll-track">
    <div class="scroll-bar"></div>
  </div>
</div>
.scroll-wrapper.easing .scroll-bar {
  transition: top 0.5s ease-out;
}

.scroll-wrapper.easing .scroll-content {
  scroll-behavior: smooth;
}
function Scrollbar(container) {
  var content = container.querySelector('.scroll-content');
  var track = container.querySelector('.scroll-track');
  var bar = container.querySelector('.scroll-bar');

  var contentHeight = content.scrollHeight;
  var containerHeight = content.clientHeight;
  var trackHeight = track.clientHeight;
  var maxScrollTop = contentHeight - containerHeight;

  bar.style.height = (containerHeight / contentHeight) * trackHeight + 'px';

  var scrollRatio = maxScrollTop / (trackHeight - bar.clientHeight);

  bar.addEventListener('mousedown', function(e) {
    e.preventDefault();
    var startY = e.clientY;
    var startTop = parseInt(getComputedStyle(bar).top);

    document.addEventListener('mousemove', drag);
    document.addEventListener('mouseup', stopDrag);

    function drag(e) {
      var deltaY = e.clientY - startY;
      var newTop = startTop + deltaY;

      if (newTop < 0) {
        newTop = 0;
      }
      if (newTop + bar.clientHeight > trackHeight) {
        newTop = trackHeight - bar.clientHeight;
      }

      var scrollTop = newTop * scrollRatio;

      animatedScroll(content, scrollTop);

      bar.style.top = newTop + 'px';
    }

    function stopDrag() {
      document.removeEventListener('mousemove', drag);
      document.removeEventListener('mouseup', stopDrag);
    }
  });

  content.addEventListener('scroll', function() {
    bar.style.top = (content.scrollTop / scrollRatio) + 'px';
  });
}

function animatedScroll(element, scrollTop) {
  var start = element.scrollTop;
  var end = scrollTop;

  var startTime = performance.now();
  var duration = 500; // 滚动持续500ms

  // 动画函数
  requestAnimationFrame(function scroll(time) {
    var elapsed = time - startTime;

    if (elapsed < duration) {
      var position = easeInOutQuad(elapsed, start, end - start, duration);
      element.scrollTop = position;
      requestAnimationFrame(scroll);
    } else {
      element.scrollTop = end;
    }
  });
}

function easeInOutQuad(t, b, c, d) {
  t = t / (d / 2);
  if (t < 1) {
    return c / 2 * t * t + b;
  } else {
    t = t - 1;
    return -c / 2 * (t * (t - 2) - 1) + b;
  }
}

var container = document.querySelector('.scroll-wrapper.easing');
var scrollbar = new Scrollbar(container);

以上就是“原生js封装自定义滚动条”的详细攻略,希望能对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:原生js封装自定义滚动条 - Python技术站

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

相关文章

  • 详解Html5项目适配系统深色模式方案总结

    详解Html5项目适配系统深色模式方案总结 背景 随着黑暗模式的流行,越来越多的用户开始期望网站、应用程序能够在深色模式下提供更好的用户体验。因此,在Html5项目中实现深色模式的适配变得非常重要。 需要适配的内容 下面是需要适配的内容: 文本颜色 背景颜色 边框颜色 图像 方案总结 使用 CSS 变量 使用CSS变量是实现深色模式的推荐方法之一。CSS变量…

    css 2023年6月9日
    00
  • 基于Bootstrap3表格插件和分页插件实例详解

    关于“基于Bootstrap3表格插件和分页插件实例详解”的攻略,可以按照以下步骤进行: 1. 确认所需库文件 在使用Bootstrap3表格插件和分页插件之前,需要在网页中引入相关的库文件,包括Bootstrap、jQuery和bootstrap-table等,可使用CDN或下载到本地引用。 示例引入CDN文件的代码如下: <!DOCTYPE htm…

    css 2023年6月10日
    00
  • JavaScript中HTML元素操作的实现

    在JavaScript中,我们可以使用DOM(Document Object Model)API操作HTML元素。DOM是Web页面的基本编程接口,它将HTML文档表示为一个树形结构,开发人员可以通过JavaScript操作该树形结构中的各个节点来修改HTML页面。 1. 查找HTML元素 要想操作HTML元素,首先需要找到该元素对应的DOM节点。我们可以使…

    css 2023年6月9日
    00
  • 用CSS实现Tab页切换效果的示例代码

    下面我将详细讲解如何用CSS实现Tab页切换效果的示例代码的完整攻略。 1. HTML结构 首先,在HTML中需要定义Tab选项卡的基本结构。我们需要一个Tab容器(通常是一个div元素),里面包含若干个Tab选项卡。每个Tab选项卡需要一个标题和对应的内容部分。基本结构如下: <div class="tab-container"&…

    css 2023年6月9日
    00
  • 浅析Bootstrap缩略图组件与警示框组件

    浅析Bootstrap缩略图组件与警示框组件 Bootstrap是一个经典的前端框架,提供了许多实用的组件和工具。本文将为大家介绍Bootstrap中的缩略图组件和警示框组件。 缩略图组件 在Bootstrap中,缩略图组件一般用于显示一组图片或者视频的缩略图,非常适合用于多媒体网站、电商网站等等。 基本用法 缩略图组件的基本代码如下: <div cl…

    css 2023年6月11日
    00
  • CSS仿网易首页的头部菜单栏按钮和三角形制作方法

    下面是关于”CSS仿网易首页的头部菜单栏按钮和三角形制作方法”的完整攻略。 制作按钮 制作按钮可以使用CSS中的伪元素::before和::after来实现。 第一步 首先,在HTML中添加一个button元素,并给它一个class名称,例如menu-btn。 <button class="menu-btn">菜单</b…

    css 2023年6月10日
    00
  • css强制换行 css强制不换行的css方法

    下面是关于CSS强制换行和强制不换行的攻略: CSS强制换行 CSS中可以使用”word-wrap”或”word-break”属性来强制换行。 word-wrap属性 “word-wrap”属性指定了当一个单词太长时,是否允许这个单词断行到下一行。可以设置的值有: normal:默认值。只有在遇到可换行点或允许断字点的时候才换行。 break-word:允许…

    css 2023年6月10日
    00
  • JavaScript改变HTML元素的样式改变CSS及元素属性

    JavaScript可以用来操作HTML元素,这包括改变元素的样式以及元素的属性。我们可以使用JavaScript来动态地改变网页的展示效果和交互性。下面是改变HTML元素的样式和属性的完整攻略。 改变HTML元素的样式 通过JavaScript设置CSS样式 可以使用JavaScript代码来操控CSS样式,以改变HTML元素的外观和表现。JavaScri…

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