yohei0125 4 лет назад
Родитель
Сommit
b6dc0498c0

+ 20 - 5
packages/app/src/client/util/smooth-scroll.ts

@@ -1,22 +1,37 @@
 const WIKI_HEADER_LINK = 120;
 
-export const smoothScrollIntoView = (element: HTMLElement, offsetTop = 0, scrollElement: HTMLElement | Window = window, useSlimScroll = false): void => {
+export const smoothScrollIntoView = (element: HTMLElement, offsetTop = 0, scrollElement: HTMLElement | Window = window): void => {
   const targetElement = element || window.document.body;
 
   // get the distance to the target element top
   const rectTop = targetElement.getBoundingClientRect().top;
 
   const top = window.pageYOffset + rectTop - offsetTop;
-  if (useSlimScroll) {
-    (<any>$(scrollElement)).slimScroll({ scrollTo: rectTop });
-    return;
-  }
   scrollElement.scrollTo({
     top,
     behavior: 'smooth',
   });
 };
 
+/**
+ * scroll to the top of the target element
+ * or
+ * scroll the target element to the center of the view
+ * by using JQuery slimScroll: http://rocha.la/jQuery-slimScroll
+ */
+export const jQuerySlimScrollIntoView = (scrollableElement: HTMLElement, scrollTargetElement: HTMLElement, moveToCenter = false): void => {
+  const windowCenter = window.innerHeight / 2;
+  const targetTop = scrollTargetElement.getBoundingClientRect().top;
+
+  let scrollTo;
+  scrollTo = targetTop;
+  if (moveToCenter) {
+    if (targetTop <= windowCenter) return;
+    scrollTo = targetTop - windowCenter;
+  }
+  (<any>$(scrollableElement)).slimScroll({ scrollTo });
+};
+
 export type SmoothScrollEventCallback = (elem: HTMLElement) => void;
 
 export const addSmoothScrollEvent = (elements: HTMLAnchorElement[], callback?: SmoothScrollEventCallback): void => {

+ 7 - 10
packages/app/src/components/Sidebar/PageTree/ItemsTree.tsx

@@ -10,7 +10,7 @@ import { toastError, toastSuccess } from '~/client/util/apiNotification';
 import {
   IPageForPageDuplicateModal, usePageDuplicateModal, usePageDeleteModal,
 } from '~/stores/modal';
-import { smoothScrollIntoView } from '~/client/util/smooth-scroll';
+import { jQuerySlimScrollIntoView } from '~/client/util/smooth-scroll';
 
 import { useIsEnabledAttachTitleHeader } from '~/stores/context';
 import { useFullTextSearchTermManager } from '~/stores/search';
@@ -95,14 +95,11 @@ const renderByInitialNode = (
   );
 };
 
-const SCROLL_OFFSET_TOP = window.innerHeight / 2;
-
-const scrollTargetItem = () => {
+const scrollPageTree = () => {
   const scrollElement = document.getElementById('grw-sidebar-contents-scroll-target');
   const target = document.getElementById('grw-pagetree-is-target');
   if (scrollElement != null && target != null) {
-    const useSlimScroll = true;
-    smoothScrollIntoView(target, SCROLL_OFFSET_TOP, scrollElement, useSlimScroll);
+    jQuerySlimScrollIntoView(scrollElement, target, true);
   }
 };
 // --- end ---
@@ -136,17 +133,17 @@ const ItemsTree: FC<ItemsTreeProps> = (props: ItemsTreeProps) => {
   const [isScrolled, setIsScrolled] = useState(false);
   const [isRenderedCompletely, setIsRenderedCompletely] = useState(false);
 
-  const scrollItem = () => {
+  const scrollToTargetItem = () => {
     if (!isScrolled) {
-      scrollTargetItem();
+      scrollPageTree();
       setIsScrolled(true);
     }
   };
 
   useEffect(() => {
-    document.addEventListener('scrollPageTree', scrollItem);
+    document.addEventListener('scrollPageTree', scrollToTargetItem);
     return () => {
-      document.removeEventListener('scrollPageTree', scrollItem);
+      document.removeEventListener('scrollPageTree', scrollToTargetItem);
     };
   });