js 自定义滚动条

js 自定义滚动条

效果图

在这里插入图片描述

需求分析

  1. 滚轮滚动带动内容滚动
  2. 滚轮拖动带动内容拖动

页面结构

<div class="wrap">
        <div class="bar">
        </div>
        <div class="show">
            <img src="https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2529206747.webp" alt="">
            <img src="https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2561305376.webp" alt="">
            <img src=" https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2315672647.webp" alt="">
            <img src=" https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2563780504.webp" alt="">
            <img src="https://img3.doubanio.com/view/photo/s_ratio_poster/public/p480747492.webp" alt="">
            <img src="https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2557573348.webp" alt="">
            <img src=" https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2457983084.webp" alt="">
            <img src=" https://img1.doubanio.com/view/photo/s_ratio_poster/public/p501177648.webp" alt="">
            <img src="https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2498971355.webp" alt="">
            <img src="https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2551995207.webp" alt="">
            <img src=" https://img1.doubanio.com/view/photo/s_ratio_poster/public/p1832875827.webp" alt="">
            <img src=" https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2549648344.webp" alt="">
            <img src="https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2516578307.webp" alt="">
            <img src="https://img9.doubanio.com/view/photo/s_ratio_poster/public/p2552058346.webp" alt="">
            <img src=" https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2537158013.webp" alt="">
            <img src=" https://img9.doubanio.com/view/photo/s_ratio_poster/public/p513344864.webp" alt="">
        </div>
    </div>

调用方式

new Scroll({
            bar: '.bar',
            wrap: '.wrap',
            show: '.show'
        })

js代码

class Scroll {
            constructor(option) {
                this.init(option)
            }
            init(option) {
                this.bar = document.querySelector(option.bar);
                this.wrap = document.querySelector(option.wrap);
                this.show = document.querySelector(option.show);
                this.exchange = this.show.clientHeight / (this.wrap.offsetHeight);
                this.scroll = 0
                this.initBar(); //初始化滚动条
                this.bindEvent(); //绑定事件
            }
            initBar() {
                if (this.wrap.offsetHeight >= this.show.offsetHeight) { //判断显示内容是否超出父元素,如果没有则隐藏滚动条
                    this.bar.style.display = 'none';
                } else {
                    this.bar.style.height = this.wrap.offsetHeight * this.wrap.offsetHeight / this.show
                        .clientHeight + 'px'; //如果超出滚动条的高度
                }
            }
            bindEvent() {
                this.wrap.onmousewheel = (ev) => {

                    if (this.wrap.offsetHeight >= this.show.offsetHeight) { //如果没有超出,取消滚轮事件
                        return;
                    }
                    let e = ev || event;
                    e.preventDefault();
                    if (e.wheelDelta < 0) {
                        this.scroll += 10;//滚轮每次滚动,滚动条增加
                        if (this.scroll > this.wrap.offsetHeight - this.bar.offsetHeight) {
                            this.scroll = this.wrap.offsetHeight - this.bar.offsetHeight;
                        }
                        this.show.style.top = -this.scroll * this.exchange + 'px';
                        this.bar.style.top = this.scroll + 'px';
                    } else {
                        this.scroll -= 10;
                        if (this.scroll < 0) {
                            this.scroll = 0;
                        }
                        this.show.style.top = -this.scroll * this.exchange + 'px';
                        this.bar.style.top = this.scroll + 'px';
                    }
                }
                this.bar.onmousedown = (ev) => {
                    let e = ev || event;
                    e.preventDefault();
                    e.stopPropagation();
                    let to_t = e.clientY - this.bar.offsetTop;
                    this.bar.style.background = 'maroon'
                    document.onmousemove = (ev) => {
                        let e = ev || event;
                        let t = e.clientY - to_t;
                        if (e.clientX < this.wrap.offsetLeft || e.clientX > this.wrap.offsetLeft + this.wrap
                            .offsetWidth +
                            100) {
                            return;
                        }
                        if (t < 0) {
                            t = 0;
                        } else if (t > this.wrap.offsetHeight - this.bar.offsetHeight) {
                            t = this.wrap.offsetHeight - this.bar.offsetHeight;
                        }
                        this.show.style.top = -t * this.exchange + 'px';
                        this.bar.style.top = t + 'px';
                        this.scroll = t;
                    }
                    document.onmouseup = () => {
                        this.bar.style.background = 'lightgrey'
                        document.onmousemove = null;
                    }
                    this.wrap.onmouseup = (ev) => {
                        this.bar.style.background = 'lightgrey'
                        document.onmousemove = null;
                    }
                }
            }
        }

    主要利用滚轮滚动的方向计算自定义滚动条的top值,然后根据置换比例算出内容的top值,拖拽原理类似。

猜你喜欢

转载自blog.csdn.net/evail_/article/details/107618713