前几天有给大家分享一个Vue自定义滚动条组件VScroll。今天再分享一个最新开发的React PC端模拟滚动条组件RScroll。




ant design vue 自定义滚动条样式_vue 滚动条


vue+pc桌面端模拟滚动条组件VScroll

rscroll 一款基于react.js构建的超小巧自定义桌面端美化滚动条。支持原生滚动条、自动隐藏、滚动条尺寸/层级/颜色等功能。


ant design vue 自定义滚动条样式_ide_02


ant design vue 自定义滚动条样式_自定义滚动条_03


如上图:支持垂直/水平滚动条。

功能及效果和之前VScroll保持一致。在开发支持参考借鉴了el-scrollbar等组件设计思想。


ant design vue 自定义滚动条样式_自定义滚动条_04


调用非常简单,只需包裹住内容即可快速生成一个漂亮的滚动条。

引入组件

// 引入滚动条组件RScrollimport RScroll from './components/rscroll'

快速使用

这里是内容信息!这里是内容信息!这里是内容信息!

这里是内容信息!这里是内容信息!这里是内容信息!


这里是内容信息!这里是内容信息!这里是内容信息!


这里是内容信息!这里是内容信息!这里是内容信息!


ant design vue 自定义滚动条样式_vue 滚动条_05


ant design vue 自定义滚动条样式_自定义滚动条_06


编码实现

在components目录下新建rscroll目录,并创建index.js页面。


ant design vue 自定义滚动条样式_ide_07


rscroll滚动条模板

render() {    return (


this.$ref__box = el} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>

this.$ref__wrap = el} onScroll={this.handleScroll}>

{prop.children}

{/* 滚动条 */}

this.$ref__barY = el} onMouseDown={this.handleDragThumb.bind(this, 0)} style={{background: prop.color, height: opt.barHeight+'px'}}>


this.$ref__barX = el} onMouseDown={this.handleDragThumb.bind(this, 1)} style={{background: prop.color, width: opt.barWidth+'px'}}>

)}

react监听元素/DOM尺寸变化。由于react不像vue可以自定义指令directives,只能使用componentDidUpdate来监听。

componentDidUpdate(preProps, preState) {    // 监听内层view DOM尺寸变化    let $view = this.$ref__wrap.querySelector('.vscroll__view')    const viewStyle = $view.currentStyle ? $view.currentStyle : document.defaultView.getComputedStyle($view, null);    if(preState.$viewWidth !== viewStyle.width || preState.$viewHeight !== viewStyle.height) {        this.setState({ $viewWidth: viewStyle.width, $viewHeight: viewStyle.height })        this.updated()    }}
/** * ReactJs|Next.js自定义滚动条组件RScroll */import React from 'react'class RScroll extends React.Component {    /**     * 默认配置     */    static defaultProps = {        // 是否显示原生滚动条        native: false,        // 鼠标滑出是否自动隐藏滚动条        autohide: false,        // 自定义滚动条大小        size: '',        // 自定义滚动条颜色        color: '',        // 滚动条层级        zIndex: null    }    constructor(props) {        super(props)        this.state = {            barWidth: 0,                    // 滚动条宽度            barHeight: 0,                   // 滚动条高度            ratioX: 1,                      // 滚动条水平偏移率            ratioY: 1,                      // 滚动条垂直偏移率            isTaped: false,                 // 鼠标光标是否按住滚动条            isHover: false,                 // 鼠标光标是否悬停在滚动区            isShow: !this.props.autohide,   // 是否显示滚动条            $viewWidth: null,            $viewHeight: null,        }    }    // 鼠标滑入    handleMouseEnter = () => {        this.setState({            isHover: true, isShow: true        })        this.updated()    }    // 鼠标滑出    handleMouseLeave = () => {        const { isTaped } = this.state        this.setState({ isHover: false })        this.setState({ isShow: false })    }    // 拖动滚动条    handleDragThumb = (index, e) => {        let _this = this        this.setState({ isTaped: true })        const { ratioX, ratioY } = this.state        let c = {}        // 阻止默认事件        domUtils.isIE() ? (e.returnValue = false, e.cancelBubble = true) : (e.stopPropagation(), e.preventDefault())        document.onselectstart = () => false        if(index == 0) {            c.dragY = true            c.clientY = e.clientY        }else {            c.dragX = true            c.clientX = e.clientX        }        domUtils.on(document, 'mousemove', function(evt) {            if(_this.state.isTaped) {                if(c.dragY) {                    _this.$ref__wrap.scrollTop += (evt.clientY - c.clientY) * ratioY                    _this.$ref__barY.style.transform = `translateY(${_this.$ref__wrap.scrollTop / ratioY}px)`                }                if(c.dragX) {                    _this.$ref__wrap.scrollLeft += (evt.clientX - c.clientX) * ratioX                    _this.$ref__barX.style.transform = `translateX(${_this.$ref__wrap.scrollLeft / ratioX})`                }            }        })        domUtils.on(document, 'mouseup', function() {            _this.setState({ isTaped: false })            document.onmouseup = null            document.onselectstart = null            if(!_this.state.isHover && _this.props.autohide) {                _this.setState({ isShow: false })            }        })    }    // 点击滚动槽    handleClickTrack = (index, e) => {        // ...    }    // 更新滚动区    updated = () => {        if(this.props.native) return        let c = {}        let barSize = domUtils.getScrollBarSize()        // 垂直滚动条        if(this.$ref__wrap.scrollHeight > this.$ref__wrap.offsetHeight) {            c.barHeight = this.$ref__box.offsetHeight **2 / this.$ref__wrap.scrollHeight            c.ratioY = (this.$ref__wrap.scrollHeight - this.$ref__box.offsetHeight) / (this.$ref__box.offsetHeight - c.barHeight)            this.$ref__barY.style.transform = `translateY(${this.$ref__wrap.scrollTop / c.ratioY}px)`            // 隐藏系统滚动条            if(barSize) {                this.$ref__wrap.style.marginRight = -barSize + 'px'            }        }else {            c.barHeight = 0            this.$ref__barY.style.transform = ''            this.$ref__wrap.style.marginRight = ''        }        // 水平滚动条        ...    }    // 鼠标滚动    handleScroll = (e) => {        const { onScroll } = this.props        typeof onScroll === 'function' && onScroll.call(this, e)        this.updated()    }    render() {        return (            // ...        )    }}export default RScroll


ant design vue 自定义滚动条样式_vue监听滚动条滚动事件_08


ant design vue 自定义滚动条样式_vue 滚动条_09

这里是内容信息!这里是内容信息!这里是内容信息!

// 监听滚动事件handleScroll = (e) => { let _scrollTop = e.target.scrollTop let _scrollStatus // 判断滚动状态 if(e.target.scrollTop == 0) { _scrollStatus = '滚到至顶部' } else if(e.target.scrollTop + e.target.offsetHeight >= e.target.scrollHeight) { _scrollStatus = '滚动至底部' }else { _scrollStatus = '正滚动中..' } this.setState({ scrollTop: _scrollTop, scrollStatus: _scrollStatus })}

好了,以上就是基于react.js开发自定义美化滚动条组件。希望大家能喜欢~~