lui - scrollBar 滚动栏

lui - scrollBar 滚动栏

cnblog

ie 兼容

ie 11
ie 10 需做css调整

intro

  1. 内容不溢出不显示滚动
  2. 内容溢出显示滚动
  3. 最左/右隐藏对应滚动按钮
  4. 多个滚动条相互独立,互不影响
  5. 按钮及内容样式可自定义,引入css仅做定位及dom操作

效果图

效果gif

use

设置指定 class: l_***

html

<!--
 * @createDate: 2022-05-16 09:33:42
 * @Author: zclee
 * @LastEditTime: 2022-05-17 17:10:55
 * @LastEditors: zclee
 * @FilePath: \webpack\l-ui\scrollBar\index.html
 * @Description: 
-->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>scrollBar</title>
    <link rel="stylesheet" href="./l_scroll_bar.css" />
  </head>
  <style>
    html,
    body {
      margin: 0;
    }
    * {
      box-sizing: border-box;
    }
    .scroll_item {
      flex: 0 0 auto;
      width: 300px;
      height: 50px;
      border: 1px solid #00aaee;
    }
    .btn {
      width: 80px;
      background-color: aqua;
    }
  </style>
  <body>
    <h1>内容不溢出不显示滚动</h1>
    <div id="scrollbar0" class="l_scroll_bar">
      <div class="btn l_scroll_btn l_scroll_btn_left">left</div>
      <div class="l_scroll_container">
        <div class="scroll_item"></div>
        <div class="scroll_item"></div>
      </div>
      <div class="btn l_scroll_btn l_scroll_btn_right">right</div>
    </div>
    <h1>内容溢出显示滚动</h1>
    <div id="scrollbar1" class="l_scroll_bar">
      <div class="btn l_scroll_btn l_scroll_btn_left">left</div>
      <div class="l_scroll_container">
        <div class="scroll_item"></div>
        <div class="scroll_item"></div>
        <div class="scroll_item"></div>
        <div class="scroll_item"></div>
      </div>
      <div class="btn l_scroll_btn l_scroll_btn_right">right</div>
    </div>
    <h1>最左/右隐藏对应滚动按钮</h1>
    <div id="scrollbar2" class="l_scroll_bar">
      <div class="btn l_scroll_btn l_scroll_btn_left">left</div>
      <div class="l_scroll_container">
        <div class="scroll_item"></div>
        <div class="scroll_item"></div>
        <div class="scroll_item"></div>
        <div class="scroll_item"></div>
      </div>
      <div class="btn l_scroll_btn l_scroll_btn_right">right</div>
    </div>
    <h1>多个滚动条相互独立,互不影响</h1>
    <div id="scrollbar3" class="l_scroll_bar">
      <div class="btn l_scroll_btn l_scroll_btn_left">left</div>
      <div class="l_scroll_container">
        <div class="scroll_item"></div>
        <div class="scroll_item"></div>
        <div class="scroll_item"></div>
        <div class="scroll_item"></div>
      </div>
      <div class="btn l_scroll_btn l_scroll_btn_right">right</div>
    </div>
    <div id="scrollbar4" class="l_scroll_bar">
      <div class="btn l_scroll_btn l_scroll_btn_left">left</div>
      <div class="l_scroll_container">
        <div class="scroll_item"></div>
        <div class="scroll_item"></div>
        <div class="scroll_item"></div>
        <div class="scroll_item"></div>
      </div>
      <div class="btn l_scroll_btn l_scroll_btn_right">right</div>
    </div>
    <!-- ie 兼容 -->
    <script src="../cdn/scrollBar.js"></script>
    <!-- <script src="../es6/scrollBar.js"></script> -->
    <script src="./index.js"></script>
  </body>
</html>

js

new ScrollBar

index.js

// index.js
/**
 * @createDate - 2022-05-16 09:34:07
 * @Author - zclee
 * @LastEditTime - 2022-05-17 17:18:28
 * @LastEditors - zclee
 * @FilePath - \webpack\l-ui\scrollBar\index.js
 * @Description -
 */

// ie
for (var i = 0; i < 5; i++) {
  new ScrollBar({
    dom: document.querySelector('#scrollbar' + i),
  });
}

// new Array(5).fill('').forEach((v, i) => {
//   new ScrollBar({
//     dom: document.querySelector('#scrollbar' + i),
//   });
// });

es6

// /es6/scrollBar.js
/**
 * @createDate - 2022-05-16 16:38:23
 * @Author - zclee
 * @LastEditTime - 2022-05-17 16:48:33
 * @LastEditors - zclee
 * @FilePath - \webpack\l-ui\es6\scrollBar.js
 * @Description -
 */

