百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>CSS教程> 选中器(picker)插件的实现办法介绍(代码)
分享文章到:

选中器(picker)插件的实现办法介绍(代码)

发布时间:09/01 来源:未知 浏览: 关键词:
本篇文章给大家带来的内容是关于选中器(picker)插件的实现办法介绍(代码),有必然的参照 价值,有需要的伴侣可以参照 一下,但愿对你有所帮忙。

一个正常的选中器插件是非常详细的,一步一步来描写就是。手指滑动内容跟从手指滚动,当内容到底或触顶的时候就不克不及在滚动并且内容要不断保持在准确的位置上。

第一步剖析插件构造

第一要有一个插件容器,整个插件容器包括渐变背景,选中实线,内容容器。结果相似于下面:

picker.jpg

所以对应的代码如下:

<div class="scroller-component" data-role="component">
    <div class="scroller-mask" data-role="mask"></div>
    <div class="scroller-indicator" data-role="indicator"></div>
    <div class="scroller-content" data-role="content">
        <div class="scroller-item" data-value='1'>1</div>
        <div class="scroller-item" data-value="2">2</div>
        <div class="scroller-item" data-value="3">3</div>
        <div class="scroller-item" data-value="4">4</div>
        <div class="scroller-item" data-value="5">5</div>
        <div class="scroller-item" data-value="6">6</div>
        <div class="scroller-item" data-value="7">7</div>
        <div class="scroller-item" data-value="8">8</div>
        <div class="scroller-item" data-value="9">9</div>
        <div class="scroller-item" data-value="10">10</div>
        <div class="scroller-item" data-value="11">11</div>
        <div class="scroller-item" data-value="12">12</div>
        <div class="scroller-item" data-value="13">13</div>
        <div class="scroller-item" data-value="14">14</div>
        <div class="scroller-item" data-value="15">15</div>
        <div class="scroller-item" data-value="16">16</div>
        <div class="scroller-item" data-value="17">17</div>
        <div class="scroller-item" data-value="18">18</div>
        <div class="scroller-item" data-value="19">19</div>
        <div class="scroller-item" data-value="20">20</div>
    </div>
</div>
* {
    margin: 0;
    padding: 0;
}
.scroller-component {
    display: block;
    position: relative;
    height: 238px;
    overflow: hidden;
    width: 100%;
}

.scroller-content {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    z-index: 1;
}

.scroller-mask {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    margin: 0 auto;
    width: 100%;
    z-index: 3;
    transform: translateZ(0px);
    background-image:
        linear-gradient(to bottom, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.6)),
        linear-gradient(to top, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.6));
    background-position: top, bottom;
    background-size: 100% 102px;
    background-repeat: no-repeat;
}

.scroller-item {
    text-align: center;
    font-size: 16px;
    height: 34px;
    line-height: 34px;
    color: #000;
}

