You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
5.0 KiB
153 lines
5.0 KiB
5 years ago
|
|
||
|
var throttle = function throttle(func, wait, options) {
|
||
|
var context = void 0;
|
||
|
var args = void 0;
|
||
|
var result = void 0;
|
||
|
var timeout = null;
|
||
|
var previous = 0;
|
||
|
if (!options) options = {};
|
||
|
var later = function later() {
|
||
|
previous = options.leading === false ? 0 : Date.now();
|
||
|
timeout = null;
|
||
|
result = func.apply(context, args);
|
||
|
if (!timeout) context = args = null;
|
||
|
};
|
||
|
return function () {
|
||
|
var now = Date.now();
|
||
|
if (!previous && options.leading === false) previous = now;
|
||
|
var remaining = wait - (now - previous);
|
||
|
context = this;
|
||
|
args = arguments;
|
||
|
if (remaining <= 0 || remaining > wait) {
|
||
|
clearTimeout(timeout);
|
||
|
timeout = null;
|
||
|
previous = now;
|
||
|
result = func.apply(context, args);
|
||
|
if (!timeout) context = args = null;
|
||
|
} else if (!timeout && options.trailing !== false) {
|
||
|
timeout = setTimeout(later, remaining);
|
||
|
}
|
||
|
return result;
|
||
|
};
|
||
|
};
|
||
|
Component({
|
||
|
options: {
|
||
|
addGlobalClass: true,
|
||
|
pureDataPattern: /^_/
|
||
|
},
|
||
|
properties: {
|
||
|
list: {
|
||
|
type: Array,
|
||
|
value: [],
|
||
|
observer: function observer(newVal) {
|
||
|
var _this = this;
|
||
|
|
||
|
if (newVal.length === 0) return;
|
||
|
var data = this.data;
|
||
|
var alphabet = data.list.map(function (item) {
|
||
|
return item.letter;
|
||
|
});
|
||
|
alphabet.unshift("↑");
|
||
|
this.setData({
|
||
|
alphabet: alphabet,
|
||
|
current: alphabet[0]
|
||
|
}, function () {
|
||
|
_this.computedSize();
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
ext:{
|
||
|
type:Object
|
||
|
},
|
||
|
vibrated: {
|
||
|
type: Boolean,
|
||
|
value: true
|
||
|
}
|
||
|
},
|
||
|
data: {
|
||
|
current: 'A',
|
||
|
intoView: '',
|
||
|
touching: false,
|
||
|
alphabet: [],
|
||
|
_tops: [],
|
||
|
_anchorItemH: 0,
|
||
|
_anchorTop: 0
|
||
|
},
|
||
|
lifetimes: {
|
||
|
created: function created() {},
|
||
|
attached: function attached() {
|
||
|
this.__scrollTo = throttle(this._scrollTo, 100, {});
|
||
|
this.__onScroll = throttle(this._onScroll, 100, {});
|
||
|
}
|
||
|
},
|
||
|
methods: {
|
||
|
choose: function choose(e) {
|
||
|
console.log("choose",e);
|
||
|
var item = e.target.dataset.item;
|
||
|
this.triggerEvent('choose', { item: item });
|
||
|
},
|
||
|
scrollTo: function scrollTo(e) {
|
||
|
this.__scrollTo(e);
|
||
|
},
|
||
|
_scrollTo: function _scrollTo(e) {
|
||
|
var data = this.data;
|
||
|
var clientY = e.changedTouches[0].clientY;
|
||
|
console.log(clientY);
|
||
|
var index = Math.floor((clientY - data._anchorTop) / data._anchorItemH);
|
||
|
if(index<0||index>=data.alphabet.length)
|
||
|
return;
|
||
|
var current = data.alphabet[index];
|
||
|
if(current=='↑')
|
||
|
this.setData({current, scrollTop:0, touching:true});
|
||
|
else
|
||
|
this.setData({ current: current, intoView: current=='#'?'hash':current, touching: true });
|
||
|
if (data.vibrated) wx.vibrateShort();
|
||
|
},
|
||
|
computedSize: function computedSize() {
|
||
|
var data = this.data;
|
||
|
var query = this.createSelectorQuery();
|
||
|
query.selectAll('.index_list_item').boundingClientRect();
|
||
|
query.select(".top-view").boundingClientRect();
|
||
|
query.select('.anchor-list').boundingClientRect(function (rect) {
|
||
|
data._anchorItemH = rect.height / data.alphabet.length;
|
||
|
data._anchorTop = rect.top;
|
||
|
//console.log("select anchor list");
|
||
|
});
|
||
|
query.exec(res=>{
|
||
|
data._tops = res[0].map(function (item) {
|
||
|
return item.top-res[1].top;
|
||
|
});
|
||
|
//console.log(res);
|
||
|
});
|
||
|
},
|
||
|
removeTouching: function removeTouching() {
|
||
|
var _this2 = this;
|
||
|
|
||
|
setTimeout(function () {
|
||
|
_this2.setData({ touching: false });
|
||
|
}, 150);
|
||
|
},
|
||
|
onScroll: function onScroll(e) {
|
||
|
this.__onScroll(e);
|
||
|
},
|
||
|
_onScroll: function _onScroll(e) {
|
||
|
var data = this.data;
|
||
|
var _tops = data._tops,
|
||
|
alphabet = data.alphabet;
|
||
|
//console.log("scroll", e.detail, this.data);
|
||
|
var pageTop = e.detail.scrollTop;
|
||
|
var current = '';
|
||
|
if (pageTop < _tops[0]) {
|
||
|
current = alphabet[0];
|
||
|
} else {
|
||
|
for (var i = 0, len = _tops.length; i < len - 1; i++) {
|
||
|
if (pageTop >= _tops[i] && pageTop < _tops[i + 1]) {
|
||
|
current = alphabet[i+1];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (!current) current = alphabet[alphabet.length - 1];
|
||
|
this.setData({ current: current });
|
||
|
}
|
||
|
}
|
||
|
});
|