浏览代码

:art: https://github.com/siyuan-note/siyuan/issues/8224 改进重启滚动条定位和定位块无法加载问题

Vanessa 2 年之前
父节点
当前提交
adf5e3af96

+ 5 - 12
app/src/protyle/scroll/event.ts

@@ -39,22 +39,15 @@ export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => {
                 const targetElement = document.elementFromPoint(elementRect.left + elementRect.width / 2, elementRect.top + 10);
                 const targetElement = document.elementFromPoint(elementRect.left + elementRect.width / 2, elementRect.top + 10);
                 const blockElement = hasClosestBlock(targetElement);
                 const blockElement = hasClosestBlock(targetElement);
                 if (!blockElement) {
                 if (!blockElement) {
-                    if (hasClosestByClassName(targetElement, "protyle-background") ||
-                        hasClosestByClassName(targetElement, "protyle-title")) {
+                    if (protyle.wysiwyg.element.firstElementChild.getAttribute("data-eof") === "1" &&
+                        (hasClosestByClassName(targetElement, "protyle-background") || hasClosestByClassName(targetElement, "protyle-title"))) {
                         const inputElement = protyle.scroll.element.querySelector(".b3-slider") as HTMLInputElement;
                         const inputElement = protyle.scroll.element.querySelector(".b3-slider") as HTMLInputElement;
                         inputElement.value = "1";
                         inputElement.value = "1";
                         protyle.scroll.element.setAttribute("aria-label", `Blocks 1/${protyle.block.blockCount}`);
                         protyle.scroll.element.setAttribute("aria-label", `Blocks 1/${protyle.block.blockCount}`);
                     }
                     }
                     return;
                     return;
                 }
                 }
-                fetchPost("/api/block/getBlockIndex", {id: blockElement.getAttribute("data-node-id")}, (response) => {
-                    if (!response.data) {
-                        return;
-                    }
-                    const inputElement = protyle.scroll.element.querySelector(".b3-slider") as HTMLInputElement;
-                    inputElement.value = response.data;
-                    protyle.scroll.element.setAttribute("aria-label", `Blocks ${response.data}/${protyle.block.blockCount}`);
-                });
+                protyle.scroll.updateIndex(protyle, blockElement.getAttribute("data-node-id"));
             }, Constants.TIMEOUT_LOAD);
             }, Constants.TIMEOUT_LOAD);
         }
         }
         if (protyle.wysiwyg.element.getAttribute("data-top") || protyle.block.showAll ||
         if (protyle.wysiwyg.element.getAttribute("data-top") || protyle.block.showAll ||
@@ -65,7 +58,7 @@ export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => {
         if (protyle.scroll.lastScrollTop - element.scrollTop > 0) {
         if (protyle.scroll.lastScrollTop - element.scrollTop > 0) {
             // up
             // up
             if (element.scrollTop < element.clientHeight &&
             if (element.scrollTop < element.clientHeight &&
-                protyle.wysiwyg.element.firstElementChild.getAttribute("data-eof") !== "true") {
+                protyle.wysiwyg.element.firstElementChild.getAttribute("data-eof") !== "1") {
                 // 禁用滚动时会产生抖动 https://ld246.com/article/1666717094418
                 // 禁用滚动时会产生抖动 https://ld246.com/article/1666717094418
                 protyle.contentElement.style.width = (protyle.contentElement.clientWidth) + "px";
                 protyle.contentElement.style.width = (protyle.contentElement.clientWidth) + "px";
                 protyle.contentElement.style.overflow = "hidden";
                 protyle.contentElement.style.overflow = "hidden";
@@ -83,7 +76,7 @@ export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => {
             }
             }
         } else if ((element.scrollTop > element.scrollHeight - element.clientHeight * 1.8) &&
         } else if ((element.scrollTop > element.scrollHeight - element.clientHeight * 1.8) &&
             protyle.wysiwyg.element.lastElementChild &&
             protyle.wysiwyg.element.lastElementChild &&
-            protyle.wysiwyg.element.lastElementChild.getAttribute("data-eof") !== "true") {
+            protyle.wysiwyg.element.lastElementChild.getAttribute("data-eof") !== "2") {
             protyle.wysiwyg.element.setAttribute("data-top", element.scrollTop.toString());
             protyle.wysiwyg.element.setAttribute("data-top", element.scrollTop.toString());
             fetchPost("/api/filetree/getDoc", {
             fetchPost("/api/filetree/getDoc", {
                 id: protyle.wysiwyg.element.lastElementChild.getAttribute("data-node-id"),
                 id: protyle.wysiwyg.element.lastElementChild.getAttribute("data-node-id"),

+ 11 - 0
app/src/protyle/scroll/index.ts

@@ -74,6 +74,17 @@ export class Scroll {
         });
         });
     }
     }
 
 
+    public updateIndex(protyle: IProtyle, id: string) {
+        fetchPost("/api/block/getBlockIndex", {id}, (response) => {
+            if (!response.data) {
+                return;
+            }
+            const inputElement = protyle.scroll.element.querySelector(".b3-slider") as HTMLInputElement;
+            inputElement.value = response.data;
+            protyle.scroll.element.setAttribute("aria-label", `Blocks ${response.data}/${protyle.block.blockCount}`);
+        });
+    }
+
     public update(protyle: IProtyle) {
     public update(protyle: IProtyle) {
         if (typeof protyle.block.blockCount === "number") {
         if (typeof protyle.block.blockCount === "number") {
             this.inputElement.setAttribute("max", protyle.block.blockCount.toString());
             this.inputElement.setAttribute("max", protyle.block.blockCount.toString());

+ 2 - 0
app/src/protyle/scroll/saveScroll.ts

@@ -100,6 +100,8 @@ export const restoreScroll = (protyle: IProtyle, scrollAttr: IScrollAttr) => {
                 pushBack(protyle, range || undefined);
                 pushBack(protyle, range || undefined);
                 /// #endif
                 /// #endif
             }
             }
+            // 使用动态滚动条定位到最后一个块,重启后无法触发滚动事件,需要再次更新 index
+            protyle.scroll.updateIndex(protyle, scrollAttr.startId);
         });
         });
     } else if (scrollAttr.scrollTop) {
     } else if (scrollAttr.scrollTop) {
         protyle.contentElement.scrollTop = scrollAttr.scrollTop;
         protyle.contentElement.scrollTop = scrollAttr.scrollTop;

+ 3 - 3
app/src/protyle/util/onGet.ts

@@ -40,9 +40,9 @@ export const onGet = (data: IWebSocketData, protyle: IProtyle, action: string[]
 
 
     if (data.data.eof) {
     if (data.data.eof) {
         if (action.includes(Constants.CB_GET_BEFORE)) {
         if (action.includes(Constants.CB_GET_BEFORE)) {
-            protyle.wysiwyg.element.firstElementChild.setAttribute("data-eof", "true");
+            protyle.wysiwyg.element.firstElementChild.setAttribute("data-eof", "1");
         } else {
         } else {
-            protyle.wysiwyg.element.lastElementChild.setAttribute("data-eof", "true");
+            protyle.wysiwyg.element.lastElementChild.setAttribute("data-eof", "2");
         }
         }
         if (data.data.mode !== 4) {
         if (data.data.mode !== 4) {
             return;
             return;
@@ -274,7 +274,7 @@ const setHTML = (options: {
     }
     }
     // 屏幕太高的页签 https://github.com/siyuan-note/siyuan/issues/5018
     // 屏幕太高的页签 https://github.com/siyuan-note/siyuan/issues/5018
     if (!protyle.scroll.element.classList.contains("fn__none") &&
     if (!protyle.scroll.element.classList.contains("fn__none") &&
-        protyle.wysiwyg.element.lastElementChild.getAttribute("data-eof") !== "true" &&
+        protyle.wysiwyg.element.lastElementChild.getAttribute("data-eof") !== "2" &&
         protyle.contentElement.scrollHeight > 0 && // 没有激活的页签 https://github.com/siyuan-note/siyuan/issues/5255
         protyle.contentElement.scrollHeight > 0 && // 没有激活的页签 https://github.com/siyuan-note/siyuan/issues/5255
         !options.action.includes(Constants.CB_GET_FOCUSFIRST) && // 防止 eof 为true https://github.com/siyuan-note/siyuan/issues/5291
         !options.action.includes(Constants.CB_GET_FOCUSFIRST) && // 防止 eof 为true https://github.com/siyuan-note/siyuan/issues/5291
         protyle.contentElement.scrollHeight <= protyle.contentElement.clientHeight) {
         protyle.contentElement.scrollHeight <= protyle.contentElement.clientHeight) {

+ 2 - 2
app/src/protyle/wysiwyg/commonHotkey.ts

@@ -211,7 +211,7 @@ export const duplicateBlock = (nodeElements: Element[], protyle: IProtyle) => {
 
 
 export const goHome = (protyle: IProtyle) => {
 export const goHome = (protyle: IProtyle) => {
     if (protyle.wysiwyg.element.firstElementChild.getAttribute("data-node-index") === "0" ||
     if (protyle.wysiwyg.element.firstElementChild.getAttribute("data-node-index") === "0" ||
-        protyle.wysiwyg.element.firstElementChild.getAttribute("data-eof") === "true" ||
+        protyle.wysiwyg.element.firstElementChild.getAttribute("data-eof") === "1" ||
         protyle.options.backlinkData) {
         protyle.options.backlinkData) {
         focusBlock(protyle.wysiwyg.element.firstElementChild);
         focusBlock(protyle.wysiwyg.element.firstElementChild);
         protyle.contentElement.scrollTop = 0;
         protyle.contentElement.scrollTop = 0;
@@ -229,7 +229,7 @@ export const goHome = (protyle: IProtyle) => {
 
 
 export const goEnd = (protyle: IProtyle) => {
 export const goEnd = (protyle: IProtyle) => {
     if (!protyle.scroll.element.classList.contains("fn__none") &&
     if (!protyle.scroll.element.classList.contains("fn__none") &&
-        protyle.wysiwyg.element.lastElementChild.getAttribute("data-eof") !== "true") {
+        protyle.wysiwyg.element.lastElementChild.getAttribute("data-eof") !== "2") {
         fetchPost("/api/filetree/getDoc", {
         fetchPost("/api/filetree/getDoc", {
             id: protyle.block.rootID,
             id: protyle.block.rootID,
             mode: 4,
             mode: 4,

+ 1 - 1
app/src/protyle/wysiwyg/index.ts

@@ -1297,7 +1297,7 @@ export class WYSIWYG {
             if (!preventGetTopHTML &&
             if (!preventGetTopHTML &&
                 event.deltaY < 0 && !protyle.scroll.element.classList.contains("fn__none") &&
                 event.deltaY < 0 && !protyle.scroll.element.classList.contains("fn__none") &&
                 protyle.contentElement.clientHeight === protyle.contentElement.scrollHeight &&
                 protyle.contentElement.clientHeight === protyle.contentElement.scrollHeight &&
-                protyle.wysiwyg.element.firstElementChild.getAttribute("data-eof") !== "true") {
+                protyle.wysiwyg.element.firstElementChild.getAttribute("data-eof") !== "1") {
                 fetchPost("/api/filetree/getDoc", {
                 fetchPost("/api/filetree/getDoc", {
                     id: protyle.wysiwyg.element.firstElementChild.getAttribute("data-node-id"),
                     id: protyle.wysiwyg.element.firstElementChild.getAttribute("data-node-id"),
                     mode: 1,
                     mode: 1,

+ 2 - 2
app/src/protyle/wysiwyg/keydown.ts

@@ -215,7 +215,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
                                 previousElement = foldElement;
                                 previousElement = foldElement;
                             }
                             }
                         }
                         }
-                    } else if (protyle.title && (protyle.wysiwyg.element.firstElementChild.getAttribute("data-eof") === "true" ||
+                    } else if (protyle.title && (protyle.wysiwyg.element.firstElementChild.getAttribute("data-eof") === "1" ||
                         protyle.contentElement.scrollTop === 0)) {
                         protyle.contentElement.scrollTop === 0)) {
                         protyle.title.editElement.focus();
                         protyle.title.editElement.focus();
                     } else if (protyle.contentElement.scrollTop !== 0) {
                     } else if (protyle.contentElement.scrollTop !== 0) {
@@ -604,7 +604,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
                     (!firstEditElement && nodeElement.isSameNode(protyle.wysiwyg.element.firstElementChild))) {
                     (!firstEditElement && nodeElement.isSameNode(protyle.wysiwyg.element.firstElementChild))) {
                     // 不能用\n判断,否则文字过长折行将错误 https://github.com/siyuan-note/siyuan/issues/6156
                     // 不能用\n判断,否则文字过长折行将错误 https://github.com/siyuan-note/siyuan/issues/6156
                     if (getSelectionPosition(nodeElement, range).top - protyle.wysiwyg.element.getBoundingClientRect().top < 40) {
                     if (getSelectionPosition(nodeElement, range).top - protyle.wysiwyg.element.getBoundingClientRect().top < 40) {
-                        if (protyle.title && (protyle.wysiwyg.element.firstElementChild.getAttribute("data-eof") === "true" ||
+                        if (protyle.title && (protyle.wysiwyg.element.firstElementChild.getAttribute("data-eof") === "1" ||
                             protyle.contentElement.scrollTop === 0)) {
                             protyle.contentElement.scrollTop === 0)) {
                             protyle.title.editElement.focus();
                             protyle.title.editElement.focus();
                         } else {
                         } else {

+ 1 - 1
app/src/protyle/wysiwyg/transaction.ts

@@ -126,7 +126,7 @@ const promiseTransaction = () => {
                     return;
                     return;
                 }
                 }
                 // 折叠标题后未触发动态加载 https://github.com/siyuan-note/siyuan/issues/4168
                 // 折叠标题后未触发动态加载 https://github.com/siyuan-note/siyuan/issues/4168
-                if (protyle.wysiwyg.element.lastElementChild.getAttribute("data-eof") !== "true" &&
+                if (protyle.wysiwyg.element.lastElementChild.getAttribute("data-eof") !== "2" &&
                     !protyle.scroll.element.classList.contains("fn__none") &&
                     !protyle.scroll.element.classList.contains("fn__none") &&
                     protyle.contentElement.scrollHeight - protyle.contentElement.scrollTop < protyle.contentElement.clientHeight * 2    // https://github.com/siyuan-note/siyuan/issues/7785
                     protyle.contentElement.scrollHeight - protyle.contentElement.scrollTop < protyle.contentElement.clientHeight * 2    // https://github.com/siyuan-note/siyuan/issues/7785
                 ) {
                 ) {