.scroller-indicator {
    width: 100%;
    height: 34px;
    position: absolute;
    left: 0;
    top: 102px;
    z-index: 3;
    background-image:
        linear-gradient(to bottom, #d0d0d0, #d0d0d0, transparent, transparent),
        linear-gradient(to top, #d0d0d0, #d0d0d0, transparent, transparent);
    background-position: top, bottom;
    background-size: 100% 1px;
    background-repeat: no-repeat;
}

.scroller-item {
    line-clamp: 1;
    -webkit-line-clamp: 1;
    overflow: hidden;
    text-overflow: ellipsis;
}

css 代码主要作为样式展现,通过外链的方式引入。这里就不做过多的说明。

第二步实现手指滚动容器

1.增加手指触摸事件

let component = document.querySelector('[data-role=component]')

let touchStartHandler = (e) => { }
let touchMoveHandler = (e) => { }
let touchEndHandler = (e) => { }

component.addEventListener('touchstart', touchStartHandler)

component.addEventListener('touchmove', touchMoveHandler)

component.addEventListener('touchend', touchEndHandler)

这样当手指触摸到 component 插件容器的时候就会触发开端,移动,完毕事件。

2.剖析手指滑动容器移动结果

手指上滑内容上滑,手指下拉内容下拉。只需要操纵 content 的位置改动的间隔跟手指滑动的间隔保持一致即可。这里用到了 transform 样式的 translate3d(x, y, z) 属性。其中 x, z 保持不变,y的值就是手指移动的值。

我们连续做拆解,当手指下拉时 content 位置下移就会跟手势保持一致。也就是 y 值变大(需要留意 y 轴正标的目的是往下的)。手指上拉恰好与下拉上滑。当再次下拉或上拉时内容要在本来的根基上保持不变。因此我们需要一个全局变量 __scrollTop 留存这个值。这个值等于会员每次上拉下拉值的和,所以我们需要求出来会员每次上拉下拉的值。

拆解会员上拉的值,当会员手触摸到屏幕的时候就会触发 touchstart 事件,移动的时候会触发 touchmove 事件。分开的时候会触发 touchend 事件。会员上拉的初始值必定是触发 touchstart 时手指的位置。完毕值就是 touchend 时手指的位置。但是这样就不克不及够做到内容跟从手指实时运动了。所以需要拆解 touchmove 事件

touchmove 事件会在会员手指运动的时候不断的触发,也就相当于会员屡次微小 的上下移动。所以我们需要记载下来会员刚开端时触摸的位置。 __startTouchTop 。用手指当前位置减去刚开端触发位置就是会员移动的间隔 __scrollTop。详细代码如下

let content = component.querySelector('[data-role=content]') // 内容容器
let __startTouchTop = 0 // 记载开端滚动的位置
let __scrollTop = 0 // 记载终究滚动的位置
// 这个办法下面立刻讲解
let __callback = (top) => {
    const distance = top
    content.style.transform = 'translate3d(0, ' + distance + 'px, 0)'
}
// 这个办法下面立刻讲解
let __publish = (top, animationDuration) => {
    __scrollTop = top
    __callback(top)
}
let touchStartHandler = (e) => {
    e.preventDefault()
    const target = e.touches ? e.touches[0] : e
    __startTouchTop = target.pageY
}
let touchMoveHandler = (e) => {
    const target = e.touches ? e.touches[0] : e
    let currentTouchTop = target.pageY
    let moveY = currentTouchTop - __startTouchTop
    let scrollTop = __scrollTop
    scrollTop = scrollTop + moveY
    __publish(scrollTop)
    __startTouchTop = currentTouchTop
}

留意1: touchstart 必需要记载触摸位置, touchend 可以不记载。由于会员第一次触摸的位置和下次触摸的位置在统一个地方的大概性几乎微不足道,所以需要在 touchstart 里面重置触摸位置。不然当会员从新触摸的时候内容会闪动

**留意2:e.preventDefault() 办法是处置某些阅读器的兼容问题并且能够提高机能。像QQ阅读器用手指下拉的时候会显现阅读器描写致使办法失败。 可以参照 文档 https://segmentfault.com/a/1190000014134234
https://www.cnblogs.com/ziyunfei/p/5545439.html**

上面的 touchMoveHandler 办法中显现了 __callback 的办法。这个办法是用来操纵内容容器的位置的, __publish 办法是对改动容器位置的一层封装,可以实现跟会员的手指动作同步,也要实现会员手指分开之后位置不准确的推断等。当前先实现跟从会员手指移动

代码到这里,你用阅读器调理成手机模式应当已经可以做到内容跟从鼠标滚动了,但是还存在许多问题,下面会一一把这些问题修复

第三步,限制手指滑动最大值和最小值

当前会员可以无穷上拉下拉,很明显是不合错误的。应当当第一个值轻微超过选中实线下方时就不克不及鄙人拉了,当最后一个值轻微超过选中实线上方时就不克不及在上拉了。所以我们需要俩个值最小滚动值: __minScrollTop 和最大滚动值: __maxScrollTop

运算方式应当是这个模样:会员下拉会发生一个最大值,而最大值应当是第一个元素下拉到中心的位置。中心应当就是元素容器中心的位置

let __maxScrollTop = component.clientHeight / 2 // 滚动最大值

最小值应当是会员上拉时最后一个元素到达中心的位置,因此应当是内容容器-最大值。

let __minScrollTop =  - (content.offsetHeight - __maxScrollTop) // 滚动最小值

最大值最小值有了,只需要在手指上拉下拉的历程中包管 __scrollTop 不大于或者不小于极值即可,因此在 touchMoveHandler 函数中补充如下代码

if (scrollTop > __maxScrollTop || scrollTop < __minScrollTop) {
    if (scrollTop > __maxScrollTop) {
        scrollTop = __maxScrollTop
    } else {
        scrollTop = __minScrollTop
    }
}

第四步元素的位置准确卡在选中实线中

当前手指抬起的时候元素逗留的位置是存在问题,这个也很容易懂得。由于一个元素是有高度的,当你手指移动的间隔只要不是元素高度的整数倍他就会卡在选中实线上。因此我们只需要对移动的间隔除以元素的高度停止四舍五入取整之后再乘以元素的高度就能够包管元素位置是元素高得的倍数了

let indicator = component.querySelector('[data-role=indicator]')
let __itemHeight = parseFloat(window.getComputedStyle(indicator).height)

let touchEndHandler = () => { 
    let scrollTop = Math.round(__scrollTop / __itemHeight).toFixed(5) * __itemHeight
    __publish(scrollTop)
}

这模样发生了俩个问题,一是当极值四舍五入之后超过了极值就会出错,二是元素跳动太大会员体验不好。所以需要处置极值状况和增加动画滑动结果

处置上面问题中发生的极值问题

我们创建一个函数 __scrollTo 专门解决元素位置不合错误的问题

// 滚动到准确位置的办法
let __scrollTo = (top) => {
    top = Math.round((top / __itemHeight).toFixed(5)) * __itemHeight
    let newTop = Math.max(Math.min(__maxScrollTop, top), __minScrollTop)
    if (top !== newTop) {
        if (newTop >= __maxScrollTop) {
            top = newTop - __itemHeight / 2
        } else {
            top = newTop + __itemHeight / 2
        }
    }
    __publish(top, 250) // 这里传入了第二个参数动画时长,先留一个伏笔。后面会讲
}

简便剖析一下,函数内第一行跟此前的一样。对位置停止四舍五入变成元素高度的倍数。第二行推断元素可否大于极值,假如大于最大值就取最大值,小于最小值就取最小值。当滚动值跟新的滚动值不一样的时候说明会员移动超越了极值。然后停止处置。大于等于最大值的时候元素的位置恰好超出半个元素高度的,所以减掉高度的一半,小于最小值的时候刚好相反。增加一半

增加动画滑动结果

这个比力费事,关于动画结果是可以独自开一章来说的。这里我简便说一下我这个动画的思绪吧。尽量长话短说。

第一讲解一下动画实现的道理,动画可以懂得为多张持续的相片快速移动超越眼睛可以捕捉的速度就会构成连接的动作。这就是我懂得的动画,像上面的 touchMoveHandler 办法其实是会被屡次调取的,并且调取频率非常的高,高到了几毫秒调取一次,这个速度你肉眼必定是辨论不出来的,并且每次移动的间隔贼短。所以你看起来就有了跟从手指滚动的结果

所以当手指抬起的时候发明位置不准确这个时候应当实现一个滚动到准确位置的减速动画结果。这里我直接将 vux 里面的 animate.js 文件简化了一下直接拿过来用了

let running = {} // 运转
let counter = 1 // 计时器
let desiredFrames = 60 // 每秒多少帧
let millisecondsPerSecond = 1000 // 每秒的毫秒数

const Animate = {
  // 休止动画
  stop (id) {
    var cleared = running[id] != null
    if (cleared) {
      running[id] = null
    }
    return cleared
  },

  // 推断给定的动画可否还在运转
  isRunning (id) {
    return running[id] != null
  },
  start (stepCallback, verifyCallback, completedCallback, duration, easingMethod, root) {
    let start = Date.now()
    let percent = 0 // 百分比
    let id = counter++
    let dropCounter = 0

    let step = function () {
      let now = Date.now()

      if (!running[id] || (verifyCallback && !verifyCallback(id))) {
        running[id] = null
        completedCallback && completedCallback(desiredFrames - (dropCounter / ((now - start) / millisecondsPerSecond)), id, false)
        return
      }

      if (duration) {
        percent = (now - start) / duration
        if (percent > 1) {
          percent = 1
        }
      }
      let value = easingMethod ? easingMethod(percent) : percent
      if (percent !== 1 && ( !verifyCallback || verifyCallback(id))) {
        stepCallback(value)
        window.requestAnimationFrame(step)
      }
    }

    running[id] = true
    window.requestAnimationFrame(step)
    return id
  }
}

以上代码作为一个js外链独自引入,不知道取什么名就用 animate.js 好了。

简便讲解一下,主如果弄了一个叫 Animate 的对象,里面包括三个属性 stop, isRunning, start。 离别是休止动画,动画可否在施行,开端一个动画。start 是关键,由于其他俩个函数在这个项目中我都没有用过,哈哈。

start 函数包括许多个参数,stepCallback:每次动画施行的时候会员处置的界面元素滚动逻辑;verifyCallback:验证动画可否还需要停止的函数;completedCallback:动画完成时的回调函数;duration:动画时长;easingMethod:规定动画的运动方式,像快进慢出,快进快出等等;root:不消管了,没用到。

完毕动画有俩种方式,第一种是传入的动画时长达成,另一种是验证动画可否还需要施行的函数验证通过。不然动画会不断运动

有了动画函数了,接下来就是怎样使用了。这里我们补充一下 __publish 函数,并且增加一个可否开启动画的全局变量 __isAnimating 和 俩个曲线函数 easeOutCubic, easeInOutCubic

let __isAnimating = false // 可否开启动画
// 开端快后来慢的渐变曲线
let easeOutCubic = (pos) => {
    return (Math.pow((pos - 1), 3) + 1)
}
// 以知足开端和完毕的动画
let easeInOutCubic = (pos) => {
    if ((pos /= 0.5) < 1) {
        return 0.5 * Math.pow(pos, 3)
    }
    return 0.5 * (Math.pow((pos - 2), 3) + 2)
}

let __publish = (top, animationDuration) => {
    if (animationDuration) {
        let oldTop = __scrollTop
        let diffTop = top - oldTop
        let wasAnimating = __isAnimating
        let step = function (percent) {
            __scrollTop = oldTop + (diffTop * percent)
            __callback(__scrollTop)
        }
        let verify = function (id) {
            return __isAnimating === id
        }
        let completed = function (renderedFramesPerSecond, animationId, wasFinished) {
            if (animationId === __isAnimating) {
                __isAnimating = false
            }
        }
        __isAnimating = Animate.start(step, verify, completed, animationDuration, wasAnimating ? easeOutCubic : easeInOutCubic)
    } else {
        __scrollTop = top
        __callback(top)
    }
}

将上面的代码补充完全你就会发明滚动到准确位置的动画结果实现了,下面就讲讲实现的道理。

这里依照函数施行的次序讲解吧。 第一是定义的几个变量, oldTop:用来留存元素的错误位置; diffTop: 传入的 top 是元素滚动的准确位置; step, verify, completed 是 Animate 对象需要的三个回调函数。里面的参数先不消管后面会讲,最下面给 __isAnimating 付了个值。 Animate.start 函数是有返回值的,返回值是当前动画的ID

其中需要留意 wasAnimating ? easeOutCubic : easeInOutCubic 这个。意思就是假如本来的动画存在就将 easeInOutCubic(俩头慢中心快的参数传入进去)函数传入进去, 假如不存在就传入进去 easeOutCubic(开端快后来慢)函数传入进去。相符的场景就是你手指快速滑动抬起动画会施行一段时间吧,这个历程动画就是从快到慢的历程,然后动画还没完毕你又接着快速滑动是不是又从慢到快了。假如你不接着施行是不是动画就由快到慢完毕了。这里为啥传入这俩个参数就不讲解了,完全可以再开一篇博客停止讲解比力费事。

step函数,接受一个 percent 翻译过来是百分比的意思。 下面的第一行代码

__scrollTop = oldTop + (diffTop * percent)

可以懂得成, 老的位置 + 移动的间隔 * 百分比 就是新的位置。百分比不断增大当百分比为百分之百的时候 __scrollTop === top。就实现了一个错误位置到准确位置的过度。

百分比的运算方式是按照时间来运算的,然后被动画曲线停止了加工

if (duration) {
    percent = (now - start) / duration
    if (percent > 1) {
      percent = 1
    }
}
let value = easingMethod ? easingMethod(percent) : percent

上面的是中心代码。start 是调取Animate.start属性的时候记载的一个当前时间,now是内部函数施行的时候记载的一个当前时间。 now - start 就是经过了多长时间,除以 duration动画时长就可以得出动画时长的百分比。下面推断 easingMethod 可否传入假如传入了就对原本匀速增添的百分比停止加工变成了动画曲线转变的百分比。

第一是 step 函数,每次运动调取的函数。接受了一个 percent ,翻译过来是百分比意思。 在外面我定了一个几个部分变量,离别是 oldTop: , , 准确位置减掉错误位置也就是元素滚动的间隔。在 step 函数里给予 __scrollTop 新值

step函数接受了一个叫百分比的参数。 用途就是当元素不在准确位置的时候会发生一个值 __scrollTop, 而元素应当的准确位置的值是 top,元素移动的间隔就是 diffTop = top - oldTop 怎样一步一步的移动到这个位置呢。就通过动画函数穿过来的这个百分比参数。这也是为啥在 __scrollTo 办法中调取 __publish 时参加第二个参数动画时长的缘由了,这样就实现了一个自在滚动的动画

verify函数接受一个当前动画的id参数,验证规则就是 __isAnimating === id 时说明开启了下一个动画 __isAnimating 就会改动。致使验证失败,这个时候就会休止上一个动画

completed函数接受好几个参数,第一个参数是每秒多少帧,第二个参数是当前动画id,第三个参数是完成状态。这里主要用到了第二个参数当前动画id。动画完成的时候应当奖动画id变为false不然会不断走验证的逻辑。

第五步快速短暂触摸,让内容本人快速动起来

像当前内容滑动的间隔根本是等于会员手指触摸的间隔的,这样就跟实际使用不相符,实际中手指用劲一滑内容也会蹭蹭的滚动。就当前这个模样内容一多也能累死会员,所以需要增加会员用劲滑动内容快速滚动起来的逻辑

第一内容本人快速动起来很明显是有个触发前提的,这里的触发前提是 touchEndHandler 函数施行时的时间减去当最后一次施行 touchMoveHandler 函数的时间小于100毫秒。知足这种状态我们认为会员开启快速滚动状态。所以增加一个全局变量 __lastTouchMove 来记载最后一次施行 touchMoveHandler 函数的时间。

知道应当快速滚动了,怎样推断应当滚动多长的间隔呢?想一下当前的前提,有一个 __lastTouchMove 和施行 touchEndHandler 函数的时间。这俩个是不是能够的出来一个时间差。在想一下是不是有个 __scrollTop 滚动的位置,假如在猎取到上一个滚动的位置是不是能够得到一个位置差。那位置 / 时间是等于速度的。我们让 __scrollTop + 速度 是不是可以得到新的位置。然后我们不断减小速度捡到最后等于 0 是不是就得到了滚动的位置,并且能够按照会员的快速滑动状况的出来应当滚动多长的间隔,会员滑的越快速度越快间隔越远,相反的会员滑动的速度越慢间隔越近

遗憾的是在 touchEndHandler 函数中拿不到目标移动的间隔 pageY。所以我们需要在 touchMoveHandler 办法中做手足,去记载每次施行这个办法时的时间和位置。所以我们再增加一个全局变量 __positions 为数组类型。

// 上面提到的俩个全局变量的代码
let __lastTouchMove = 0 // 最后滚动时间记载
let __positions = [] // 记载位置和时间

然后我们将增添 __positions 的代码增加到 touchMoveHandler 办法中

if (__positions.length > 40) {
    __positions.splice(0, 20)
}
__positions.push(scrollTop, e.timeStamp)

__publish(scrollTop)

__startTouchTop = currentTouchTop
__lastTouchMove = e.timeStamp

其中假如 __positions 的长度超越40我们就取后20个。由于数组太大占用内存,并且轮回遍历的时候还非常白费时间。按照上面的逻辑我们手指快速移动不会取时间过长的数据,所以20足够了。当有了珍贵的位置和时间数据我们就需要在 touchEndHandler 办法中剖析出来移动的速度了。这里我将完全的代码先切出来。

let __deceleratingMove = 0 // 减速状态每帧移动的间隔
let __isDecelerating = false // 可否开启减速状态
let touchEndHandler = (e) => {
    if (e.timeStamp - __lastTouchMove < 100) { // 假如抬起时间和最后移动时间小于 100 证明快速滚动过
        let positions = __positions
        let endPos = positions.length - 1
        let startPos = endPos
        // 由于留存的时候位置跟时间都留存了, 所以 i -= 2
        // positions[i] > (self.__lastTouchMove - 100) 推断是从什么时候开端的快速滑动
        for (let i = endPos; i > 0 && positions[i] > (__lastTouchMove - 100); i -= 2) {
            startPos = i
        }
        if (startPos !== endPos) {
            // 运算这两点之间的相对运动
            let timeOffset = positions[endPos] - positions[startPos] // 快速开端时间 - 完毕滚动时间
            let movedTop = __scrollTop - positions[startPos - 1] // 终究间隔 - 快速开端间隔
            
            __deceleratingMove = movedTop / timeOffset * (1000 / 60) // 1000 / 60 代表 1秒60每帧 也就是 60fps。玩游戏的大概懂得 60fps是啥意思
    
            let minVelocityToStartDeceleration = 4 // 开端减速的最小速度 
            // 只要速度大于最小加快速度时才会显现下面的动画
            if (Math.abs(__deceleratingMove) > minVelocityToStartDeceleration) {
                __startDeceleration()
            }
        }
    }
    if (!__isDecelerating) {
        __scrollTo(__scrollTop)
    }
    
    __positions.length = 0
}

新增加了俩个全局变量运动速度和减速状态记载。当减速状态为true的时候必定不克不及施行 __scrollTo 办法的由于这俩个办法是冲突的。所以需要 __isDecelerating 记载一下。里面新定义了一个函数 __startDeceleration。 我们的减速办法也主如果在这个办法里面实现的。给你一下代码

// 开端减速动画
let __startDeceleration = () => {
    let step = () => {
        let scrollTop = __scrollTop + __deceleratingMove
        let scrollTopFixed = Math.max(Math.min(__maxScrollTop, scrollTop), __minScrollTop) // 不小于最小值,不大于最大值
        if (scrollTopFixed !== scrollTop) {
            scrollTop = scrollTopFixed
            __deceleratingMove = 0
        }
        if (Math.abs(__deceleratingMove) <= 1) {
            if (Math.abs(scrollTop % __itemHeight) < 1) {
                __deceleratingMove = 0
            }
        } else {
            __deceleratingMove *= 0.95
        }
        __publish(scrollTop)
    }
    let minVelocityToKeepDecelerating = 0.5
    let verify = () => {
        // 保持减速运转需要多少速度
        let shouldContinue = Math.abs(__deceleratingMove) >= minVelocityToKeepDecelerating
        return shouldContinue
    }
    let completed = function (renderedFramesPerSecond, animationId, wasFinished) {
        __isDecelerating = false
        if (__scrollTop <= __minScrollTop || __scrollTop >= __maxScrollTop) {
            __scrollTo(__scrollTop)
            return
        }
    }
    __isDecelerating = Animate.start(step, verify, completed)
}

当你把这些代码都加进去的时候,选中器插件根本上就已经完成了。下面讲解一下这段让你头痛的代码。

这里面用到了动画,所以必定包括三大回调函数 step, verify, completed。然后一个一个讲解一下

step函数:这个函数是让内容一步一步运动的,这个函数根本上跟滚动到准确位置的函数类似度很高。 新的位置是老位置 __scrollTop 加上每帧移动的位置 __deceleratingMove。 然后让每帧移动的位置不断减少,但是需要留意 scrollTop 不克不及超出极值,所以做了最大值最小值推断当抵达极值的时候就将 __deceleratingMove 赋值为0 。

if (Math.abs(__deceleratingMove) <= 1) {
    if (Math.abs(scrollTop % __itemHeight) < 1) {
        __deceleratingMove = 0
    }
}

这段代码,你大概佷懵。他的作用是当滚动的位置没有抵达极值的时候怎样让他卡在准确位置上。 Math.abs(__deceleratingMove) 这是每帧移动的间隔的绝对值。当他小于1的时候说明移动的间隔已经非常小了,会员根本上都发觉不到移动了。然后再用新位置对元素高度取余,假如余数为0表示恰好卡在准确位置上,但是即便轻微比 0 大那么一丢丢也看不出来,并且根本不会那么巧取到 0,所以当余数知足小于 1 的时候讲每帧移动的间隔赋值为0.

verify函数:定义了一个最小每帧移动间隔的部分变量 minVelocityToKeepDecelerating, 当 __deceleratingMove 值小于他的时候说明会员根本上不会发明内容还在移动可以停下来了。

completed函数:既然是完成函数就必然要将 __isDecelerating 参数变为false,不然下次停止的不是快速移动内容就没法跑到准确位置上了。这里多加了一步可否是极值的推断,假如是极值就施行 __scrollTo 函数到准确位置上。

本篇文章到这里就已经全部完毕了,更多其他出色内容可以关注PHP中文网的CSS视频教程栏目!

以上就是选中器(picker)插件的实现办法介绍(代码)的具体内容,更多请关注百分百源码网其它相关文章!

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有151人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板