?
This commit is contained in:
parent
88315d3e80
commit
877a7a81bb
3 changed files with 20 additions and 30 deletions
|
@ -41,7 +41,7 @@
|
||||||
import { computed, ComputedRef, isRef, nextTick, onActivated, onBeforeUnmount, onDeactivated, onMounted, ref, watch } from 'vue';
|
import { computed, ComputedRef, isRef, nextTick, onActivated, onBeforeUnmount, onDeactivated, onMounted, ref, watch } from 'vue';
|
||||||
import * as misskey from 'misskey-js';
|
import * as misskey from 'misskey-js';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import { isBottomVisible, isTopVisible, getBodyScrollHeight, getScrollContainer, scrollToBottom, scroll, scrollToTop } from '@/scripts/scroll';
|
import { isBottomVisible, isTopVisible, getBodyScrollHeight, getScrollContainer, scrollToBottom, scrollToTop, scroll } from '@/scripts/scroll';
|
||||||
import { useDocumentVisibility } from '@/scripts/use-document-visibility';
|
import { useDocumentVisibility } from '@/scripts/use-document-visibility';
|
||||||
import MkButton from '@/components/MkButton.vue';
|
import MkButton from '@/components/MkButton.vue';
|
||||||
import { defaultStore } from '@/store';
|
import { defaultStore } from '@/store';
|
||||||
|
@ -151,7 +151,8 @@ const {
|
||||||
const displayLimit = computed(() => props.pagination.displayLimit ?? props.pagination.limit * 2);
|
const displayLimit = computed(() => props.pagination.displayLimit ?? props.pagination.limit * 2);
|
||||||
|
|
||||||
const contentEl = $computed(() => props.pagination.pageEl ?? rootEl);
|
const contentEl = $computed(() => props.pagination.pageEl ?? rootEl);
|
||||||
const scrollableElement = $computed(() => contentEl ? getScrollContainer(contentEl) ?? document.body : document.body);
|
const scrollableElement = $computed(() => contentEl ? getScrollContainer(contentEl) ?? null : null);
|
||||||
|
const scrollableElementOrHtml = $computed(() => scrollableElement ?? document.getElementsByName('html')[0]);
|
||||||
|
|
||||||
const visibility = useDocumentVisibility();
|
const visibility = useDocumentVisibility();
|
||||||
|
|
||||||
|
@ -173,7 +174,7 @@ watch([() => props.pagination.reversed, $$(scrollableElement)], () => {
|
||||||
weakBacked = entries[0].isIntersecting;
|
weakBacked = entries[0].isIntersecting;
|
||||||
if (weakBacked) backed = true;
|
if (weakBacked) backed = true;
|
||||||
}, {
|
}, {
|
||||||
root: scrollableElement,
|
root: scrollableElementOrHtml,
|
||||||
rootMargin: props.pagination.reversed ? '-100% 0px 100% 0px' : '100% 0px -100% 0px',
|
rootMargin: props.pagination.reversed ? '-100% 0px 100% 0px' : '100% 0px -100% 0px',
|
||||||
threshold: 0.1, // 10%ぐらいになったらqueueを読む
|
threshold: 0.1, // 10%ぐらいになったらqueueを読む
|
||||||
});
|
});
|
||||||
|
@ -219,7 +220,7 @@ watch([$$(weakBacked), $$(contentEl)], () => {
|
||||||
// とりあえず評価してみる
|
// とりあえず評価してみる
|
||||||
onScroll();
|
onScroll();
|
||||||
|
|
||||||
const container = scrollableElement;
|
const container = scrollableElementOrHtml;
|
||||||
|
|
||||||
function removeListener() { container.removeEventListener('scroll', onScroll); }
|
function removeListener() { container.removeEventListener('scroll', onScroll); }
|
||||||
container.addEventListener('scroll', onScroll, { passive: true });
|
container.addEventListener('scroll', onScroll, { passive: true });
|
||||||
|
@ -232,11 +233,12 @@ watch([$$(weakBacked), $$(contentEl)], () => {
|
||||||
* @param fn DOM操作(unshiftItemsなどで)
|
* @param fn DOM操作(unshiftItemsなどで)
|
||||||
*/
|
*/
|
||||||
function adjustScroll(fn: () => void): Promise<void> {
|
function adjustScroll(fn: () => void): Promise<void> {
|
||||||
const oldHeight = scrollableElement.scrollHeight;
|
const oldHeight = scrollableElement ? scrollableElement.scrollHeight : getBodyScrollHeight();
|
||||||
const oldScroll = scrollableElement.scrollTop;
|
const oldScroll = scrollableElement ? scrollableElement.scrollTop : window.scrollY;
|
||||||
|
|
||||||
fn();
|
fn();
|
||||||
return nextTick(() => {
|
return nextTick(() => {
|
||||||
const top = oldScroll + (scrollableElement.scrollHeight - oldHeight);
|
const top = oldScroll + ((scrollableElement ? scrollableElement.scrollHeight : getBodyScrollHeight()) - oldHeight);
|
||||||
scroll(scrollableElement, { top, behavior: 'instant' });
|
scroll(scrollableElement, { top, behavior: 'instant' });
|
||||||
if (top > TOLERANCE) {
|
if (top > TOLERANCE) {
|
||||||
weakBacked = true;
|
weakBacked = true;
|
||||||
|
@ -349,22 +351,7 @@ const fetchMore = async (): Promise<void> => {
|
||||||
if (i === 10) item._shouldInsertAd_ = true;
|
if (i === 10) item._shouldInsertAd_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const reverseConcat = _res => {
|
const reverseConcat = (_res) => adjustScroll(() => concatMapWithArray(items.value, _res));
|
||||||
const oldHeight = scrollableElement ? scrollableElement.scrollHeight : getBodyScrollHeight();
|
|
||||||
const oldScroll = scrollableElement ? scrollableElement.scrollTop : window.scrollY;
|
|
||||||
|
|
||||||
items.value = concatMapWithArray(items.value, _res);
|
|
||||||
|
|
||||||
return nextTick(() => {
|
|
||||||
if (scrollableElement) {
|
|
||||||
scroll(scrollableElement, { top: oldScroll + (scrollableElement.scrollHeight - oldHeight), behavior: 'instant' });
|
|
||||||
} else {
|
|
||||||
window.scroll({ top: oldScroll + (getBodyScrollHeight() - oldHeight), behavior: 'instant' });
|
|
||||||
}
|
|
||||||
|
|
||||||
return nextTick();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
if (res.length === 0) {
|
if (res.length === 0) {
|
||||||
if (props.pagination.reversed) {
|
if (props.pagination.reversed) {
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, watch } from 'vue';
|
import { computed, watch } from 'vue';
|
||||||
import MkTimeline from '@/components/MkTimeline.vue';
|
import MkTimeline from '@/components/MkTimeline.vue';
|
||||||
import { scroll } from '@/scripts/scroll';
|
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import { useRouter } from '@/router';
|
import { useRouter } from '@/router';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||||
|
|
|
@ -70,12 +70,16 @@ export function onScrollBottom(el: HTMLElement, cb: () => unknown, tolerance = 1
|
||||||
return removeListener;
|
return removeListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function scroll(el: HTMLElement, options: ScrollToOptions | undefined) {
|
/**
|
||||||
const container = getScrollContainer(el);
|
* コンテナを指定してスクロールする
|
||||||
if (container == null) {
|
* @param el Container element
|
||||||
|
* @param options ScrollToOptions
|
||||||
|
*/
|
||||||
|
export function scroll(el: HTMLElement | null, options: ScrollToOptions | undefined) {
|
||||||
|
if (el == null) {
|
||||||
window.scroll(options);
|
window.scroll(options);
|
||||||
} else {
|
} else {
|
||||||
container.scroll(options);
|
el.scroll(options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,8 +88,8 @@ export function scroll(el: HTMLElement, options: ScrollToOptions | undefined) {
|
||||||
* @param el Scroll container element
|
* @param el Scroll container element
|
||||||
* @param options Scroll options
|
* @param options Scroll options
|
||||||
*/
|
*/
|
||||||
export function scrollToTop(el: HTMLElement, options: { behavior?: ScrollBehavior; } = {}) {
|
export function scrollToTop(el: HTMLElement | null, options: { behavior?: ScrollBehavior; } = {}) {
|
||||||
scroll(el, { top: 0, ...options });
|
scroll(getScrollContainer(el), { top: 0, ...options });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue