欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

小程序click-scroll组件设计

程序员文章站 2022-09-07 12:11:30
一. 背景 有些业务需求,要求前端展示的内容多时可以通过scroll的形式拖拉查看,但是太多的滚动条又造成页面太乱,于是封装了这个click-scroll 组件。在组...

一. 背景

有些业务需求,要求前端展示的内容多时可以通过scroll的形式拖拉查看,但是太多的滚动条又造成页面太乱,于是封装了这个click-scroll 组件。在组件上设定好展示的位置和空间大小,在组件内部放置实际要展示的内容,实际展示的内容宽度或长或短都由此组件来控制。

二. 功能

组件内的内容宽度超过组件宽度时,组件两侧会自动出现『左右移动』交互。

当内部展示的内容超过组件的可见区域时,可以在组件的可见区域单击拖动查看内容

三. 背景知识,元素大小的测量

1.偏移量(offset dimension):

元素在屏幕上占用的可见的所有空间,元素的可见大小由其高度、宽度决定,包括所有内边距、滚动条和边框大小。由四个值决定:offsetheight、offsetwidth、offsetleft和offsetright。

  • offsetheight:元素在垂直方向上占用的空间大小,以像素计。包括元素的高度、(可见)水平滚动条的高度、上边框高度和下边框高度。
  • offsetwidth:元素在水平方向上占用的空间大小,以像素计。包括元素的宽度、(可见)垂直滚动条的宽度、左边框宽度和右边框宽度。
  • offsetleft:元素的左外边框至包含元素的左内边框之间的像素距离。 d.
  • offsettop:元素的上外边框至包含元素的上内边框之间的像素距离。

小程序click-scroll组件设计

2.客户区大小(client dimension)

元素内容及其内边距所占据空间的大小,滚动条占用的空间不计算在内。

  • clientwidth:元素内容区宽度加上左右内边距的宽度
  • clientheight: 元素内容区高度加上上下内边距的高度

小程序click-scroll组件设计

3.滚动大小(scroll dimension)

包含滚动内容的元素的大小。

  • scrollheight:在没有滚动条的情况下,元素内容的实际总高度。
  • scrollwidth:在没有滚动条的情况下,元素内容的实际总宽度。
  • scrollleft:被隐藏在内容区域左侧的像素数。通过设置这个属性可以改变元素的滚动位置。
  • scrolltop:被隐藏在内容区域上方的像素数。通过设置这个属性可以改变元素的滚动位置。

小程序click-scroll组件设计

四. 组件设计思路

小程序click-scroll组件设计

五. 使用文档

slot:

参数 说明 类型
content 组件实际要展示的内容 dom
<click-scroll>
  <template slot="content">
    <div>
      我是实际要展示的内容啊啊啊啊啊……
    </div>
  </template>
</click-scroll>

六. 组件源码

<template>
 <div class="hui-hui" :id="domid.compid">
  <!--向左滑动-->
  <div class="hui-drag-left"
     :class="{'hui-drag-action': drag.isleft}"
     v-if="drag.isshow"
     @click="onclickleft">
  </div>

  <!--展示的内容-->
  <div :id="domid.containerid"
     class="hui-container"
     v-show="hascontent"
     ref='container'
     @mousedown="onmousedown">
   <slot name="content"></slot>
  </div>
  <div v-show="!hascontent" class="hui-no-data">暂无数据</div>

  <!--向右滑动-->
  <div class="hui-drag-right"
     :class="{'hui-drag-action': drag.isright}"
     v-if="drag.isshow"
     @click="onclickright">
  </div>
 </div>
</template>

<script>
import store from '@/store'
export default {
 name: 'cards-container',
 data () {
  return {
   hascontent: false,
   domid: {
    compid: `hui-comp-${+new date()}`,
    containerid: `hui-container-${+new date()}`
   },
   drag: {
    isshow: false,
    isleft: false,
    isright: false
   }
  }
 },
 methods: {
  judgehascontent () {
   this.hascontent = this.$slots.hasownproperty('content')
  },

  judgedragisshow () {
   const compwidth = this.getcompwidth()
   const contextmaxwidth = this.getcontextmaxwidth()

   if (compwidth >= contextmaxwidth) {
    this.drag.isshow = false
   } else {
    this.drag.isshow = true
   }
   return this.drag.isshow
  },
  judgeisleft () {
   const containerdom = this.getcontainerdom()
   const contentwidth = this.getcontextmaxwidth()

   if (!containerdom && !contentwidth) this.drag.isleft = false
   if (containerdom.offsetwidth + containerdom.scrollleft >= contentwidth) {
    this.drag.isleft = false
   } else {
    this.drag.isleft = true
   }
  },
  judgeisright () {
   const containerdom = this.getcontainerdom()

   if (!containerdom) this.drag.isright = false
   if (containerdom.scrollleft === 0) {
    this.drag.isright = false
   } else {
    this.drag.isright = true
   }
  },

  getcompdom () {
   return document.getelementbyid(this.domid.compid) || null
  },
  getcompwidth () {
   const compdom = this.getcompdom()
   if (!compdom) {
    return 0
   } else {
    return compdom.offsetwidth
   }
  },
  getcontainerdom () {
   return document.getelementbyid(this.domid.containerid) || null
  },
  getcontextmaxwidth () {
   if (!this.$refs.hasownproperty('container')) {
    return 0
   } else {
    const widtharr = []
    for(let e of this.$refs['container'].childnodes) {
     widtharr.push(e.offsetwidth)
    }
    return math.max(...widtharr)
   }
  },

  onmousedown (e) { // 手动滑动
   const containerdom = this.getcontainerdom()
   if (!containerdom) return

   let scrollleft = containerdom.scrollleft
   const containerleft = containerdom.offsetleft
   let ev = e || window.event
   let offsetleft = ev.clientx - containerleft

   document.onmousemove = (e) => {
    let ev = e || window.event
    let nowoffsetleft = ev.clientx - containerleft
    containerdom.scrollleft = scrollleft + (offsetleft - nowoffsetleft)

    this.judgeisleft()
    this.judgeisright()
   }

   document.onmouseup = () => {
    document.onmousemove = null
    document.onmouseup = null
   }
  },

  onclickleft () { // 向左滑动
   if (!this.hascontent && !this.drag.isleft) return

   const containerdom = this.getcontainerdom()
   if (!containerdom) return

   const scrollwidth = containerdom.offsetwidth
   containerdom.scrollleft += scrollwidth

   this.judgeisleft()
   this.judgeisright()
  },

  onclickright () { // 向右滑动
   if (!this.hascontent && !this.drag.isright) return

   const containerdom = this.getcontainerdom()
   if (!containerdom) return

   const scrollwidth = containerdom.offsetwidth
   containerdom.scrollleft -= scrollwidth

   this.judgeisleft()
   this.judgeisright()
  }
 },
 updated () {
  this.$nexttick(() => {
   this.judgehascontent()
   const isshow = this.judgedragisshow()
   if (isshow) {
    this.judgeisleft()
    this.judgeisright()
   }
  })
 },
 mounted () {
  this.judgehascontent()
  const isshow = this.judgedragisshow()
  if (isshow) {
   this.judgeisleft()
   this.judgeisright()
  }
 }
}
</script>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。