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…
	
	Add table
		Add a link
		
	
		Reference in a new issue