wip
This commit is contained in:
parent
b88fc1fb4e
commit
99d8172ae5
3 changed files with 23 additions and 20 deletions
|
@ -287,7 +287,7 @@ onDeactivated(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
function toBottom() {
|
function toBottom() {
|
||||||
if (scrollableElement) scrollToBottom(scrollableElement);
|
scrollToBottom(contentEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
|
@ -49,7 +49,7 @@ import XList from '@/components/date-separated-list.vue';
|
||||||
import MkPagination, { Paging } from '@/components/ui/pagination.vue';
|
import MkPagination, { Paging } from '@/components/ui/pagination.vue';
|
||||||
import XMessage from './messaging-room.message.vue';
|
import XMessage from './messaging-room.message.vue';
|
||||||
import XForm from './messaging-room.form.vue';
|
import XForm from './messaging-room.form.vue';
|
||||||
import { isBottom, onScrollBottom, scroll } from '@/scripts/scroll';
|
import { isBottom, onScrollBottom, scrollToBottom } from '@/scripts/scroll';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import { stream } from '@/stream';
|
import { stream } from '@/stream';
|
||||||
import * as sound from '@/scripts/sound';
|
import * as sound from '@/scripts/sound';
|
||||||
|
@ -134,7 +134,7 @@ async function fetch() {
|
||||||
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
pagingComponent.inited.then(() => {
|
pagingComponent.inited.then(() => {
|
||||||
scrollToBottom();
|
thisScrollToBottom();
|
||||||
});
|
});
|
||||||
window.setTimeout(() => {
|
window.setTimeout(() => {
|
||||||
fetching = false
|
fetching = false
|
||||||
|
@ -194,7 +194,7 @@ function onMessage(message) {
|
||||||
if (_isBottom) {
|
if (_isBottom) {
|
||||||
// Scroll to bottom
|
// Scroll to bottom
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
scrollToBottom();
|
thisScrollToBottom();
|
||||||
});
|
});
|
||||||
} else if (message.userId != $i?.id) {
|
} else if (message.userId != $i?.id) {
|
||||||
// Notify
|
// Notify
|
||||||
|
@ -234,13 +234,13 @@ function onDeleted(id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function scrollToBottom() {
|
function thisScrollToBottom() {
|
||||||
scroll(rootEl, { top: rootEl.scrollHeight || 999999, behavior: "smooth" });
|
scrollToBottom($$(rootEl).value, { behavior: "smooth" });
|
||||||
}
|
}
|
||||||
|
|
||||||
function onIndicatorClick() {
|
function onIndicatorClick() {
|
||||||
showIndicator = false;
|
showIndicator = false;
|
||||||
scrollToBottom();
|
thisScrollToBottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
function notifyNewMessage() {
|
function notifyNewMessage() {
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
type ScrollBehavior = 'auto' | 'smooth' | 'instant';
|
|
||||||
|
|
||||||
export function getScrollContainer(el: HTMLElement | null): HTMLElement | null {
|
export function getScrollContainer(el: HTMLElement | null): HTMLElement | null {
|
||||||
if (el == null || el.tagName === 'HTML') return null;
|
if (el == null || el.tagName === 'HTML') return null;
|
||||||
const overflow = window.getComputedStyle(el).getPropertyValue('overflow');
|
const overflow = window.getComputedStyle(el).getPropertyValue('overflow');
|
||||||
|
@ -19,7 +17,7 @@ export function getScrollPosition(el: HTMLElement | null): number {
|
||||||
return container == null ? window.scrollY : container.scrollTop;
|
return container == null ? window.scrollY : container.scrollTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isTopVisible(el: HTMLElement | null): boolean {
|
export function isTopVisible(el: HTMLElement): boolean {
|
||||||
const scrollTop = getScrollPosition(el);
|
const scrollTop = getScrollPosition(el);
|
||||||
const topPosition = el.offsetTop; // TODO: container内でのelの相対位置を取得できればより正確になる
|
const topPosition = el.offsetTop; // TODO: container内でのelの相対位置を取得できればより正確になる
|
||||||
|
|
||||||
|
@ -32,10 +30,12 @@ export function onScrollTop(el: HTMLElement, cb) {
|
||||||
if (!document.body.contains(el)) return;
|
if (!document.body.contains(el)) return;
|
||||||
if (isTopVisible(el)) {
|
if (isTopVisible(el)) {
|
||||||
cb();
|
cb();
|
||||||
container.removeEventListener('scroll', onScroll);
|
removeListener();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
function removeListener() { container.removeEventListener('scroll', onScroll) }
|
||||||
container.addEventListener('scroll', onScroll, { passive: true });
|
container.addEventListener('scroll', onScroll, { passive: true });
|
||||||
|
return removeListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function onScrollBottom(el: HTMLElement, cb) {
|
export function onScrollBottom(el: HTMLElement, cb) {
|
||||||
|
@ -45,17 +45,15 @@ export function onScrollBottom(el: HTMLElement, cb) {
|
||||||
if (!document.body.contains(el)) return;
|
if (!document.body.contains(el)) return;
|
||||||
if (isBottom(el, 1, container)) {
|
if (isBottom(el, 1, container)) {
|
||||||
cb();
|
cb();
|
||||||
containerOrWindow.removeEventListener('scroll', onScroll);
|
removeListener();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
function removeListener() { containerOrWindow.removeEventListener('scroll', onScroll) }
|
||||||
containerOrWindow.addEventListener('scroll', onScroll, { passive: true });
|
containerOrWindow.addEventListener('scroll', onScroll, { passive: true });
|
||||||
|
return removeListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function scroll(el: HTMLElement, options: {
|
export function scroll(el: HTMLElement, options: ScrollToOptions | undefined) {
|
||||||
top?: number;
|
|
||||||
left?: number;
|
|
||||||
behavior?: ScrollBehavior;
|
|
||||||
}) {
|
|
||||||
const container = getScrollContainer(el);
|
const container = getScrollContainer(el);
|
||||||
if (container == null) {
|
if (container == null) {
|
||||||
window.scroll(options);
|
window.scroll(options);
|
||||||
|
@ -75,11 +73,16 @@ export function scrollToTop(el: HTMLElement, options: { behavior?: ScrollBehavio
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scroll to Bottom
|
* Scroll to Bottom
|
||||||
* @param el Scroll container element
|
* @param el Content element
|
||||||
* @param options Scroll options
|
* @param options Scroll options
|
||||||
|
* @param container Scroll container element
|
||||||
*/
|
*/
|
||||||
export function scrollToBottom(el: HTMLElement, options: { behavior?: ScrollBehavior; } = {}) {
|
export function scrollToBottom(el: HTMLElement, options: ScrollToOptions = {}, container = getScrollContainer(el)) {
|
||||||
scroll(el, { top: el.scrollHeight, ...options }); // TODO: ちゃんと計算する
|
if (container) {
|
||||||
|
container.scroll({ top: el.scrollHeight - container.clientHeight || 0, ...options });
|
||||||
|
} else {
|
||||||
|
window.scroll({ top: el.scrollHeight - window.innerHeight || 0, ...options });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isBottom(el: HTMLElement, asobi = 1, container = getScrollContainer(el)) {
|
export function isBottom(el: HTMLElement, asobi = 1, container = getScrollContainer(el)) {
|
||||||
|
|
Loading…
Reference in a new issue