小程序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 相关文章推荐
js 分页全选或反选标识实现代码
Aug 09 Javascript
jQuery 1.7.2中getAll方法的疑惑分析
May 23 Javascript
jQuery链式操作如何实现以及为什么要用链式操作
Jan 17 Javascript
js循环改变div颜色具体方法
Jun 25 Javascript
node.js中的fs.readdirSync方法使用说明
Dec 17 Javascript
js模仿php中strtotime()与date()函数实现方法
Aug 11 Javascript
JavaScript 数组中最大最小值
Jun 05 Javascript
jQuery自定义数值抽奖活动代码
Jun 11 Javascript
深入理解Angular4中的依赖注入
Jun 07 Javascript
vue2.0结合Element-ui实战案例
Mar 06 Javascript
详解基于vue-cli3快速发布一个fullpage组件
Mar 08 Javascript
vue element中axios下载文件(后端Python)
May 10 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写的serv-u的web申请账号的程序
2006/10/09 PHP
PHP中isset与array_key_exists的区别实例分析
2015/06/02 PHP
PHP微信模板消息操作示例
2017/06/29 PHP
php微信开发之音乐回复功能
2018/06/14 PHP
让textarea自动调整大小的js代码
2011/04/12 Javascript
Yii-自定义删除确认弹框(zyd)jquery实现代码
2013/03/04 Javascript
Jquery 动态循环输出表格具体方法
2013/11/23 Javascript
js利用数组length属性清空和截短数组的小例子
2014/01/15 Javascript
jQuery选择器源码解读(七):elementMatcher函数
2015/03/31 Javascript
JS制作手机端自适应缩放显示
2015/06/11 Javascript
js+css实现上下翻页相册代码分享
2015/08/18 Javascript
设置点击文本框或图片弹出日历控件的实现代码
2016/05/12 Javascript
javascript表单控件实例讲解
2016/09/13 Javascript
JSON键值对序列化和反序列化解析
2017/01/24 Javascript
使用Nuxt.js改造已有项目的方法
2018/08/07 Javascript
详解jQuery中的easyui
2018/09/02 jQuery
bootstrap-table formatter 使用vue组件的方法
2019/05/09 Javascript
vue实现配置全局访问路径头(axios)
2019/11/01 Javascript
Vue中使用Echarts仪表盘展示实时数据的实现
2020/11/01 Javascript
JavaScript实现表单验证功能
2020/12/09 Javascript
win10系统中安装scrapy-1.1
2016/07/03 Python
浅谈python for循环的巧妙运用(迭代、列表生成式)
2017/09/26 Python
Python numpy生成矩阵、串联矩阵代码分享
2017/12/04 Python
Django web框架使用url path name详解
2019/04/29 Python
浅谈Pytorch torch.optim优化器个性化的使用
2020/02/20 Python
Django web自定义通用权限控制实现方法
2020/11/24 Python
SpringBoot首页设置解析(推荐)
2021/02/11 Python
武汉高蓝德国际.net机试
2016/06/24 面试题
Prototype如何实现页面局部定时刷新
2013/08/06 面试题
个人自我剖析材料
2014/02/07 职场文书
大一工商管理职业生涯规划:有梦最美,行动相随
2014/09/18 职场文书
2014年防汛工作总结
2014/12/08 职场文书
三好学生竞选稿范文
2019/08/21 职场文书
Spring Boot项目传参校验的最佳实践指南
2022/04/05 Java/Android
Nginx流量拷贝ngx_http_mirror_module模块使用方法详解
2022/04/07 Servers
MySQL提取JSON字段数据实现查询
2022/04/22 MySQL