基于 vue2 的响应式基础组件(滚动条),移动端和桌面端都支持

这是一个基于Vue2的响应式滚动条组件,适用于移动端和桌面端。文章介绍了开源项目vue2do中关于scroller组件的实现,包括scroller.js、scroller.render.js、scroller.api.js和scroller.scss等核心文件。
摘要由CSDN通过智能技术生成

基于 vue2 的响应式基础组件(滚动条),移动端和桌面端都支持

本文章是个人开源项目 vue2do,文档地址是: https://zen0822.github.io/#/component/scroller

scroller.js

/**
 * scroller 组件 滚动条
 *
 * @prop height - 滚动区域的高度(auto | { Number }px | 100% }),
 *                auto:根据滚动内容的高度
 *                { Number }:自定义像素高度
 *                100%:根据父元素的高度
 * @prop width - 滚动区域的宽度(auto | {Number}px | 100%),同上
 * @prop autoHide - 自动隐藏滚动条
 *
 * @event scrollY - 滚动事件
 *                  return isBottom - 滚动条是否到低
 *                         isTop - 滚动条是否到顶
 *                         top - 滚动条到滚动区域的顶部的当前距离
 *                         offset - 滚动条离滚动区域的顶部的距离
 * @event scrollX - 滚动事件
 *                  return isRight - 滚动条是否到结束的地方
 *                         isLeft - 滚动条是否到开始的地方
 *                         left - 滚动条到滚动区域的最左边的当前距离
 *                         offset - 滚动条离滚动区域的顶部的距离
 * @event yBarChange - y-bar 滚动条改变
 *                  return isBottom - 滚动条是否到低
 *                         isTop - 滚动条是否到顶
 *                         top - 滚动条到滚动区域的顶部的当前距离
 *                         offset - 滚动条离滚动区域的顶部的距离
 * @event xBarChange - x-bar 滚动条改变
 *                  return isRight - 滚动条是否到结束的地方
 *                         isLeft - 滚动条是否到开始的地方
 *                         left - 滚动条到滚动区域的最左边的当前距离
 *                         offset - 滚动条离滚动区域的顶部的距离
 * @event scrollerChange - 滚动区域的高度/宽度变化
 */

import './Scroller.scss'

import baseMixin from '../../mixin/base'
import apiMixin from './Scroller.api'
import render from './Scroller.render.js'

import {
  offset as propOffset
} from '../../util/dom/prop'

import MotionFade from '../MotionFade/MotionFade'

// 滚动一次的滚动区域走的像素大小
const SCROLL_PIXEL = 10

export default {
  name: 'Scroller',

  mixins: [baseMixin, apiMixin],

  render,

  components: {
    'motion-fade': MotionFade
  },

  props: {
    height: {
      type: [Number, String],
      default: 'auto',
      validator(val) {
        if (typeof val === 'number') {
          return true
        } else if (val === 'auto' || val === '100%') {
          return true
        } else {
          return false
        }
      }
    },

    width: {
      type: [Number, String],
      default: 'auto',
      validator(val) {
        if (typeof val === 'number') {
          return true
        } else if (val === 'auto' || val === '100%') {
          return true
        } else {
          return false
        }
      }
    },

    autoHide: {
      type: Boolean,
      default: false
    }
  },

  data() {
    this.compName = 'scroller' // 组件名字
    this.interValInitScroller = '' // 初始化滚动条定时器

    return {
      yData: { // y-scroller detail
        barAndScrollerOffset: 0, // 滚动条和滚动区域的偏移值
        barLength: 0, // 滚动条的高度
        barTop: 0, // bar 的高度
        boxBarRate: 0, // 滚动内容 / 滚动条区域
        boxAndScrollerOffset: 0, // 滚动内容和滚动区域的偏移值
        isMousedown: false, // 滚动条的 mousedown 事件
        oldBarTop: 0, // 记录上一次滚动条的高度
        scrollBarPixel: 0, // 滚动一次的滚动条走的像素大小
        scrollerContainBox: false // 滚动条的高度是否大于滚动区域
      },

      xData: { // x-scroller detail
        barLength: 0,
        barLeft: 0,
        barAndScrollerOffset: 0,
        boxBarRate: 0,
        boxAndScrollerOffset: 0,
        isMousedown: false,
        oldBarLeft: 0,
        scrollBarPixel: 0,
        scrollerContainBox: false
      },

      boxTop: 0, // box 离最顶端的偏移值
      boxLeft: 0, // box 离最开始的偏移值
      boxHeight: 0, // 滚动内容的高度
      boxWidth: 0, // 滚动内容的宽度
      boxStyleHeight: 0, // 滚动内容的样式高度
      boxStyleWidth: 0, // 滚动内容的样式宽度
      scrollerHeight: 0, // 滚动区域的高度
      scrollerWidth: 0, // 滚动区域的宽度
      parentHeight: 0, // 滚动区域的父元素的高度
      parentWidth: 0, // 滚动区域的父元素的宽度
      showBar: false, // 滚动条自动隐藏的状态
      isTouchStart: false, // 滚动区域的 touchend 事件
      scrolling: false, // 记录连续滚动的标注
      moving: false, // 记录是否还在触摸移动中
      hasScrollerGrandpa: false, // 是否有 scroller 组件的祖先

      touchStart: { // 记录开始触摸滚动区域的坐标
        x: 0,
        y: 0
      },

      pointStart: { // 记录开始点击滚动条的坐标
        x: 0,
        y: 0
      }
    }
  },

  computed: {
    boxStyle() {
      return {
        top: this.boxTop + 'px',
        left: this.boxLeft + 'px'
      }
    },
    scrollerStyle() {
      return {
        height: this.scrollerHeight + 'px',
        width: this.scrollerWidth + 'px'
      }
    },
    xComputed() { // x 方向的计算属性
      return {
        barDisplay: !this.xData.scrollerContainBox && (!this.autoHide || this.showBar),
        isLeft: this.xData.barLeft === 0,
        isRight: this.xData.barLeft === this.xData.barAndScrollerOffset,
        barStyle: {
          'width': this.xData.barLength + 'px',
          'left': this.xData.barLeft + 'px'
        }
      }
    },
    yComputed() { // y 方向的计算属性
      return
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值