组件 mp-indexList.wxml
<scroll-view
class="page page-select-index"
style="height: {{windowHeight}}px;"
enable-back-to-top
scroll-into-view="{{intoView}}"
scroll-y
bindscroll="onScroll"
>
<view>
<slot></slot>
</view>
<view class="index_list_item" wx:for="{{list}}" wx:key="alpha" id="{{item.alpha}}">
<view class="index-group__title font-size-26 tips-color">{{item.alpha}}</view>
<view class="index-group__content">
<view class="index-group__list">
<block wx:for="{{item.subItems}}" wx:for-item="subItem" wx:key="name">
<view
class="index-group__item thin-border-bottom"
hover-class="bg-highlight"
data-item="{{subItem}}"
bindtap="choose">
{{subItem.name}}
</view>
</block>
</view>
</view>
</view>
</scroll-view>
<view
class="anchor-bar__wrp wx-flex"
catchtouchstart='scrollTo'
catchtouchmove='scrollTo'
catchtouchend='removeTouching'
>
<view class="anchor-bar wx-flex__item">
<view class="anchor-list">
<block wx:for="{{alphabet}}" wx:key="*this" wx:for-item="alpha">
<view class="anchor-item {{current == alpha ? ( touching ? 'selected tapped' : 'selected' ): ''}}" data-alpha="{{alpha}}">
<view class="anchor-item__inner">{{alpha}}</view>
<view class="anchor-item__pop">{{alpha}}</view>
</view>
</block>
</view>
</view>
</view>
mp-indexList.js
const throttle = function (func, wait, options) {
let context;
let args;
let result
let timeout = null
// 上次执行时间点
let previous = 0
if (!options) options = {}
// 延迟执行函数
const later = function () {
// 若设定了开始边界不执行选项,上次执行时间始终为0
previous = options.leading === false ? 0 : Date.now()
timeout = null
result = func.apply(context, args)
if (!timeout) context = args = null
}
return function () {
const now = Date.now()
// 首次执行时,如果设定了开始边界不执行选项,将上次执行时间设定为当前时间。
if (!previous && options.leading === false) previous = now
// 延迟执行时间间隔
const remaining = wait - (now - previous)
context = this
args = arguments
// 延迟时间间隔remaining小于等于0,表示上次执行至此所间隔时间已经超过一个时间窗口
// remaining大于时间窗口wait,表示客户端系统时间被调整过
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 (newVal) {
if (newVal.length === 0) return
const data = this.data
const alphabet = data.list.map(item => item.alpha)
this.setData({
alphabet,
current: alphabet[0]
}, () => {
this.computedSize()
})
}
},
vibrated: {
type: Boolean,
value: true
}
},
data: {
windowHeight: 612,
current: 'A',
intoView: '',
touching: false,
alphabet: [],
_tops: [],
_anchorItemH: 0,
_anchorItemW: 0,
_anchorTop: 0,
_listUpperBound: 0
},
lifetimes: {
created() {
},
attached() {
this.__scrollTo = throttle(this._scrollTo, 100, {})
this.__onScroll = throttle(this._onScroll, 100, {})
const {
windowHeight
} = wx.getSystemInfoSync()
this.setData({
windowHeight
})
}
},
methods: {
choose(e) {
const item = e.target.dataset.item
this.triggerEvent('choose', {
item
})
},
scrollTo(e) {
this.__scrollTo(e)
},
_scrollTo(e) {
const data = this.data
const clientY = e.changedTouches[0].clientY
const index = Math.floor((clientY - data._anchorTop) / data._anchorItemH)
const current = data.alphabet[index]
this.setData({
current,
intoView: current,
touching: true
})
// 振动效果
if (data.vibrated) wx.vibrateShort()
},
computedSize() {
const data = this.data
// 计算列表每个区块的高度等信息
const query = this.createSelectorQuery()
query.selectAll('.index_list_item').boundingClientRect(rects => {
const result = rects
data._tops = result.map(item => item.top)
}).exec()
// 计算右侧字母栏小区块的高度等信息
query.select('.anchor-list').boundingClientRect(rect => {
data._anchorItemH = rect.height / data.alphabet.length
data._anchorItemW = rect.width
data._anchorTop = rect.top
}).exec()
// 计算滚动区域的上边界
query.select('.page-select-index').boundingClientRect(rect => {
data._listUpperBound = rect.top
})
},
// throttle 的延迟
removeTouching() {
setTimeout(() => {
this.setData({
touching: false
})
}, 150)
},
onScroll(e) {
this.__onScroll(e)
},
_onScroll(e) {
const data = this.data
const {
_tops,
alphabet
} = data
const scrollTop = e.detail.scrollTop
let current = ''
if (scrollTop < _tops[0]) {
current = alphabet[0]
} else {
for (let i = 0, len = _tops.length; i < len - 1; i++) {
if (scrollTop >= _tops[i] && scrollTop < _tops[i + 1]) {
current = alphabet[i]
}
}
}
if (!current) current = alphabet[alphabet.length - 1]
this.setData({
current
})
}
}
})
mp-indexList.scss
.wx-flex{
display: flex;
align-items: center;
}
.wx-flex__item{
flex: 1;
}
.thin-border-bottom{
position: relative;
}
.thin-border-bottom:after{
content: "";
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px;
border-bottom: 1px solid #EAEAEA;
color: #e5e5e5;
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
z-index: 2;
}
.index-group__title{
padding: 24rpx 24rpx 12rpx;
}
.index-group__content{
font-size: 0;
}
.index-group__item{
padding: 30rpx 24rpx;
font-size: 30rpx;
}
.index-group__item.thin-border-bottom:after{
left: 24rpx;
}
.anchor-bar__wrp{
position: fixed;
top: 0;
bottom: 0;
right: 0;
width: 60rpx;
z-index: 999;
}
.anchor-item{
font-size: 0;
text-align: center;
position: relative;
}
.anchor-item__inner{
line-height: 28rpx;
height: 28rpx;
width: 28rpx;
border-radius: 50%;
display: inline-block;
font-size: 20rpx;
margin: 2rpx 0;
font-weight: 500;
}
.tapped .anchor-item__pop{
display: block;
}
.anchor-item__pop{
position: absolute;
font-size: 64rpx;
width: 100rpx;
height: 100rpx;
line-height: 100rpx;
color: #fff;
background-color: #C9C9C9;
border-radius: 50%;
right: 80rpx;
top: 50%;
transform: translateY(-50%);
display: none;
}
.anchor-item__pop:after{
content: "";
display: block;
position: absolute;
width: 0;
height: 0;
left: 80rpx;
border: 40rpx solid;
border-color: transparent transparent transparent #C9C9C9;
top: 50%;
transform: translateY(-50%);
}
.anchor-item.selected .anchor-item__inner{
color: #fff;
background-color: #1aad19;
}
使用案例
JSON
{
"usingComponents": {
"mp-indexList": "./components/mp-indexList"
}
}
WXML:
<mp-indexList class="city__list" list="{{list}}" bindchoose="onChoose">
<view class="page">
<view class="page__hd">
<view class="page__title">Index List</view>
<view class="page__desc">类通讯录列表</view>
</view>
<view class="page__bd">
</view>
</view>
</mp-indexList>
JS
import cityList from './city-list'
Page({
data: {
list: cityList,
},
})
SCSS
/* sub-pages/business/demos/index-list-demo/index-list.wxss */
.page__hd {
padding: 20px;
}
.page__bd {
padding-bottom: 0px;
}
.page__bd_spacing {
padding-left: 15px;
padding-right: 15px;
}
.page__ft {
padding-bottom: 10px;
text-align: center;
}
.page__title {
text-align: left;
font-size: 20px;
font-weight: 400;
}
.page__desc {
margin-top: 5px;
color: #888888;
text-align: left;
font-size: 14px;
}
.weui-cell_example:before {
left: 52px;
}
page {
background-color: #FFFFFF;
height: 100%;
}
.city__list {
height: 100%;
}
MOCK数据
const cityList = [
{
alpha: 'A',
subItems: [
{ name: '阿坝藏族羌族自治州' },
{ name: '阿克苏地区' },
{ name: '阿拉尔市' },
{ name: '阿拉善盟' },
{ name: '阿勒泰地区' },
{ name: '阿里地区' },
{ name: '安康市' },
{ name: '安庆市' },
{ name: '鞍山市' },
{ name: '安顺市' },
{ name: '安阳市' },
{ name: '澳门半岛' }
]
},
{
alpha: 'B',
subItems: [
{ name: '白城市' },
{ name: '百色市' },
{ name: '白沙黎族自治县' },
{ name: '白山市' },
{ name: '白银市' },
{ name: '巴南区' },
{ name: '宝坻区' },
{ name: '保定市' },
{ name: '宝鸡市' },
{ name: '宝山区' },
{ name: '保山市' },
{ name: '保亭黎族苗族自治县' },
{ name: '包头市' },
{ name: '巴彦淖尔市' },
{ name: '巴中市' },
{ name: '巴音郭楞蒙古自治州' },
{ name: '北碚区' },
{ name: '北辰区' },
{ name: '北海市' },
{ name: '北区' },
{ name: '北屯市' },
{ name: '蚌埠市' },
{ name: '本溪市' },
{ name: '毕节市' },
{ name: '滨海新区' },
{ name: '滨州市' },
{ name: '璧山区' },
{ name: '亳州市' },
{ name: '博尔塔拉蒙古自治州' }
]
},
{
alpha: 'C',
subItems: [
{ name: '沧州市' },
{ name: '长春市' },
{ name: '常德市' },
{ name: '昌都市' },
{ name: '昌吉回族自治州' },
{ name: '昌江黎族自治县' },
{ name: '长宁区' },
{ name: '昌平区' },
{ name: '长沙市' },
{ name: '长寿区' },
{ name: '长治市' },
{ name: '常州市' },
{ name: '朝阳区' },
{ name: '朝阳市' },
{ name: '潮州市' },
{ name: '承德市' },
{ name: '成都市' },
{ name: '城口县' },
{ name: '澄迈县' },
{ name: '郴州市' },
{ name: '赤峰市' },
{ name: '池州市' },
{ name: '崇明区' },
{ name: '崇左市' },
{ name: '楚雄彝族自治州' },
{ name: '滁州市' }
]
},
{
alpha: 'D',
subItems: [
{ name: '大渡口区' },
{ name: '大理白族自治州' },
{ name: '大连市' },
{ name: '丹东市' },
{ name: '凼仔' },
{ name: '儋州市' },
{ name: '大埔区' },
{ name: '大庆市' },
{ name: '大同市' },
{ name: '大兴区' },
{ name: '大兴安岭地区' },
{ name: '达州市' },
{ name: '大足区' },
{ name: '德宏傣族景颇族自治州' },
{ name: '德阳市' },
{ name: '德州市' },
{ name: '垫江县' },
{ name: '定安县' },
{ name: '定西市' },
{ name: '迪庆藏族自治州' },
{ name: '东城区' },
{ name: '东方市' },
{ name: '东莞市' },
{ name: '东丽区' },
{ name: '东区' },
{ name: '东营市' }
]
},
{
alpha: 'E',
subItems: [
{ name: '鄂尔多斯市' },
{ name: '恩施土家族苗族自治州' },
{ name: '鄂州市' }
]
},
{
alpha: 'F',
subItems: [
{ name: '防城港市' },
{ name: '房山区' },
{ name: '丰都县' },
{ name: '奉节县' },
{ name: '丰台区' },
{ name: '奉贤区' },
{ name: '佛山市' },
{ name: '涪陵区' },
{ name: '抚顺市' },
{ name: '阜新市' },
{ name: '阜阳市' },
{ name: '福州市' },
{ name: '抚州市' }
]
},
{
alpha: 'G',
subItems: [
{ name: '甘南藏族自治州' },
{ name: '赣州市' },
{ name: '甘孜藏族自治州' },
{ name: '高雄市' },
{ name: '广安市' },
{ name: '广元市' },
{ name: '广州市' },
{ name: '观塘区' },
{ name: '贵港市' },
{ name: '桂林市' },
{ name: '贵阳市' },
{ name: '果洛藏族自治州' },
{ name: '固原市' }
]
},
{
alpha: 'H',
subItems: [
{ name: '哈尔滨市' },
{ name: '海北藏族自治州' },
{ name: '海淀区' },
{ name: '海东市' },
{ name: '海口市' },
{ name: '海南藏族自治州' },
{ name: '海西蒙古族藏族自治州' },
{ name: '哈密市' },
{ name: '邯郸市' },
{ name: '杭州市' },
{ name: '汉中市' },
{ name: '河北区' },
{ name: '鹤壁市' },
{ name: '河池市' },
{ name: '合川区' },
{ name: '河东区' },
{ name: '合肥市' },
{ name: '鹤岗市' },
{ name: '黑河市' },
{ name: '衡水市' },
{ name: '衡阳市' },
{ name: '和平区' },
{ name: '和田地区' },
{ name: '河西区' },
{ name: '河源市' },
{ name: '菏泽市' },
{ name: '贺州市' },
{ name: '红河哈尼族彝族自治州' },
{ name: '虹口区' },
{ name: '红桥区' },
{ name: '淮安市' },
{ name: '淮北市' },
{ name: '怀化市' },
{ name: '淮南市' },
{ name: '怀柔区' },
{ name: '花莲县' },
{ name: '黄大仙区' },
{ name: '黄冈市' },
{ name: '黄南藏族自治州' },
{ name: '黄浦区' },
{ name: '黄山市' },
{ name: '黄石市' },
{ name: '呼和浩特市' },
{ name: '惠州市' },
{ name: '葫芦岛市' },
{ name: '呼伦贝尔市' },
{ name: '湖州市' }
]
},
{
alpha: 'J',
subItems: [
{ name: '嘉定区' },
{ name: '佳木斯市' },
{ name: '吉安市' },
{ name: '江北区' },
{ name: '江津区' },
{ name: '江门市' },
{ name: '焦作市' },
{ name: '嘉兴市' },
{ name: '嘉义市' },
{ name: '嘉义县' },
{ name: '嘉峪关市' },
{ name: '揭阳市' },
{ name: '吉林市' },
{ name: '基隆市' },
{ name: '济南市' },
{ name: '金昌市' },
{ name: '晋城市' },
{ name: '静安区' },
{ name: '景德镇市' },
{ name: '静海区' },
{ name: '荆门市' },
{ name: '荆州市' },
{ name: '金华市' },
{ name: '济宁市' },
{ name: '津南区' },
{ name: '金山区' },
{ name: '晋中市' },
{ name: '锦州市' },
{ name: '九江市' },
{ name: '九龙城区' },
{ name: '九龙坡区' },
{ name: '酒泉市' },
{ name: '鸡西市' },
{ name: '济源市' },
{ name: '蓟州区' }
]
},
{
alpha: 'K',
subItems: [
{ name: '开封市' },
{ name: '开州区' },
{ name: '喀什地区' },
{ name: '可克达拉市' },
{ name: '克拉玛依市' },
{ name: '克孜勒苏柯尔克孜自治州' },
{ name: '葵青区' },
{ name: '昆明市' },
{ name: '昆玉市' }
]
},
{
alpha: 'L',
subItems: [
{ name: '来宾市' },
{ name: '廊坊市' },
{ name: '兰州市' },
{ name: '拉萨市' },
{ name: '乐东黎族自治县' },
{ name: '乐山市' },
{ name: '梁平区' },
{ name: '凉山彝族自治州' },
{ name: '连云港市' },
{ name: '聊城市' },
{ name: '辽阳市' },
{ name: '辽源市' },
{ name: '离岛区' },
{ name: '丽江市' },
{ name: '临沧市' },
{ name: '临汾市' },
{ name: '临高县' },
{ name: '陵水黎族自治县' },
{ name: '临夏回族自治州' },
{ name: '临沂市' },
{ name: '林芝市' },
{ name: '丽水市' },
{ name: '六安市' },
{ name: '六盘水市' },
{ name: '柳州市' },
{ name: '陇南市' },
{ name: '龙岩市' },
{ name: '娄底市' },
{ name: '路凼城' },
{ name: '路环' },
{ name: '漯河市' },
{ name: '洛阳市' },
{ name: '泸州市' },
{ name: '吕梁市' }
]
},
{
alpha: 'M',
subItems: [
{ name: '马鞍山市' },
{ name: '茂名市' },
{ name: '眉山市' },
{ name: '梅州市' },
{ name: '门头沟区' },
{ name: '绵阳市' },
{ name: '苗栗县' },
{ name: '闵行区' },
{ name: '密云区' },
{ name: '牡丹江市' }
]
},
{
alpha: 'N',
subItems: [
{ name: '南岸区' },
{ name: '南昌市' },
{ name: '南充市' },
{ name: '南川区' },
{ name: '南京市' },
{ name: '南开区' },
{ name: '南宁市' },
{ name: '南平市' },
{ name: '南区' },
{ name: '南通市' },
{ name: '南投县' },
{ name: '南阳市' },
{ name: '那曲市' },
{ name: '内江市' },
{ name: '宁波市' },
{ name: '宁德市' },
{ name: '宁河区' },
{ name: '怒江傈僳族自治州' }
]
},
{
alpha: 'P',
subItems: [
{ name: '盘锦市' },
{ name: '攀枝花市' },
{ name: '澎湖县' },
{ name: '彭水苗族土家族自治县' },
{ name: '平顶山市' },
{ name: '屏东县' },
{ name: '平谷区' },
{ name: '平凉市' },
{ name: '萍乡市' },
{ name: '浦东新区' },
{ name: '普洱市' },
{ name: '莆田市' },
{ name: '普陀区' },
{ name: '濮阳市' }
]
},
{
alpha: 'Q',
subItems: [
{ name: '黔东南苗族侗族自治州' },
{ name: '潜江市' },
{ name: '黔江区' },
{ name: '黔南布依族苗族自治州' },
{ name: '黔西南布依族苗族自治州' },
{ name: '綦江区' },
{ name: '青岛市' },
{ name: '青浦区' },
{ name: '庆阳市' },
{ name: '清远市' },
{ name: '秦皇岛市' },
{ name: '钦州市' },
{ name: '琼海市' },
{ name: '琼中黎族苗族自治县' },
{ name: '齐齐哈尔市' },
{ name: '七台河市' },
{ name: '荃湾区' },
{ name: '泉州市' },
{ name: '曲靖市' },
{ name: '衢州市' }
]
},
{
alpha: 'R',
subItems: [{ name: '日喀则市' }, { name: '日照市' }, { name: '荣昌区' }]
},
{
alpha: 'S',
subItems: [
{ name: '三门峡市' },
{ name: '三明市' },
{ name: '三沙市' },
{ name: '三亚市' },
{ name: '商洛市' },
{ name: '商丘市' },
{ name: '上饶市' },
{ name: '山南市' },
{ name: '汕头市' },
{ name: '汕尾市' },
{ name: '韶关市' },
{ name: '绍兴市' },
{ name: '邵阳市' },
{ name: '沙坪坝区' },
{ name: '沙田区' },
{ name: '神农架林区' },
{ name: '深水埗区' },
{ name: '沈阳市' },
{ name: '深圳市' },
{ name: '石河子市' },
{ name: '石家庄市' },
{ name: '石景山区' },
{ name: '十堰市' },
{ name: '石柱土家族自治县' },
{ name: '石嘴山市' },
{ name: '双河市' },
{ name: '双鸭山市' },
{ name: '顺义区' },
{ name: '朔州市' },
{ name: '四平市' },
{ name: '松江区' },
{ name: '松原市' },
{ name: '绥化市' },
{ name: '遂宁市' },
{ name: '随州市' },
{ name: '宿迁市' },
{ name: '苏州市' },
{ name: '宿州市' }
]
},
{
alpha: 'T',
subItems: [
{ name: '塔城地区' },
{ name: '泰安市' },
{ name: '台北市' },
{ name: '台东县' },
{ name: '台南市' },
{ name: '太原市' },
{ name: '台中市' },
{ name: '泰州市' },
{ name: '台州市' },
{ name: '唐山市' },
{ name: '桃园市' },
{ name: '天门市' },
{ name: '天水市' },
{ name: '铁岭市' },
{ name: '铁门关市' },
{ name: '铜川市' },
{ name: '通化市' },
{ name: '铜梁区' },
{ name: '通辽市' },
{ name: '铜陵市' },
{ name: '潼南区' },
{ name: '铜仁市' },
{ name: '通州区' },
{ name: '吐鲁番市' },
{ name: '图木舒克市' },
{ name: '屯昌县' },
{ name: '屯门区' }
]
},
{
alpha: 'W',
subItems: [
{ name: '万宁市' },
{ name: '万州区' },
{ name: '湾仔区' },
{ name: '潍坊市' },
{ name: '威海市' },
{ name: '渭南市' },
{ name: '文昌市' },
{ name: '文山壮族苗族自治州' },
{ name: '温州市' },
{ name: '乌海市' },
{ name: '武汉市' },
{ name: '芜湖市' },
{ name: '五家渠市' },
{ name: '乌兰察布市' },
{ name: '武隆区' },
{ name: '乌鲁木齐市' },
{ name: '武清区' },
{ name: '巫山县' },
{ name: '武威市' },
{ name: '无锡市' },
{ name: '巫溪县' },
{ name: '五指山市' },
{ name: '吴忠市' },
{ name: '梧州市' }
]
},
{
alpha: 'X',
subItems: [
{ name: '厦门市' },
{ name: '西安市' },
{ name: '湘潭市' },
{ name: '湘西土家族苗族自治州' },
{ name: '襄阳市' },
{ name: '咸宁市' },
{ name: '仙桃市' },
{ name: '咸阳市' },
{ name: '孝感市' },
{ name: '西城区' },
{ name: '西贡区' },
{ name: '锡林郭勒盟' },
{ name: '新北市' },
{ name: '兴安盟' },
{ name: '邢台市' },
{ name: '西宁市' },
{ name: '新乡市' },
{ name: '信阳市' },
{ name: '新余市' },
{ name: '忻州市' },
{ name: '新竹市' },
{ name: '新竹县' },
{ name: '西青区' },
{ name: '西双版纳傣族自治州' },
{ name: '秀山土家族苗族自治县' },
{ name: '宣城市' },
{ name: '许昌市' },
{ name: '徐汇区' },
{ name: '徐州市' }
]
},
{
alpha: 'Y',
subItems: [
{ name: '雅安市' },
{ name: '延安市' },
{ name: '延边朝鲜族自治州' },
{ name: '盐城市' },
{ name: '阳江市' },
{ name: '杨浦区' },
{ name: '阳泉市' },
{ name: '扬州市' },
{ name: '延庆区' },
{ name: '烟台市' },
{ name: '宜宾市' },
{ name: '宜昌市' },
{ name: '伊春市' },
{ name: '宜春市' },
{ name: '宜兰县' },
{ name: '伊犁哈萨克自治州' },
{ name: '银川市' },
{ name: '营口市' },
{ name: '鹰潭市' },
{ name: '益阳市' },
{ name: '永川区' },
{ name: '永州市' },
{ name: '油尖旺区' },
{ name: '酉阳土家族苗族自治县' },
{ name: '元朗区' },
{ name: '渝北区' },
{ name: '岳阳市' },
{ name: '玉林市' },
{ name: '榆林市' },
{ name: '运城市' },
{ name: '云浮市' },
{ name: '云林县' },
{ name: '云阳县' },
{ name: '玉树藏族自治州' },
{ name: '玉溪市' },
{ name: '渝中区' }
]
},
{
alpha: 'Z',
subItems: [
{ name: '枣庄市' },
{ name: '彰化县' },
{ name: '张家界市' },
{ name: '张家口市' },
{ name: '张掖市' },
{ name: '漳州市' },
{ name: '湛江市' },
{ name: '肇庆市' },
{ name: '昭通市' },
{ name: '郑州市' },
{ name: '镇江市' },
{ name: '中山市' },
{ name: '中卫市' },
{ name: '忠县' },
{ name: '中西区' },
{ name: '周口市' },
{ name: '舟山市' },
{ name: '珠海市' },
{ name: '驻马店市' },
{ name: '株洲市' },
{ name: '淄博市' },
{ name: '自贡市' },
{ name: '资阳市' },
{ name: '遵义市' }
]
}
];
export default cityList;