固定滚动距离

This commit is contained in:
fofolee 2022-05-03 14:59:43 +08:00
parent 07f6c93079
commit f784e695c0

View File

@ -2,6 +2,7 @@
<q-card> <q-card>
<q-virtual-scroll <q-virtual-scroll
ref="scrollBar" ref="scrollBar"
@scroll="scrollHandler"
:style="{ maxHeight: listMaxHeight + 'px', height: '100vh' }" :style="{ maxHeight: listMaxHeight + 'px', height: '100vh' }"
:virtual-scroll-slice-size="lazyItemSize" :virtual-scroll-slice-size="lazyItemSize"
:virtual-scroll-item-size="itemHeight" :virtual-scroll-item-size="itemHeight"
@ -16,16 +17,15 @@
@click="clickOK" @click="clickOK"
manual-focus manual-focus
:focused="index === currentIndex" :focused="index === currentIndex"
:active="index === currentIndex"
:style="{ :style="{
height: itemHeight + 'px', height: itemHeight + 'px',
paddingRight: shortCutWidth + 'px', paddingRight: shortCutWidth + 'px',
}" }"
> >
<q-item-section v-if="isText"> <q-item-section v-if="is.text">
<q-item-label lines="1">{{ item }}</q-item-label> <q-item-label lines="1">{{ item }}</q-item-label>
</q-item-section> </q-item-section>
<q-item-section v-else-if="isJson" class="content-start"> <q-item-section v-else-if="is.json" class="content-start">
<q-avatar size="34px" style="margin-right: 16px" v-if="item.icon"> <q-avatar size="34px" style="margin-right: 16px" v-if="item.icon">
<q-img :src="item.icon" /> <q-img :src="item.icon" />
</q-avatar> </q-avatar>
@ -36,7 +36,7 @@
item.description item.description
}}</q-item-label> }}</q-item-label>
</q-item-section> </q-item-section>
<q-item-section v-else-if="isHtml"> <q-item-section v-else-if="is.html">
<div v-html="item"></div> <div v-html="item"></div>
</q-item-section> </q-item-section>
</q-item> </q-item>
@ -44,15 +44,15 @@
</q-virtual-scroll> </q-virtual-scroll>
<div <div
:style="{ top: 0, bottom: 0, width: shortCutWidth + 'px' }" :style="{ top: 0, bottom: 0, width: shortCutWidth + 'px' }"
class="fixed-right" class="fixed-right shortcut"
> >
<div <div
:style="{ height: itemHeight + 'px' }" :style="{ height: itemHeight + 'px' }"
class="flex content-center justify-start q-pa-xs" class="flex content-center justify-start q-pa-xs"
v-for="count in 10" v-for="count in countsPerPage"
:key="count" :key="count"
> >
{{ $q.platform.is.mac ? "⌘" : "Alt" }}+{{ count % 10 }} {{ $q.platform.is.mac ? "⌘" : "Alt" }}+{{ count % countsPerPage }}
</div> </div>
</div> </div>
<q-btn <q-btn
@ -76,14 +76,14 @@ export default {
listMaxHeight: 500, listMaxHeight: 500,
currentIndex: 0, currentIndex: 0,
itemHeight: 50, itemHeight: 50,
lazyItemSize: 50, lazyItemSize: 100,
shortCutWidth: 50, shortCutWidth: 50,
searchWords: "", searchWords: "",
lastTimeStamp: null, topIndex: 0,
timeoutId: null,
}; };
}, },
mounted() { mounted() {
window.aa = this;
this.options.options.enableSearch && this.setSubInput(); this.options.options.enableSearch && this.setSubInput();
this.addListeners(); this.addListeners();
this.setUtoolsHeight(this.itemHeight * this.matchedItemsSize); this.setUtoolsHeight(this.itemHeight * this.matchedItemsSize);
@ -104,14 +104,18 @@ export default {
matchedItemsSize() { matchedItemsSize() {
return this.matchedItems.length; return this.matchedItems.length;
}, },
isJson() { countsPerPage() {
return this.options.options.optionType === "json"; return this.listMaxHeight / this.itemHeight;
}, },
isHtml() { bottomIndex() {
return this.options.options.optionType === "html"; return this.topIndex + this.countsPerPage - 1;
}, },
isText() { is() {
return this.options.options.optionType === "plaintext"; return {
json: this.options.options.optionType === "json",
html: this.options.options.optionType === "html",
text: this.options.options.optionType === "plaintext",
};
}, },
}, },
props: { props: {
@ -124,7 +128,7 @@ export default {
}, },
clickOK() { clickOK() {
let selected = this.isJson let selected = this.is.json
? this.matchedItems[this.currentIndex] ? this.matchedItems[this.currentIndex]
: { : {
id: this.currentIndex, id: this.currentIndex,
@ -134,37 +138,47 @@ export default {
this.options.options.closeOnSelect && this.hide(); this.options.options.closeOnSelect && this.hide();
}, },
changeItemIndex(e) { keyHandler(e) {
e.preventDefault(); e.preventDefault();
if (e.keyCode === 13) return this.clickOK(); if (this.$q.platform.is.mac ? e.metaKey : e.altKey && !isNaN(e.key)) {
if (e.keyCode && e.keyCode !== 38 && e.keyCode !== 40) return; let index = e.key === "0" ? 10 : parseInt(e.key);
if (e.timeStamp - this.lastTimeStamp < 50) return; this.currentIndex = this.topIndex + index - 1;
let value = e.deltaY ? e.deltaY : e.keyCode - 39; return this.clickOK();
switch (value > 0) { }
case false: switch (e.keyCode) {
case 38: //
this.currentIndex = Math.max(0, this.currentIndex - 1); this.currentIndex = Math.max(0, this.currentIndex - 1);
break; break;
case true: case 40: //
this.currentIndex = Math.min( this.currentIndex = Math.min(
this.matchedItemsSize - 1, this.matchedItemsSize - 1,
this.currentIndex + 1 this.currentIndex + 1
); );
break; break;
case 13: //
return this.clickOK();
} }
this.$refs.scrollBar.scrollTo(this.currentIndex); this.$refs.scrollBar.scrollTo(this.currentIndex);
this.lastTimeStamp = e.timeStamp;
}, },
shortCutHandle(e) { scrollHandler(e) {
this.topIndex = parseInt(e.target.scrollTop / this.itemHeight);
clearTimeout(this.timeoutId);
this.timeoutId = setTimeout(() => {
if (this.currentIndex < this.topIndex)
this.currentIndex = this.topIndex;
if (this.currentIndex > this.bottomIndex)
this.currentIndex = this.bottomIndex;
this.timeoutId = null;
}, 200);
},
mouseHandler(e) {
e.preventDefault(); e.preventDefault();
if (!(this.$q.platform.is.mac ? e.metaKey : e.altKey) || isNaN(e.key)) this.$refs.scrollBar.$el.scrollBy(
return; 0,
let index = parseInt(e.key); (e.deltaY / this.itemHeight).toFixed() * this.itemHeight
this.currentIndex = );
Math.ceil(this.$refs.scrollBar.$el.scrollTop / 50) +
(index === 0 ? 10 : index) -
1;
this.clickOK();
}, },
setSubInput() { setSubInput() {
@ -179,18 +193,16 @@ export default {
clear() { clear() {
utools.removeSubInput(); utools.removeSubInput();
document.removeEventListener("keydown", this.changeItemIndex); document.removeEventListener("keydown", this.keyHandler);
document.removeEventListener("keydown", this.shortCutHandle); document.removeEventListener("wheel", this.mouseHandler, {
document.removeEventListener("mousewheel", this.changeItemIndex, {
passive: false, passive: false,
}); });
this.setUtoolsHeight(this.listMaxHeight); this.setUtoolsHeight(this.listMaxHeight);
}, },
addListeners() { addListeners() {
document.addEventListener("keydown", this.changeItemIndex); document.addEventListener("keydown", this.keyHandler);
document.addEventListener("keydown", this.shortCutHandle); document.addEventListener("wheel", this.mouseHandler, {
document.addEventListener("mousewheel", this.changeItemIndex, {
passive: false, passive: false,
}); });
}, },
@ -202,4 +214,8 @@ export default {
.q-card--dark { .q-card--dark {
background: var(--q-dark-page); background: var(--q-dark-page);
} }
.q-item,
.shortcut {
user-select: none;
}
</style> </style>