class ScrollBar {
  constructor(options = {}) {
    // 默认参数
    let defaultOptions = {
      // render dom
      //   只有单个可不传 默认document
      //   多个需指定dom 否则只生效第一个
      dom: null,
    };
    Object.assign(
      this,
      {
        target: null,
        leftBtn: null,
        rightBtn: null,
        timer: null,
      },
      defaultOptions,
      options
    );
    this.init();
  }
  init() {
    let { dom, left, right, target } = this;
    if (dom) {
      let doms = Array.from(dom.childNodes).filter((v) => v.nodeType == 1);
      left = doms.find((v) => v.className.indexOf('l_scroll_btn_left') != -1);
      right = doms.find((v) => v.className.indexOf('l_scroll_btn_right') != -1);
      target = doms.find(
        (v) => v.className.indexOf('l_scroll_container') != -1
      );
    } else {
      left = document.querySelector('.l_scroll_bar .l_scroll_btn_left');
      right = document.querySelector('.l_scroll_bar .l_scroll_btn_right');
      target = document.querySelector('.l_scroll_bar .l_scroll_container');
    }
    left.onmousedown = this.mousedown.bind(this, 'left');
    left.onmouseup = this.mouseup.bind(this, 'left');
    right.onmousedown = this.mousedown.bind(this, 'right');
    right.onmouseup = this.mouseup.bind(this, 'right');

    Object.assign(this, {
      left,
      right,
      target,
    });
    this.showBtn();
  }
  mousedown(type) {
    // this.move(type);
    // this.timer = requestAnimationFrame(this.mousedown.bind(this, type));
    this.timer = setInterval(this.move.bind(this, type), 10);
  }
  move(type) {
    let { target } = this;
    if (type == 'right') {
      target.scrollLeft += 2;
    } else {
      target.scrollLeft -= 2;
    }
    this.showBtn();
  }
  mouseup() {
    clearInterval(this.timer);
    // cancelAnimationFrame(this.timer); // 无效
    this.timer = null;
  }
  showBtn() {
    let { left, right, target } = this;
    // console.log(target.scrollWidth, target.clientWidth);
    if (target.scrollLeft > 0) {
      left.style.display = 'flex';
    } else {
      left.style.display = 'none';
      this.mouseup();
    }
    // console.log(target.scrollWidth - target.clientWidth, target.scrollLeft);
    if (target.scrollLeft < target.scrollWidth - target.clientWidth) {
      right.style.display = 'flex';
    } else {
      right.style.display = 'none';
      this.mouseup();
    }
  }
}

ie 兼容

// /cdn/scrollBar.js
/**
 * @createDate - 2022-05-16 16:38:23
 * @Author - zclee
 * @LastEditTime - 2022-05-17 17:19:27
 * @LastEditors - zclee
 * @FilePath - \webpack\l-ui\cdn\scrollBar.js
 * @Description -
 */

function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError('Cannot call a class as a function');
  }
}

if (typeof Object.assign != 'function') {
  Object.assign = function (target) {
    'use strict';
    if (target == null) {
      throw new TypeError('Cannot convert undefined or null to object');
    }

    target = Object(target);
    for (var index = 1; index < arguments.length; index++) {
      var source = arguments[index];
      if (source != null) {
        for (var key in source) {
          if (Object.prototype.hasOwnProperty.call(source, key)) {
            target[key] = source[key];
          }
        }
      }
    }
    return target;
  };
}

var ScrollBar = (function () {
  function ScrollBar() {
    var options =
      arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

    _classCallCheck(this, ScrollBar);

    // 默认参数
    var defaultOptions = {
      // render dom
      //   只有单个可不传 默认document
      //   多个需指定dom 否则只生效第一个
      dom: null,
    };
    Object.assign(
      this,
      {
        target: null,
        leftBtn: null,
        rightBtn: null,
        timer: null,
      },
      defaultOptions,
      options
    );
    this.init();
  }

  ScrollBar.prototype.init = function init() {
    var dom = this.dom,
      left = this.left,
      right = this.right,
      target = this.target;

    if (dom) {
      var doms = Array.prototype.slice
        .call(dom.childNodes)
        .filter(function (v) {
          return v.nodeType == 1;
        });
      left = doms[0];
      right = doms[2];
      target = doms[1];
    } else {
      left = document.querySelector('.l_scroll_bar .l_scroll_btn_left');
      right = document.querySelector('.l_scroll_bar .l_scroll_btn_right');
      target = document.querySelector('.l_scroll_bar .l_scroll_container');
    }
    left.onmousedown = this.mousedown.bind(this, 'left');
    left.onmouseup = this.mouseup.bind(this, 'left');
    right.onmousedown = this.mousedown.bind(this, 'right');
    right.onmouseup = this.mouseup.bind(this, 'right');

    Object.assign(this, {
      left: left,
      right: right,
      target: target,
    });
    this.showBtn();
  };

  ScrollBar.prototype.mousedown = function mousedown(type) {
    var _this = this;

    var target = this.target;

    this.timer = setInterval(function () {
      // console.log(
      //   'timer',
      //   target.clientWidth,
      //   target.scrollWidth,
      //   'scrollLeft:',
      //   target.scrollLeft,
      //   target.offsetLeft
      // );
      if (type == 'right') {
        target.scrollLeft += 2;
      } else {
        target.scrollLeft -= 2;
      }
      _this.showBtn();
    }, 10);
  };

  ScrollBar.prototype.mouseup = function mouseup() {
    clearInterval(this.timer);
    this.timer = null;
  };

  ScrollBar.prototype.showBtn = function showBtn() {
    var left = this.left,
      right = this.right,
      target = this.target;
    //   console.log(target.scrollWidth, target.clientWidth);

    if (target.scrollLeft > 0) {
      left.style.display = 'flex';
    } else {
      left.style.display = 'none';
      this.mouseup();
    }

    if (target.scrollLeft < target.scrollWidth - target.clientWidth) {
      right.style.display = 'flex';
    } else {
      right.style.display = 'none';
      this.mouseup();
    }
  };

  return ScrollBar;
})();

css

// l_scroll_bar.css
.l_scroll_bar {
  display: flex;
}
.l_scroll_container {
  flex: 1 0 0;
  display: flex;
  overflow: auto;
  -ms-overflow-style: none;
}
.l_scroll_container::-webkit-scrollbar {
  width: 0px;
  height: 0px;
}
.l_scroll_btn {
  width: 80px;
  flex: 0 0 auto;
  cursor: pointer;
  display: none;
  align-items: center;
  justify-content: center;
}

posted @ 2022-05-17 17:02  zc-lee  阅读(33)  评论(0编辑  收藏  举报