uni.createSelectorQuery()
.in(this)
.select('#list')
.boundingClientRect()
.exec(ret => {
console.log(ret)
this.winOffsetY = ret[0].top
this.winHeight = ret[0].height
this.itemHeight = this.winHeight / this.lists.length
})```
- 发布:2022-09-22 22:38
- 更新:2022-09-22 23:11
- 阅读:418
产品分类: uniapp/小程序
PC开发环境操作系统: Windows
PC开发环境操作系统版本号: 21H2
HBuilderX类型: 正式
HBuilderX版本号: 3.6.3
第三方开发者工具版本号: 3.1.3
基础库版本号: 未知
项目创建方式: HBuilderX
示例代码:
操作步骤:
<template>
<view class="ray-indexed-list" ref="list" id="list">
<scroll-view :scroll-into-view="scrollViewId" class="ray-indexed-list__scroll" scroll-y>
<view v-for="(list, idx) in lists" :key="idx" :id="'ray-' + idx">
<slot name="item" :itemList="list"></slot>
</view>
</scroll-view>
<view class="ray-indexed-list__menu" @touchstart="touchStart" @touchmove.stop.prevent="touchMove"
@touchend="touchEnd" @mousedown.stop="mousedown" @mousemove.stop.prevent="mousemove"
@mouseleave.stop="mouseleave">
<view v-for="(list, key) in lists" :key="key" class="ray-indexed-list__menu-item"
:class="touchmoveIndex == key ? 'ray-indexed-list__menu--active' : ''">
<text class="ray-indexed-list__menu-text"
:class="touchmoveIndex == key ? 'ray-indexed-list__menu-text--active' : ''">{{ list.key }}</text>
</view>
</view>
<view v-if="touchmove" class="ray-indexed-list__alert-wrapper">
<text class="ray-indexed-list__alert">{{ lists[touchmoveIndex].key }}</text>
</view>
</view>
</template>
<script>
import indexedListItem from './uni-indexed-list-item.vue'
/**
* IndexedList 索引列表
* @description 用于展示索引列表
* @tutorial https://ext.dcloud.net.cn/plugin?id=375
* @value true 展示模式
* @value false 选择模式
* @property {Object} options 索引列表需要的数据对象
*/
export default {
name: 'RayIndexedList',
components: {
indexedListItem
},
props: {
options: {
type: Array,
default () {
return []
}
}
},
data() {
return {
lists: [],
winHeight: 0,
itemHeight: 0,
winOffsetY: 0,
touchmove: false,
touchmoveIndex: -1,
scrollViewId: '',
touchmovable: true,
isPC: false
}
},
watch: {
options: {
handler: function() {
this.setList()
},
deep: true
}
},
mounted() {
// #ifdef H5
this.isPC = this.IsPC()
// #endif
setTimeout(() => {
this.setList()
}, 50)
setTimeout(() => {
this.loaded = true
}, 300);
},
methods: {
setList() {
let index = 0;
this.lists = []
this.options.forEach((value) => {
if (value.data.length === 0) {
return
}
let items = value.data.map(item => {
let obj = {}
obj['key'] = value.letter
obj['name'] = item
obj['itemIndex'] = index
index++
return obj
})
this.lists.push({
key: value.letter,
items: items,
})
})
uni.createSelectorQuery()
.in(this)
.select('#list')
.boundingClientRect()
.exec(ret => {
console.log(ret)
this.winOffsetY = ret[0].top
this.winHeight = ret[0].height
this.itemHeight = this.winHeight / this.lists.length
})
},
touchStart(e) {
this.touchmove = true
let pageY = this.isPC ? e.pageY : e.touches[0].pageY
let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
let item = this.lists[index]
if (item) {
this.scrollViewId = 'ray-' + index
this.touchmoveIndex = index
}
},
touchMove(e) {
let pageY = this.isPC ? e.pageY : e.touches[0].pageY
let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
if (this.touchmoveIndex === index) {
return false
}
let item = this.lists[index]
if (item) {
this.scrollViewId = 'ray-' + index
this.touchmoveIndex = index
}
},
touchEnd() {
this.touchmove = false
// this.touchmoveIndex = -1
},
/**
* 兼容 PC @tian
*/
mousedown(e) {
if (!this.isPC) return
this.touchStart(e)
},
mousemove(e) {
if (!this.isPC) return
this.touchMove(e)
},
mouseleave(e) {
if (!this.isPC) return
this.touchEnd(e)
},
// #ifdef H5
IsPC() {
var userAgentInfo = navigator.userAgent;
var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
var flag = true;
for (let v = 0; v < Agents.length - 1; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false;
break;
}
}
return flag;
},
// #endif
}
}
</script>
<style lang="scss">
.ray-indexed-list {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.ray-indexed-list__scroll {
flex: 1;
}
.ray-indexed-list__menu {
width: 24px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
}
.ray-indexed-list__menu-item {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
align-items: center;
justify-content: center;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.ray-indexed-list__menu-text {
font-size: 12px;
text-align: center;
color: #aaa;
}
.ray-indexed-list__menu--active {
// background-color: rgb(200, 200, 200);
}
.ray-indexed-list__menu--active {}
.ray-indexed-list__menu-text--active {
border-radius: 16px;
width: 16px;
height: 16px;
line-height: 16px;
background-color: #007aff;
color: #fff;
}
.ray-indexed-list__alert-wrapper {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
}
.ray-indexed-list__alert {
width: 80px;
height: 80px;
border-radius: 80px;
text-align: center;
line-height: 80px;
font-size: 35px;
color: #fff;
background-color: rgba(0, 0, 0, 0.5);
}
</style>
<template>
<view class="ray-indexed-list" ref="list" id="list">
<scroll-view :scroll-into-view="scrollViewId" class="ray-indexed-list__scroll" scroll-y>
<view v-for="(list, idx) in lists" :key="idx" :id="'ray-' + idx">
<slot name="item" :itemList="list"></slot>
</view>
</scroll-view>
<view class="ray-indexed-list__menu" @touchstart="touchStart" @touchmove.stop.prevent="touchMove"
@touchend="touchEnd" @mousedown.stop="mousedown" @mousemove.stop.prevent="mousemove"
@mouseleave.stop="mouseleave">
<view v-for="(list, key) in lists" :key="key" class="ray-indexed-list__menu-item"
:class="touchmoveIndex == key ? 'ray-indexed-list__menu--active' : ''">
<text class="ray-indexed-list__menu-text"
:class="touchmoveIndex == key ? 'ray-indexed-list__menu-text--active' : ''">{{ list.key }}</text>
</view>
</view>
<view v-if="touchmove" class="ray-indexed-list__alert-wrapper">
<text class="ray-indexed-list__alert">{{ lists[touchmoveIndex].key }}</text>
</view>
</view>
</template>
<script>
import indexedListItem from './uni-indexed-list-item.vue'
/**
* IndexedList 索引列表
* @description 用于展示索引列表
* @tutorial https://ext.dcloud.net.cn/plugin?id=375
* @value true 展示模式
* @value false 选择模式
* @property {Object} options 索引列表需要的数据对象
*/
export default {
name: 'RayIndexedList',
components: {
indexedListItem
},
props: {
options: {
type: Array,
default () {
return []
}
}
},
data() {
return {
lists: [],
winHeight: 0,
itemHeight: 0,
winOffsetY: 0,
touchmove: false,
touchmoveIndex: -1,
scrollViewId: '',
touchmovable: true,
isPC: false
}
},
watch: {
options: {
handler: function() {
this.setList()
},
deep: true
}
},
mounted() {
// #ifdef H5
this.isPC = this.IsPC()
// #endif
setTimeout(() => {
this.setList()
}, 50)
setTimeout(() => {
this.loaded = true
}, 300);
},
methods: {
setList() {
let index = 0;
this.lists = []
this.options.forEach((value) => {
if (value.data.length === 0) {
return
}
let items = value.data.map(item => {
let obj = {}
obj['key'] = value.letter
obj['name'] = item
obj['itemIndex'] = index
index++
return obj
})
this.lists.push({
key: value.letter,
items: items,
})
})
uni.createSelectorQuery()
.in(this)
.select('#list')
.boundingClientRect()
.exec(ret => {
console.log(ret)
this.winOffsetY = ret[0].top
this.winHeight = ret[0].height
this.itemHeight = this.winHeight / this.lists.length
})
},
touchStart(e) {
this.touchmove = true
let pageY = this.isPC ? e.pageY : e.touches[0].pageY
let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
let item = this.lists[index]
if (item) {
this.scrollViewId = 'ray-' + index
this.touchmoveIndex = index
}
},
touchMove(e) {
let pageY = this.isPC ? e.pageY : e.touches[0].pageY
let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
if (this.touchmoveIndex === index) {
return false
}
let item = this.lists[index]
if (item) {
this.scrollViewId = 'ray-' + index
this.touchmoveIndex = index
}
},
touchEnd() {
this.touchmove = false
// this.touchmoveIndex = -1
},
/**
* 兼容 PC @tian
*/
mousedown(e) {
if (!this.isPC) return
this.touchStart(e)
},
mousemove(e) {
if (!this.isPC) return
this.touchMove(e)
},
mouseleave(e) {
if (!this.isPC) return
this.touchEnd(e)
},
// #ifdef H5
IsPC() {
var userAgentInfo = navigator.userAgent;
var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod"];
var flag = true;
for (let v = 0; v < Agents.length - 1; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false;
break;
}
}
return flag;
},
// #endif
}
}
</script>
<style lang="scss">
.ray-indexed-list {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.ray-indexed-list__scroll {
flex: 1;
}
.ray-indexed-list__menu {
width: 24px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
}
.ray-indexed-list__menu-item {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
align-items: center;
justify-content: center;
/* #ifdef H5 */
cursor: pointer;
/* #endif */
}
.ray-indexed-list__menu-text {
font-size: 12px;
text-align: center;
color: #aaa;
}
.ray-indexed-list__menu--active {
// background-color: rgb(200, 200, 200);
}
.ray-indexed-list__menu--active {}
.ray-indexed-list__menu-text--active {
border-radius: 16px;
width: 16px;
height: 16px;
line-height: 16px;
background-color: #007aff;
color: #fff;
}
.ray-indexed-list__alert-wrapper {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
}
.ray-indexed-list__alert {
width: 80px;
height: 80px;
border-radius: 80px;
text-align: center;
line-height: 80px;
font-size: 35px;
color: #fff;
background-color: rgba(0, 0, 0, 0.5);
}
</style>
预期结果:
{id: "list", dataset: {…}, left: 0, right: 320, top: 0, …}
{id: "list", dataset: {…}, left: 0, right: 320, top: 0, …}
实际结果:
null
null
bug描述:
uni.createSelectorQuery() 在 钉钉小程序 返回 null,微信小程序正常返回
1 个回复
2***@qq.com (作者)
这样可以解决