IScroll中文文档css
第一个问题: 边界留白vue
就是这种,上边界(最小),下边界(最大)有两个列表的位置是不能选择的。解决的办法是:es6
在HTML中,添加空白节点就好了。app
第二个问题:初始化以后的滚动中止的事件的第二个参数问题。 函数
var myScroll = new IScroll('#wrapper'); myScroll.on('scrollEnd', function(){ //这里必定不要写成es6箭头函数 //要执行的代码 //这个函数没有参数 });
(1) 第二的个参数,是个函数。它没有参数,并且不要写成,不要写成,不要写成箭头的形式。由于这函数里面的this,是绑定的一些有用信息,好比:this.y是当前滚动的距离等。还有哪些信息能够看 文档中的 滚动条信息 这一栏。若是写成ES6的形式,那this指向就变了,这样就获取不了所需的信息。this
(2) 第二个参数是没有形参的。即没有任何可以使用的参数。spa
第三个问题:定义了snap选项,可是滚动有误差code
开发的日历选择组件picker是使用rem单位自适应的,虽然在配置项中 有个options.snap,官方说能够对齐到固定的位置和元素,可是在使用自适应单位的状况中,这个配置并无展示出真正的效果,滚动的时候必定会出现误差。对象
那怎么解决这个自适应的问题呢?因为是在滚动结束以后,位置才出现的误差。那么我就在滚动结束以后立马调用修正位置的函数就好了。blog
我是在vue中使用的。因此定义下面的函数,由于有 年,月,日,时四个滚动项。因此须要判断是哪个正在滚动
fixPos: function(target,num) { var step = Math.abs(Math.round(target.y / this.itemHeight)); var maxYearLen = this.yearArr.length; var maxMonthLen = this.monthArr.length; var maxDayLen = this.dayArr.length; var maxHourLen = this.hourArr.length; switch(num){ case 0: step = step > maxYearLen ? maxYearLen - 1 : step; break; case 1: step = step > maxMonthLen ? maxMonthLen - 1 : step; break; case 2: step = step > maxDayLen ? maxDayLen - 1 : step; break; case 3: step = step > maxHourLen ? maxHourLen - 1 : step; break; } var fixPos = step * this.itemHeight;//从新计算较为精确的位置 target.y = fixPos;//重置原来的滚动距离 this.selectArr[num] = step;//这是保存每一个列表滚动的索引值 target.scrollTo(0, -fixPos);//这是滚动到修正后的位置 },
(1) 大体的思路就是:首先用当前滚动的距离,来除以滚动内容中,每一个列表的高度。而后取最近似的值,就是当前应该滚动的列表的个数。
(2) 若是出现忽然滚动到最底部,这时候须要滚动的个数大于了滚动内容的最大列表个数,那么就纠正一下个数为最大列表数 - 1。
(3) 而后设置较为精确的滚动距离。再滚动到指定的位置。
(4) this.itemHeight是在created生命周期的时候就声明的 this.itemHeight = (document.body.offsetWidth / 750) * 100 * 0.8; 至关于在375px宽度下,每一个列表就是40px的高度。在iPhone5 320px下,就是34.133334了。
调用的时候:
var yearScroll = new IScroll('#calendarYear'); var that = this; yearScroll.on('scrollEnd', function() { that.fixPos(this, 0); })
第四个问题:使用自适应单位时最大滚动距离不许确
这个问题和第二个问题相似,解决的方法:
fixMaxScrollY: function(target, num) { var yearLen = this.yearArr.length - 1; var monthLen = this.monthArr.length - 1; var dayLen = this.dayArr.length - 1; var hourLen = this.hourArr.length - 1; switch(num) { case 0: target.maxScrollY = -(Math.round(yearLen * this.itemHeight)); break; case 1: target.maxScrollY = -(Math.round(monthLen * this.itemHeight)); break; case 2: target.maxScrollY = -(Math.round(dayLen * this.itemHeight)); break; case 3: target.maxScrollY = -(Math.round(hourLen * this.itemHeight)); break; } },
(1) 实例化后的滚动对象,有个最大滚动值maxScrollY,主要也是根据滚动内容的列表长度来重置最大滚动距离
(2) 由于有四个滚动的内容项,因此须要传入当前是第几个滚动的内容。
调用的时候:
var yearScroll = new IScroll('#calendarYear'); this.fixMaxScrollY(yearScroll, 0);
第五个问题: 日历组件的内容是在点击某个按钮以后再触发显示的,最初是隐藏。但就是这个缘由,致使显示出来的内容滚动不了。
解决的办法是:使用 xxx.refresh() 刷新函数。这个函数具体的说明能够看文档中 刷新 这个选项内容
在控制组件显示的函数中,调用刷新的方法。
this.$nextTick(function(){ this.scrollTarget[0].refresh(); this.scrollTarget[1].refresh(); this.scrollTarget[2].refresh(); this.scrollTarget[3].refresh(); //若是默认隐藏,则必须修复滚动的位置 this.scrollTarget[0].scrollTo(0, -this.itemHeight * this.selectArr[0]); this.scrollTarget[1].scrollTo(0, -this.itemHeight * this.selectArr[1]); this.scrollTarget[2].scrollTo(0, -this.itemHeight * this.selectArr[2]); this.scrollTarget[3].scrollTo(0, -this.itemHeight * this.selectArr[3]); })
(1) scrollTarget 是初始化滚动实例以后,保存的滚动实例。由于屡次会用到。
(2) 由于有年,月,日,时四个滚动内容,因此要刷新四个滚动器。
(3) 若是日历有最初的滚动位置,那么也会出现不能跳到指定的位置的问题。因此,也须要初始化最初始的位置。
(4) selectArr 是滚动器滚动的索引值。好比我月份是1月到12月,当前滚动到了6月,那么此时selectArr[1] 就是5 。
(5) 官方是推荐用setTimeout来使用刷新,可是我使用的是vue来开发的,因此,这里用vm.$nextTick()来代替setTimeout。
第六个问题: 日历组件复用时,只能初始化滚动第一个日历组件,并且第一个日历组件滚动仍是有问题。
这个问题产生的缘由很简单:由于 IScroll 在初始化实例的时候, var myScroll = new IScroll('.wrapper'); 它这个css选择器使用的是querySelector
而不是 querySelectorAll
,因此iScroll只会做用到选择器选中元素的第一个。若是你须要对多个对象使用iScroll,你须要构建本身的循环机制。这是官方的说法。那么怎样创建循环机制呢?难道我要在初始化的时候还要循环去 new IScroll(xxx)建立实例吗?
其实不必。只须要改一改源码就好了。
我使用的是 iscroll-lite 这个版本。这里面 在定义 IScroll 这个函数的时候有这段代码
this.wrapper = typeof el == 'string' ? document.querySelector(el) : el;
它每次初始化时,只选择了 el 滚动对象的第一个元素,那么,我只须要传入当前是第几个日历组件,再改为querySelectorAll就好了。即:
this.wrapper = typeof el == 'string' ? document.querySelectorAll(el)[childIndex] : el;
而后在这个定义的 IScroll 函数的参数中,再增长一个参数,表示第几个元素。
而后在初始化滚动实例的时候:
var options = { snap: '.calendar-scroll-item', //对齐的位置,至关于自动纠正每次移动的距离 //scrollbars: true,//是否显示滚动条 } //初始化滚动 var yearScroll = new IScroll('.calendar-scroll>.calendarYear', options , this.curIndex);
固然这个时候,css选择器就不要用 id 了。
而后在 组件的 prop 里面添加一个属性。
curIndex:{ type:Number, default:0 }
(1) 默认只使用一个组件,即不传这个prop 的话就是默认初始化第一个组件的滚动内容。
使用组件的时候:引入,注册等步骤就省略了
<calendar :cur-index='0'/> <calendar :cur-index='1'/> <calendar :cur-index='2'/>
这样无论使用多少个,都能正常初始化滚动了。并且互不影响 。注意,若是传的是数字,须要v-bind 告诉vue这不是字符串,是表达式。否则传过去的是字符串