• 简单的自定义滚动条


    1. 滚动条长度如何计算
    滚动条长度 = 可视长度 * 滚动条容器长度 / 内容长度
    
    • 1
    1. 移动一像素实际比例
    比例 = (内容长度 - 可视长度) / (滚动条容器长度 - 滚动条长度 )
    
    • 1
    1. 图解
      在这里插入图片描述
    DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <title>Documenttitle>
    head>
    
    
    <body>
      <div class="wrap">
        <div class="content">
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec in ligula id sem tristique ultrices eget id neque.
          Duis enim turpis, tempus at accumsan vitae, lobortis id sapien. Pellentesque nec orci mi, in pharetra ligula.
          Nulla
          facilisi. Nulla facilisi. Mauris convallis venenatis massa, quis consectetur felis ornare quis. Sed aliquet nunc
          ac
          ante molestie ultricies. Nam pulvinar ultricies bibendum. Vivamus diam leo, faucibus et vehicula eu, molestie sit
          amet dui. Proin nec orci et elit semper ultrices. Cum sociis natoque penatibus et magnis dis parturient montes,
          nascetur ridiculus mus. Sed quis urna mi, ac dignissim mauris. Quisque mollis ornare mauris, sed laoreet diam
          malesuada quis. Proin vel elementum ante. Donec hendrerit arcu ac odio tincidunt posuere. Vestibulum nec risus eu
          lacus semper viverra.
          Vestibulum dictum consectetur magna eu egestas. Praesent molestie dapibus erat, sit amet sodales lectus congue ut.
          Nam adipiscing, tortor ac blandit egestas, lorem ligula posuere ipsum, nec faucibus nisl enim eu purus. Quisque
          bibendum diam quis nunc eleifend at molestie libero tincidunt. Quisque tincidunt sapien a sapien pellentesque
          consequat. Mauris adipiscing venenatis augue ut tempor. Donec auctor mattis quam quis aliquam. Nullam ultrices
          erat
          in dolor pharetra bibendum. Suspendisse eget odio ut libero imperdiet rhoncus. Curabitur aliquet, ipsum sit amet
          aliquet varius, est urna ullamcorper magna, sed eleifend libero nunc non erat. Vivamus semper turpis ac turpis
          volutpat non cursus velit aliquam. Fusce id tortor id sapien porta egestas. Nulla venenatis luctus libero et
          suscipit. Sed sed purus risus. Donec auctor, leo nec eleifend vehicula, lacus felis sollicitudin est, vitae
          lacinia
          lectus urna nec libero. Aliquam pellentesque, arcu condimentum pharetra vestibulum, lectus felis malesuada felis,
          vel fringilla dolor dui tempus nisi. In hac habitasse platea dictumst. Ut imperdiet mauris vitae eros varius eget
          accumsan lectus adipiscing.
          Quisque et massa leo, sit amet adipiscing nisi. Mauris vel condimentum dolor. Duis quis ullamcorper eros. Proin
          metus dui, facilisis id bibendum sed, aliquet non ipsum. Aenean pulvinar risus eu nisi dictum eleifend. Maecenas
          mattis dolor eget lectus pretium eget molestie libero auctor. Praesent sit amet tellus sed nibh convallis semper.
          Curabitur nisl odio, feugiat non dapibus sed, tincidunt ut est. Nullam erat velit, suscipit aliquet commodo sit
          amet, mollis in mauris. Curabitur pharetra dictum interdum. In posuere pretium ultricies. Curabitur volutpat eros
          vehicula quam ultrices varius. Proin volutpat enim a massa tempor ornare. Sed ullamcorper fermentum nisl, ac
          hendrerit sem feugiat ac. Donec porttitor ullamcorper quam. Morbi pretium adipiscing quam, quis bibendum diam
          congue
          eget. Sed at lectus at est malesuada iaculis. Sed fermentum quam dui. Donec eget ipsum dolor, id mollis nisi.
          Donec
          fermentum vehicula porta.
          Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor
          quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean
          ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra.
          Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt
          condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar
          facilisis.
          Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat.
          Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus
          Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor
          quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean
          ultricies mi vitae est. Mauris placerat eleifend leo.
        div>
        <div class="scroll">
          <div class="slider">div>
        div>
      div>
    
      <div class="wrap1">
        <div class="content1">
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec in ligula id sem tristique ultrices eget id neque.
          Duis enim turpis, tempus at accumsan vitae, lobortis id sapien. Pellentesque nec orci mi, in pharetra ligula.
          Nulla
          facilisi. Nulla facilisi. Mauris convallis venenatis massa, quis consectetur felis ornare quis. Sed aliquet nunc
          ac
          ante molestie ultricies. Nam pulvinar ultricies bibendum. Vivamus diam leo, faucibus et vehicula eu, molestie sit
          amet dui. Proin nec orci et elit semper ultrices. Cum sociis natoque penatibus et magnis dis parturient montes,
          nascetur ridiculus mus. Sed quis urna mi, ac dignissim mauris. Quisque mollis ornare mauris, sed laoreet diam
          malesuada quis. Proin vel elementum ante. Donec hendrerit arcu ac odio tincidunt posuere. Vestibulum nec risus eu
          lacus semper viverra.
          Vestibulum dictum consectetur magna eu egestas. Praesent molestie dapibus erat, sit amet sodales lectus congue ut.
          Nam adipiscing, tortor ac blandit egestas, lorem ligula posuere ipsum, nec faucibus nisl enim eu purus. Quisque
          bibendum diam quis nunc eleifend at molestie libero tincidunt. Quisque tincidunt sapien a sapien pellentesque
          consequat. Mauris adipiscing venenatis augue ut tempor. Donec auctor mattis quam quis aliquam. Nullam ultrices
          erat
          in dolor pharetra bibendum. Suspendisse eget odio ut libero imperdiet rhoncus. Curabitur aliquet, ipsum sit amet
          aliquet varius, est urna ullamcorper magna, sed eleifend libero nunc non erat. Vivamus semper turpis ac turpis
          volutpat non cursus velit aliquam. Fusce id tortor id sapien porta egestas. Nulla venenatis luctus libero et
          suscipit. Sed sed purus risus. Donec auctor, leo nec eleifend vehicula, lacus felis sollicitudin est, vitae
          lacinia
          lectus urna nec libero. Aliquam pellentesque, arcu condimentum pharetra vestibulum, lectus felis malesuada felis,
          vel fringilla dolor dui tempus nisi. In hac habitasse platea dictumst. Ut imperdiet mauris vitae eros varius eget
          accumsan lectus adipiscing.
          Quisque et massa leo, sit amet adipiscing nisi. Mauris vel condimentum dolor. Duis quis ullamcorper eros. Proin
          metus dui, facilisis id bibendum sed, aliquet non ipsum. Aenean pulvinar risus eu nisi dictum eleifend. Maecenas
          mattis dolor eget lectus pretium eget molestie libero auctor. Praesent sit amet tellus sed nibh convallis semper.
          Curabitur nisl odio, feugiat non dapibus sed, tincidunt ut est. Nullam erat velit, suscipit aliquet commodo sit
          amet, mollis in mauris. Curabitur pharetra dictum interdum. In posuere pretium ultricies. Curabitur volutpat eros
          vehicula quam ultrices varius. Proin volutpat enim a massa tempor ornare. Sed ullamcorper fermentum nisl, ac
          hendrerit sem feugiat ac. Donec porttitor ullamcorper quam. Morbi pretium adipiscing quam, quis bibendum diam
          congue
          eget. Sed at lectus at est malesuada iaculis. Sed fermentum quam dui. Donec eget ipsum dolor, id mollis nisi.
          Donec
          fermentum vehicula porta.
          Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor
          quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean
          ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra.
          Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt
          condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar
          facilisis.
          Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat.
          Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus
          Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor
          quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean
          ultricies mi vitae est. Mauris placerat eleifend leo.
        div>
        <div class="scroll1">
          <div class="slider1">div>
        div>
      div>
      <style type="text/css">
        .wrap {
          user-select: none;
          position: relative;
          width: 400px;
          height: 300px;
          overflow: hidden;
          border: 1px solid #aaa;
        }
    
        .wrap .scroll {
          opacity: 0;
          transition: opacity .3s
        }
    
        .wrap:hover .scroll {
          opacity: 1;
        }
    
        .content {
          width: 100%;
          height: 300px;
          overflow: auto;
        }
    
        .content::-webkit-scrollbar {
          width: 0 !important
        }
    
        .scroll {
          position: absolute;
          width: 10px;
          height: calc(100%);
          right: 0px;
          top: 0px;
          background-color: red;
          opacity: .5;
        }
    
        .slider {
          position: absolute;
          top: 0px;
          left: 0px;
          width: 100%;
          height: 100px;
          background: blue;
        }
      style>
      <style type="text/css">
        .wrap1 {
          user-select: none;
          position: relative;
          width: 1000px;
          overflow: hidden;
          border: 1px solid #aaa;
        }
    
        .wrap1 .scroll1 {
          opacity: 0;
          transition: opacity .3s
        }
    
        .wrap1:hover .scroll1 {
          opacity: 1;
        }
    
        .content1 {
          white-space: nowrap;
          width: 100%;
          overflow: auto;
        }
    
        .content1::-webkit-scrollbar {
          width: 0 !important
        }
    
        .scroll1 {
          position: absolute;
          width: calc(100%);
          height: 10px;
          right: 0px;
          bottom: 0px;
          background-color: red;
          opacity: .5;
        }
    
        .slider1 {
          position: absolute;
          top: 0px;
          left: 0px;
          width: 100px;
          height: 10px;
          background: blue;
        }
      style>
      <script>
        // bar_height/wrap_height = wrap_height/content_height;
        // bar_height = wrap_height*wrap_height/content_height;  // 滚动条的长度
        const wrap = document.querySelector(".wrap")
        const content = document.querySelector(".content")
        const scroll = document.querySelector(".scroll")
        const sliderDom = document.querySelector(".slider")
    
        const visibleHeight = parseInt(window.getComputedStyle(wrap).height)
        const scrollbarHeight = parseInt(scroll.clientHeight)
        const scrollHeight = content.scrollHeight
        // 根据 visibleHeight / scrollHeight = sliderHeight / scrollbarHeight 得出
    
        const sliderHeight = visibleHeight * scrollbarHeight / scrollHeight
        const sliderRatio = (scrollHeight - visibleHeight) / (scrollbarHeight - sliderHeight)
    
    
        function updateSlider(moveDelta) {
          // 更新滑块的高度和位置
          sliderDom.style.height = sliderHeight + 'px';
          sliderDom.style.top = moveDelta + 'px';
        }
    
        updateSlider(0);
        let isMove = false
        let initY = 0
        let over = 0
        let moveDelta = 0
        sliderDom.addEventListener('mousedown', (e) => {
          initY = e.pageY - over;
          isMove = true
          document.addEventListener('mousemove', mousemove);
        })
    
        function mousemove(e) {
          if (!isMove) {
            return
          }
          const dom = e.currentTarget
          // 移动的距离
          moveDelta = e.pageY - initY
          if (moveDelta < 0) {
            moveDelta = 0
          }
          const max = scroll.clientHeight - sliderDom.clientHeight
          if (moveDelta > max) {
            moveDelta = max
          }
          updateSlider(moveDelta);
          content.scrollTo(0, moveDelta * sliderRatio);
        }
        document.addEventListener("mouseup", function (e) {
          isMove = false
          over = moveDelta
          document.removeEventListener("mouse", mousemove)
        })
    
        scroll.addEventListener('mousedown', (e) => {
          if (e.target !== sliderDom) {
            let moveDeltatmp = e.pageY - sliderDom.clientHeight / 2
            const min = sliderDom.clientHeight / 2
            if (moveDeltatmp < min) {
              moveDeltatmp = 0
            }
            const max = scroll.clientHeight - sliderDom.clientHeight
            if (moveDeltatmp > max) {
              moveDeltatmp = max
            }
            moveDelta = moveDeltatmp
            updateSlider(moveDelta);
            content.scrollTo(0, moveDelta * sliderRatio);
          }
        })
    
    
        content.addEventListener('mousewheel', (e) => {
          const scrollTop = e.currentTarget.scrollTop
          const moveDelta = scrollTop / sliderRatio
          updateSlider(moveDelta);
          over = moveDelta
        })
      script>
      <script>
        // bar_height/wrap_height = wrap_height/content_height;
        // bar_height = wrap_height*wrap_height/content_height;  // 滚动条的长度
        const wrap1 = document.querySelector(".wrap1")
        const content1 = document.querySelector(".content1")
        const scroll1 = document.querySelector(".scroll1")
        const sliderDom1 = document.querySelector(".slider1")
    
        const visibleWidth1 = parseInt(window.getComputedStyle(wrap1).width)
        const scrollbarWidth1 = parseInt(scroll1.clientWidth)
        const scrollWidth1 = content1.scrollWidth
        // 根据 visibleHeight / scrollHeight = sliderHeight / scrollbarHeight 得出
    
        const sliderWidth1 = visibleWidth1 * scrollbarWidth1 / scrollWidth1
        const sliderRatio1 = (scrollWidth1 - visibleWidth1) / (scrollbarWidth1 - sliderWidth1)
    
        function updateSlider1(moveDelta) {
          // 更新滑块的高度和位置
          sliderDom1.style.width = sliderWidth1 + 'px';
          sliderDom1.style.left = moveDelta + 'px';
        }
    
        updateSlider1(0);
        let isMove1 = false
        let initX1 = 0
        let over1 = 0
        let moveDelta1 = 0
        sliderDom1.addEventListener('mousedown', (e) => {
          initX1 = e.pageX - over1;
          isMove1 = true
          document.addEventListener('mousemove', mousemove1);
        })
    
        function mousemove1(e) {
          if (!isMove1) {
            return
          }
          const dom = e.currentTarget
          // 移动的距离
          moveDelta1 = e.pageX - initX1
          if (moveDelta1 < 0) {
            moveDelta1 = 0
          }
          const max = scroll1.clientWidth - sliderDom1.clientWidth
          if (moveDelta1 > max) {
            moveDelta1 = max
          }
          updateSlider1(moveDelta1);
          content1.scrollTo(moveDelta1 * sliderRatio1, 0);
        }
        document.addEventListener("mouseup", function (e) {
          isMove1 = false
          over1 = moveDelta1
          document.removeEventListener("mouse", mousemove1)
        })
    
        scroll1.addEventListener('mousedown', (e) => {
          if (e.target !== sliderDom1) {
            let moveDeltatmp = e.pageX - sliderDom1.clientWidth / 2
            const min = sliderDom1.clientWidth / 2
            if (moveDeltatmp < min) {
              moveDeltatmp = 0
            }
            const max = scroll1.clientWidth - sliderDom1.clientWidth
            if (moveDeltatmp > max) {
              moveDeltatmp = max
            }
            moveDelta1 = moveDeltatmp
            updateSlider1(moveDelta1);
            content1.scrollTo(moveDelta1 * sliderRatio1, 0);
          }
        })
    
    
        content1.addEventListener('mousewheel', (e) => {
          const scrollLeft = e.currentTarget.scrollLeft
          const moveDelta = scrollLeft / sliderRatio1
          updateSlider1(moveDelta);
          over1 = moveDelta
        })
      script>
    body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
  • 相关阅读:
    Python中的super函数,你熟吗?
    解析多层级 JSON 如:get(A.B.C)
    Spring boot接收zip包并获取其中excel文件的方法
    李宏毅《机器学习》丨7. Conclusion(总结)
    U盘RAW格式无法格式化怎么办?
    类和对象(跑路人笔记)<完>
    Pr:导出设置之音频
    数据库基础+增删查改初阶
    汽车协议学习
    Compression-Resistant Backdoor Attack against Deep Neural Networks 论文笔记
  • 原文地址:https://blog.csdn.net/WuQingLaoXingXing/article/details/126242724