use the same code for page scrolling on both the desktop and mobile versions

This commit is contained in:
MaysWind
2025-12-21 02:34:35 +08:00
parent 931d5e8395
commit a535fbcef1
20 changed files with 197 additions and 255 deletions
+53
View File
@@ -7,6 +7,59 @@ import { KnownFileType } from '@/core/file.ts';
import logger from '../logger.ts';
export function scrollToSelectedItem(parentEl: Element | null | undefined, containerSelector: string | null, scrollableListSelector: string | null, selectedItemSelector: string): void {
if (!parentEl) {
return;
}
const container = containerSelector ? parentEl.querySelector<HTMLElement>(containerSelector) : parentEl;
if (!container) {
return;
}
const scrollableList = scrollableListSelector ? parentEl.querySelector<HTMLElement>(scrollableListSelector) : parentEl;
if (!scrollableList) {
return;
}
const selectedItems = scrollableList.querySelectorAll<HTMLElement>(selectedItemSelector);
if (!selectedItems.length) {
return;
}
const containerHeight: number = container.clientHeight;
const firstSelectedItem: HTMLElement = selectedItems[0] as HTMLElement;
const lastSelectedItem: HTMLElement = selectedItems[selectedItems.length - 1] as HTMLElement;
const firstSelectedItemHeight: number = firstSelectedItem.offsetHeight;
const firstSelectedItemTop: number = firstSelectedItem.offsetTop;
const lastSelectedItemTop: number = lastSelectedItem.offsetTop;
const lastSelectedItemBottom: number = lastSelectedItem.offsetTop + lastSelectedItem.offsetHeight;
const middle: number = (firstSelectedItemTop + lastSelectedItemBottom) / 2;
let targetScrollTop: number = middle - containerHeight / 2;
if (containerSelector !== scrollableListSelector) {
const scrollableListStyle = window.getComputedStyle(scrollableList);
const paddingTop: number = parseFloat(scrollableListStyle.paddingTop) || 0;
targetScrollTop += paddingTop / 3 * 2;
if (selectedItems.length > 1 && lastSelectedItemTop - firstSelectedItemTop > containerHeight - firstSelectedItemHeight - paddingTop) {
targetScrollTop = firstSelectedItemTop;
}
} else {
if (selectedItems.length > 1 && lastSelectedItemTop - firstSelectedItemTop > containerHeight - firstSelectedItemHeight) {
targetScrollTop = firstSelectedItemTop;
}
}
scrollableList.scrollTop = Math.max(0, targetScrollTop);
}
export function getSystemTheme(): ThemeType {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
return ThemeType.Dark;
-63
View File
@@ -39,15 +39,6 @@ export function getNavSideBarOuterHeight(element: HTMLElement | null): number {
return totalHeight;
}
export function getCssValue(element: HTMLElement | null, name: string): string {
if (!element) {
return '0';
}
const computedStyle = window.getComputedStyle(element);
return computedStyle.getPropertyValue(name);
}
export function setChildInputFocus(parentEl: HTMLElement | undefined, childSelector: string): void {
if (!parentEl) {
return;
@@ -63,57 +54,3 @@ export function setChildInputFocus(parentEl: HTMLElement | undefined, childSelec
childInput.focus();
childInput.select();
}
export function scrollToSelectedItem(parentEl: HTMLElement | null | undefined, containerSelector: string | null, selectedItemSelector: string): void {
if (!parentEl) {
return;
}
let container = parentEl;
if (containerSelector) {
const lists = parentEl.querySelectorAll(containerSelector);
if (!lists.length || !lists[0]) {
return;
}
container = lists[0] as HTMLElement;
}
const selectedItems = container.querySelectorAll(selectedItemSelector);
if (!selectedItems.length || !selectedItems[0]) {
return;
}
const selectedItem = selectedItems[0] as HTMLElement;
const containerOuterHeight = getOuterHeight(container);
const selectedItemOuterHeight = getOuterHeight(selectedItem);
let targetPos = selectedItem.offsetTop - container.offsetTop - parseInt(getCssValue(container, 'padding-top'), 10)
- (containerOuterHeight - selectedItemOuterHeight) / 2;
if (selectedItems.length > 1) {
const firstSelectedItem = selectedItems[0] as HTMLElement;
const lastSelectedItem = selectedItems[selectedItems.length - 1] as HTMLElement;
const firstSelectedItemInTop = firstSelectedItem.offsetTop - container.offsetTop - parseInt(getCssValue(container, 'padding-top'), 10);
const lastSelectedItemInTop = lastSelectedItem.offsetTop - container.offsetTop - parseInt(getCssValue(container, 'padding-top'), 10);
const lastSelectedItemInBottom = lastSelectedItem.offsetTop - container.offsetTop - parseInt(getCssValue(container, 'padding-top'), 10)
- (containerOuterHeight - selectedItemOuterHeight);
targetPos = (firstSelectedItemInTop + lastSelectedItemInBottom) / 2;
if (lastSelectedItemInTop - firstSelectedItemInTop > containerOuterHeight) {
targetPos = firstSelectedItemInTop;
}
}
if (targetPos <= 0) {
return;
}
container.scrollTop = targetPos;
}
-46
View File
@@ -6,7 +6,6 @@ import { useI18n } from '@/locales/helpers.ts';
import { TextDirection } from '@/core/text.ts';
import { FontSize, FONT_SIZE_PREVIEW_CLASSNAME_PREFIX } from '@/core/font.ts';
import { getNumberValue } from '../common.ts';
import { isEnableAnimate } from '../settings.ts';
export interface Framework7Dom {
@@ -148,51 +147,6 @@ export function getElementBoundingRect(selector: string): DOMRect | null {
return el.getBoundingClientRect();
}
export function scrollToSelectedItem(parentEl: Framework7Dom, containerSelector: string, selectedItemSelector: string, hasBottomToolbar?: boolean): void {
if (!parentEl || !parentEl.length) {
return;
}
const container = parentEl.find(containerSelector);
const selectedItem = parentEl.find(selectedItemSelector);
if (!container.length || !selectedItem.length) {
return;
}
const containerPaddingTop = getNumberValue(container.css('padding-top'), 0) / 2;
let targetPos = selectedItem.offset().top - container.offset().top - containerPaddingTop
- (container.outerHeight() - selectedItem.outerHeight()) / 2;
if (selectedItem.length > 1) {
const firstSelectedItem = f7.$(selectedItem[0]);
const lastSelectedItem = f7.$(selectedItem[selectedItem.length - 1]);
const firstSelectedItemInTop = firstSelectedItem.offset().top - container.offset().top - containerPaddingTop;
const lastSelectedItemInTop = lastSelectedItem.offset().top - container.offset().top - containerPaddingTop;
const lastSelectedItemInBottom = lastSelectedItem.offset().top - container.offset().top - containerPaddingTop
- (container.outerHeight() - firstSelectedItem.outerHeight());
targetPos = (firstSelectedItemInTop + lastSelectedItemInBottom) / 2;
if (lastSelectedItemInTop - firstSelectedItemInTop > container.outerHeight()) {
targetPos = firstSelectedItemInTop;
}
}
if (targetPos <= 0) {
return;
}
if (hasBottomToolbar) {
const toolbarHeight = parentEl.find('.toolbar.toolbar-bottom').outerHeight() || 0;
targetPos += toolbarHeight / 2;
}
container.scrollTop(targetPos);
}
export function scrollSheetToTop(sheetElement: HTMLElement | undefined, windowNormalInnerHeight: number): void {
if (!sheetElement) {
return;