mint-ui range 源码(?)分析

mint-ui  range 分析

前段时间学习了 mint-ui, 一看,感觉这个 ui 真的是 前端的福音,但是继续学习感觉怪怪的,有一部分出现了问题,

网站上大部分有解答,但是 range 我发现我真心是 找不到答案,就是  拖不动那个滑块,百度也没有资源

当时 是弄了个 input type=range ,正好参数一致,对好位置后放在 那个 range 上面隐形,能正常使用

<input type="range" class="range" v-model.number="rangeValue" max="90" min="10" step="10">

                                             注意这里要使用 .number ,要不然返回的是 字符型的 数据

后来想想不能这样糊弄自己,只好自己去看代码(目前只是小白,写这个单纯交流,勿喷)

html

<template>
  <div class="content" ref="content">
  <!-- <div class="thumb" ref="thumb"></div> -->
    <div class="progress" ref="thumb" :style="{width: progress + '%'}"></div>
    <div class="thumb" ref="thumb" :style="{left: progress + '%'}"></div>
  </div>
</template>

 

 

<script>

data()

data () {
return {
progress : 0 , // 当前的 进度(相对于 整个 range 的 百分比)
max : 100 ,
min : 0 ,
step : 1 ,
dragState : {}, // 拖动的 状态
newProgress : null , // 新的 在 range 里的 占比
isDragging : false , // 是否正在拖动
supportTouch : true // 是否支持 touch 事件(源码里是判断来着,但我还是写死好了)
}
},
 

 

mounted()

 

 //  这里主要就是 给 元素绑定 各种 拖动的事件    

//  我发现 在源码中 主要是没有在这里写 各种绑定事件导致的不能拖动

mounted () {
let element = this . $refs . content // 获取 range 组件的 根节点
element . addEventListener( this . supportTouch ? ' touchstart ' : ' mousedown ' , ( event ) => {
if ( this . isDragging) return
event . preventDefault()
// 就是 防止 在拖动的时候 顺便把 东西给 左键 选中
document . onselectstart = function () { return false }
// 就是 防止 在拖动滑块的时候 顺便把 东西给 拖放了
document . ondragstart = function () { return false }
if ( ! this . supportTouch) { // 这里 this.supportTouch 我顺便被 默认 true 了
document . addEventListener( ' mousemove ' , this . moveFn)
document . addEventListener( ' mouseup ' , this . endFn)
}
this . isDragging = true
if ( this . start) {
this . start( this . supportTouch ? event . changedTouches[ 0] || event . touches[ 0] : event)
}
})
if ( this . supportTouch) {
element . addEventListener( ' touchmove ' , this . moveFn) ;
element . addEventListener( ' touchend ' , this . endFn) ;
element . addEventListener( ' touchcancel ' , this . endFn) ;
}
},
 

 

methods : {
// 获取 滑块的 信息
getThumbPosition () {
// 那个小滑块
let thumb = this . $refs . thumb
// 整个 range 的 容器 (不包括 文字)
let content = this . $refs . content
let contentBox = content . getBoundingClientRect()
let thumbBox = thumb . getBoundingClientRect()
return {
left : thumbBox . left - contentBox . left ,
top : thumbBox . top - contentBox . top ,
thumbBoxLeft : thumbBox . left
}
},
/**********************************************************************

说实话,我这是第一次看到这个函数 getBoundingClientRect(),当时找半天,找不到这个函数的 定义在哪里

查了 资料才知道原来是一个 原生 的函数,特意在控制台输出了一下

返回值:

 

一个一个属性过,说一下

left 和 top 就是理解的那个 left  top

但是 bottom  =  top + height

     right    =  left + width

这个真的是,孤陋寡闻,如闻天音

**********************************************************************/

 
// 刚点击的 滑块 和 点击点 的位置信息
start ( event ) {
console . log( ' start ')
if ( this . disabled) return
let position = this . getThumbPosition()
// 看点击的 位置 和 原先 滑块的 位置有 多少距离
let thumbClickDetalX = event . clientX - position . thumbBoxLeft
// 点击之后 滑块 的 位置 属性
this . dragState = {
thumbStartLeft : position . left ,
thumbStartTop : position . top ,
thumbClickDetalX : thumbClickDetalX
}
},
drag ( event ) {
if ( this . disabled) return
let dragState = this . dragState
let content = this . $refs . content
let contentBox = content . getBoundingClientRect()
// 点击之后 拖动的 距离(搞得这么麻烦我也是醉了)
let deltax = event . pageX - contentBox . left - dragState . thumbStartLeft - dragState . thumbClickDetalX
let stepCount = Math . ceil(( this . max - this . min) / this . step)
// 这里有点奇妙,我卡在这里有一会了。
// 原始的距离 + 拖动的 距离 理论上就是 当前 距离的数值,
// 但是若设置了 步长, 这里 假设 stepCount = 1, 那 % 之后 一直为 0
// 那 当前的 距离就是 原始的 距离 + 拖动 的 距离
// 若 步长 不为 1 假设 为 10
// 若 拖动的 距离 小于 10 那 % 出来的 数字 即为 拖动的 那一段距离,正好被减掉,滑块为 不拖动,
// 若拖动距离 为 10 那 % 之后的 数字为 0, 那就 会 跳了 一格
let newPosition = ( dragState . thumbStartLeft + deltax) -
( dragState . thumbStartLeft + deltax) % ( contentBox . width / stepCount)
 
console . log( newPosition)
let newProgress = newPosition / contentBox . width
console . log( newProgress)
if ( newProgress < 0) {
newProgress = 0
} else if ( newProgress > 1) {
newProgress = 1
}
// console.log(newProgress)
this . progress = newProgress * 100
 
this . $emit( ' input ' , Math . round( this . min + newProgress * ( this . max - this . min)))
},
end () {
if ( this . disabled) return
this . $emit( ' change ' , this . value)
this . dragState = {}
},
moveFn ( event ) {
// console.log(event.touches)
if ( this . drag) {
this . drag( this . supportTouch ? event . touches[ 0] : event)
}
},
endFn ( event ) {
if ( ! this . supportTouch) {
document . removeEventListener( ' mousemove ' , this . moveFn)
document . removeEventListener( ' mouseup ' , this . endFn)
}
document . onselectstart = null
document . ondragstart = null
 
this . isDragging = false
 
if ( this . end) {
this . end( this . supportTouch ? event . touches[ 0] : event)
}
}
}

 

style  只写了很简单的一点

 

< style lang= " stylus " >
.content
  width 100 %
  height 10 px
  background-color pink
  div
    position absolute
    & .thumb
      width 20 px
      height 20 px
      background-color white
      border-radius 50 %
      & .progress
         background-color blue
         height 10 px
</ style >

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值