小程序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基础知识大集锦(一) 推荐收藏
Jan 13 Javascript
jquery方法+js一般方法+js面向对象方法实现拖拽效果
Aug 30 Javascript
修改js Calendar日历控件 兼容IE9/谷歌/火狐
Jan 04 Javascript
jquery 绑定回车动作扑捉回车键触发的事件
Mar 26 Javascript
JS实现的Select三级下拉菜单代码
Aug 20 Javascript
学习JavaScript设计模式之状态模式
Jan 08 Javascript
JavaScript弹出对话框的三种方式
Mar 23 Javascript
jQuery、layer实现弹出层的打开、关闭功能
Jun 28 jQuery
js实现简易聊天对话框
Aug 17 Javascript
Mac中安装nvm的教程分享
Dec 11 Javascript
Angular处理未可知异常错误的方法详解
Jan 17 Javascript
JS如何使用剪贴板操作Clipboard API
May 17 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 配置文件中open_basedir选项作用
2009/07/19 PHP
php数组中删除元素之重新索引的方法
2014/09/16 PHP
php计划任务之验证是否有多个进程调用同一个job的方法
2015/12/07 PHP
php显示页码分页类的封装
2017/06/08 PHP
js中几种去掉字串左右空格的方法
2006/12/25 Javascript
跨域表单提交状态的变相判断代码
2009/11/12 Javascript
ExtJs使用总结(非常详细)
2012/03/22 Javascript
JavaScript实现统计文本框Textarea字数增强用户体验
2012/12/21 Javascript
捕获键盘事件(且兼容各浏览器)
2013/07/03 Javascript
jquery实现Li滚动时滚动条自动添加样式的方法
2015/08/10 Javascript
第三篇Bootstrap网格基础
2016/06/21 Javascript
js cookie实现记住密码功能
2017/01/17 Javascript
关于Sequelize连接查询时inlude中model和association的区别详解
2017/02/27 Javascript
js获取当前周、上一周、下一周日期
2017/03/19 Javascript
Vue组件中prop属性使用说明实例代码详解
2018/05/31 Javascript
zepto.js 实时监听输入框的方法
2018/12/04 Javascript
Vue的路由及路由钩子函数的实现
2019/07/02 Javascript
python 排列组合之itertools
2013/03/20 Python
Python生成随机MAC地址
2015/03/10 Python
在Gnumeric下使用Python脚本操作表格的教程
2015/04/14 Python
详解JavaScript编程中的window与window.screen对象
2015/10/26 Python
在双python下设置python3为默认的方法
2018/10/31 Python
python如何制作英文字典
2019/06/25 Python
Python发送手机动态验证码代码实例
2020/02/28 Python
Python生成器next方法和send方法区别详解
2020/05/30 Python
HTML5中微数据概述及在搜索引擎中的使用举例
2013/02/07 HTML / CSS
Tarte Cosmetics官网:美国最受欢迎的化妆品公司之一
2017/08/24 全球购物
Etam艾格英国官网:法国著名女装品牌
2019/04/15 全球购物
大学毕业生通用自荐信范文
2013/10/31 职场文书
生产部主管岗位职责
2014/01/06 职场文书
高中课程设置方案
2014/05/28 职场文书
2014年妇产科工作总结
2014/12/08 职场文书
2014年居委会工作总结
2014/12/09 职场文书
幼儿园亲子活动感想
2015/08/07 职场文书
Go 自定义package包设置与导入操作
2021/05/06 Golang
MySQL数据库优化之通过索引解决SQL性能问题
2022/04/10 MySQL