您当前的位置:首页 > 网站建设 > javascript
| php | asp | css | H5 | javascript | Mysql | Dreamweaver | Delphi | 网站维护 | 帝国cms | React | 考试系统 | ajax |

javascript实现自定义滚动条效果

51自学网 2022-05-02 21:34:04
  javascript

在实际项目中,遇到上下滚动条和左右滚动条不在一个DIV内部,所以某些情况下,右侧滚动条不可见。但是需要咋同一个视口内显示两个滚动条。

一个解决思路是:自定义滚动条,隐藏原始滚动条。

自定义滚动条

scrollbar.js

import React, { Component } from 'react';import PropTypes from 'prop-types';import '../css/scrollbar.css';const propTypes = {  eventBus: PropTypes.object.isRequired,};class ScrollBar extends Component {  constructor(props) {    super(props);    this.state = {      isDraging: false,      // X: bottom scrollbar offset left, range [0, innerWidth - 100]. When dragging, x is changing      x: null,      // clickX 表示拖动滚动条时,鼠标点击的位置距离滚动条左侧的距离, range [0, 100], When dragging, clickX isn't changing      clickX: 0,    };  }  componentDidMount() {    this.unsubscribeScrollToColumn = this.props.eventBus.subscribe('set-scrollbar-left', this.setScrollBarLeft);    document.addEventListener('mouseup', this.onMouseUp);  }  componentWillUnmount() {    this.unsubscribeScrollToColumn();    document.removeEventListener('mouseup', this.onMouseUp);  }  /**   * 这个函数处理联动(界面滚动时,触发滚动条滚动)这里的100是滚动条的宽度   */  setScrollBarLeft = (leftRatio) => {    // when bottom scrollbar is dragging, can't set scrollBa left    if (this.state.isDraging) return;    this.setState({      x: (window.innerWidth - 100) * leftRatio,    });  }  /**   * 当鼠标按下,开始拖动,设置当前的位置为初始拖动的位置   */  handleMouseDown = (e) => {    this.setState({      isDraging: true,      clickX: e.nativeEvent.offsetX,    });  }  /**   * 当鼠标抬起时,停止拖拽,设置当前的点击位置是0(这个有没有必要设置)   */  onMouseUp = () => {    if (this.state.isDraging) {      setTimeout(() => {        this.setState({ isDraging: false, clickX: 0 });      }, 100);    }  }  /**   * 当拖拽进行时(鼠标按下并开始移动),获取当前的位移,计算新的偏移量   * 注意:可以向右滚动,可以向左滚动   * 当拖拽进行时,应该计算出当前的比例,然后Grid水平滚动   * 现在的问题,如果鼠标拖动时移动到滚动条外部,那么无法触发拖动   * */   onMouseMove = (e) => {    e.persist();    if (this.state.isDraging) {      // 新距离 = 原始距离 + (当前滚动的距离 - 初始滚动的距离)      let newX = this.state.x + e.nativeEvent.offsetX - this.state.clickX;      newX = Math.min(newX, window.innerWidth - 100); // 最大的拖动不能超过右侧边界      this.setState({ x: newX });      const leftRatio = newX / (window.innerWidth - 100);    }  }  renderBottomToolbar = () => {    return (      <div        className="antiscroll-scrollbar antiscroll-scrollbar-horizontal antiscroll-scrollbar-shown"        style={{transform: `translateX(${this.state.x}px)`}}        draggable="true"        onMouseDown={this.handleMouseDown}        onMouseMove={this.onMouseMove}        onMouseUp={this.onMouseUp}      ></div>    );  }  // todo: rightToolbar event handle  renderRightToolbar = () => {    return (      <div        className="antiscroll-scrollbar antiscroll-scrollbar-vertical antiscroll-scrollbar-shown"      ></div>    );  }  render() {    return (      <div id="scrollOverlay" className="antiscroll-wrap">        {this.renderBottomToolbar()}        {this.renderRightToolbar()}      </div>    );  }}ScrollBar.propTypes = propTypes;export default ScrollBar;

滚动条样式

对应的 scrollbar.css

#scrollOverlay {  display: inline-block;  overflow: hidden;  position: fixed;  left: 0;  right: 0;  top: 156px;  bottom: 0;  z-index: 4;  pointer-events: none;  opacity: .7;}#scrollOverlay .antiscroll-scrollbar {  pointer-events: auto;  z-index: 2;  background-color: hsla(0,0%,0%,0.28);  box-shadow: inset 0 0 0 1px hsl(0,0%,100%);  border-radius: 5px;}#scrollOverlay .antiscroll-scrollbar-horizontal {  height: 12px;  width: 100px;  position: absolute;  bottom: 32px;}#scrollOverlay .antiscroll-scrollbar-vertical {  width: 12px;  height: 100px;  position: absolute;  right: 0;}/* 隐藏原始滚动对象的滚动条 */.react-demo::-webkit-scrollbar {  width: 0;}

滚动条具体使用

具体使用,我们在 Grid 中加入这个滚动条

import ScrollBar from '../components/scrollbar';// Grid 原生滚动,触发回调函数onScroll = () => {  // todo: when clientWidth is smaller than innerWidth, don't show bottom scrollBar  let scrollLeftRatio = this._scrollLeft / (clientWidth - window.innerWidth);  // 当原生DOM左右滚定时,获取当前滚动的比例(偏移量/全部宽度),并设置滚动条进行滚动  this.setScrollLeftRatio(scrollLeftRatio);}setScrollLeftRatio = (scrollLeftRatio) => {  this.props.eventBus.dispatch('set-scrollbar-left', scrollLeftRatio);}// 在原始滚动元素中,传入eventBus,便于事件传值处理// <ScrollBar eventBus={this.props.eventBus}/>

自定义滚动条也有很多开源第三方组件,我们优先使用第三方库实现(处理滚动条计算考虑情况较多)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持wanshiok.com。


js+css实现三级导航菜单
jQuery实现图片跟随效果
51自学网,即我要自学网,自学EXCEL、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。
京ICP备13026421号-1