天天看点

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 } },

  // 刚点击的 滑块 和 点击点 的位置信息 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 >

版权声明:本文为CSDN博主「dongcehao」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/dongcehao/article/details/79508986