小程序click-scroll组件设计


Posted in Javascript onJune 18, 2019

一. 背景

有些业务需求,要求前端展示的内容多时可以通过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>

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

Javascript 相关文章推荐
JavaScript 原型继承
Dec 26 Javascript
用js实现trim()的解决办法
Apr 16 Javascript
jQuery中.live()方法的用法深入解析
Dec 30 Javascript
解决html按钮切换绑定不同函数后点击时执行多次函数问题
May 14 Javascript
jQuery实现瀑布流的取巧做法分享
Jan 12 Javascript
jquery结合CSS使用validate实现漂亮的验证
Jan 29 Javascript
JavaScript移除数组内重复元素的方法
Mar 18 Javascript
RequireJS使用注意细节
May 15 Javascript
JavaScript 弹出子窗体并返回结果到父窗体的实现代码
May 28 Javascript
Jquery实现跨域异步上传文件总结
Feb 03 Javascript
Vue使用NProgress进度条的方法
Sep 21 Javascript
你不知道的SpringBoot与Vue部署解决方案
Nov 09 Javascript
在JavaScript中如何访问暂未存在的嵌套对象
Jun 18 #Javascript
用Vue.js在浏览器中实现裁剪图像功能
Jun 18 #Javascript
JS删除String里某个字符的方法
Jan 06 #Javascript
简单了解Javscript中兄弟ifream的方法调用
Jun 17 #Javascript
vue中typescript装饰器的使用方法超实用教程
Jun 17 #Javascript
简单学习5种处理Vue.js异常的方法
Jun 17 #Javascript
js/jQuery实现全选效果
Jun 17 #jQuery
You might like
PHP 开发工具
2006/12/06 PHP
让Json更懂中文(JSON_UNESCAPED_UNICODE)
2011/10/27 PHP
用php实现百度网盘图片直链的代码分享
2012/11/01 PHP
CodeIgniter图像处理类的深入解析
2013/06/17 PHP
php旋转图片90度的方法
2013/11/07 PHP
laravel利用中间件防止未登录用户直接访问后台的方法
2019/09/30 PHP
php设计模式之模板模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
javascript中的toFixed固定小数位数 简单实例分享
2013/07/12 Javascript
动态加载script文件的两种方法
2013/08/15 Javascript
node.js中的fs.fchmodSync方法使用说明
2014/12/16 Javascript
JS开发中百度地图+城市联动实现实时触发查询地址功能
2017/04/13 Javascript
微信浏览器禁止页面下拉查看网址实例详解
2017/06/28 Javascript
JS SetInterval 代码实现页面轮询
2017/08/11 Javascript
AngularJs 最新验证手机号码的实例,成功测试通过
2017/11/26 Javascript
react中使用swiper的具体方法
2018/05/15 Javascript
ES6 系列之 WeakMap的使用示例
2018/08/06 Javascript
详解javascript中的Error对象
2019/04/25 Javascript
微信小程序实现轨迹回放的示例代码
2019/12/13 Javascript
[03:17]DOTA2-DPC中国联赛1月29日Recap集锦
2021/03/11 DOTA
Python开发的十个小贴士和技巧及长常犯错误
2018/09/27 Python
itchat-python搭建微信机器人(附示例)
2019/06/11 Python
Python 类方法和实例方法(@classmethod),静态方法(@staticmethod)原理与用法分析
2019/09/20 Python
pytorch 状态字典:state_dict使用详解
2020/01/17 Python
在Python中通过threshold创建mask方式
2020/02/19 Python
Python插件机制实现详解
2020/05/04 Python
德国BA保镖药房韩文网:kr.ba.de
2017/09/04 全球购物
会议邀请函范文
2014/01/09 职场文书
主管会计岗位责任制
2014/02/10 职场文书
小学国庆节活动方案
2014/02/11 职场文书
《雷雨》教学反思
2014/02/20 职场文书
《小动物过冬》教学反思
2014/04/17 职场文书
经济管理专业求职信
2014/06/09 职场文书
学校联谊协议书
2014/09/16 职场文书
建国大业观后感600字
2015/06/01 职场文书
Python深度学习之Pytorch初步使用
2021/05/20 Python
Android 界面一键变灰 深色主题工具类
2022/04/28 Java/Android