mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-01-06 00:38:49 +01:00
🎨 页面内容变化时保持 av 头尾
This commit is contained in:
parent
8641d0c6b2
commit
efd0828b9d
7 changed files with 79 additions and 63 deletions
|
|
@ -27,6 +27,7 @@ import {resize} from "../protyle/util/resize";
|
|||
import {Search} from "../search";
|
||||
import {App} from "../index";
|
||||
import {newCardModel} from "../card/newCardTab";
|
||||
import {preventScroll} from "../protyle/scroll/preventScroll";
|
||||
|
||||
export const checkFold = (id: string, cb: (zoomIn: boolean, action: string[]) => void) => {
|
||||
if (!id) {
|
||||
|
|
@ -369,6 +370,8 @@ const switchEditor = (editor: Editor, options: IOpenFileOptions, allModels: IMod
|
|||
updateBacklinkGraph(allModels, editor.editor.protyle);
|
||||
});
|
||||
} else {
|
||||
// 点击大纲产生滚动时会动态加载内容,最终导致定位不准确
|
||||
preventScroll(editor.editor.protyle);
|
||||
if (options.action?.includes(Constants.CB_GET_HL)) {
|
||||
highlightById(editor.editor.protyle, options.id, true);
|
||||
} else if (options.action?.includes(Constants.CB_GET_FOCUS)) {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,11 @@ export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => {
|
|||
if (protyle.scroll && !protyle.scroll.element.classList.contains("fn__none")) {
|
||||
clearTimeout(getIndexTimeout);
|
||||
getIndexTimeout = window.setTimeout(() => {
|
||||
const targetElement = document.elementFromPoint(elementRect.left + elementRect.width / 2, elementRect.top + 10);
|
||||
let targetElement = document.elementFromPoint(elementRect.left + elementRect.width / 2, elementRect.top + 10);
|
||||
if (targetElement.classList.contains("protyle-wysiwyg")) {
|
||||
// 恰好定位到块的中间时
|
||||
targetElement = document.elementFromPoint(elementRect.left + elementRect.width / 2, elementRect.top + 20);
|
||||
}
|
||||
const blockElement = hasClosestBlock(targetElement);
|
||||
if (!blockElement) {
|
||||
if ((protyle.wysiwyg.element.firstElementChild.getAttribute("data-eof") === "1" ||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ export const destroy = (protyle: IProtyle) => {
|
|||
return;
|
||||
}
|
||||
hideElements(["util"], protyle);
|
||||
protyle.observer?.disconnect();
|
||||
protyle.observerLoad?.disconnect();
|
||||
protyle.element.classList.remove("protyle");
|
||||
protyle.element.removeAttribute("style");
|
||||
if (protyle.wysiwyg) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import {fetchPost} from "../../util/fetch";
|
|||
import {processRender} from "./processCode";
|
||||
import {highlightRender} from "../render/highlightRender";
|
||||
import {blockRender} from "../render/blockRender";
|
||||
import {highlightById} from "../../util/highlightById";
|
||||
import {bgFade} from "../../util/highlightById";
|
||||
/// #if !MOBILE
|
||||
import {pushBack} from "../../util/backForward";
|
||||
/// #endif
|
||||
|
|
@ -185,54 +185,21 @@ const setHTML = (options: {
|
|||
if (protyle.options.render.scroll) {
|
||||
protyle.scroll.update(protyle);
|
||||
}
|
||||
if (options.scrollAttr) {
|
||||
protyle.contentElement.scrollTop = options.scrollAttr.scrollTop;
|
||||
if (options.action.includes(Constants.CB_GET_HL)) {
|
||||
highlightById(protyle, options.scrollAttr.focusId, true);
|
||||
} else if (options.action.includes(Constants.CB_GET_FOCUS)) {
|
||||
if (options.scrollAttr.focusId) {
|
||||
const range = focusByOffset(protyle.wysiwyg.element.querySelector(`[data-node-id="${options.scrollAttr.focusId}"]`), options.scrollAttr.focusStart, options.scrollAttr.focusEnd);
|
||||
/// #if !MOBILE
|
||||
if (!options.action.includes(Constants.CB_GET_UNUNDO)) {
|
||||
pushBack(protyle, range || undefined);
|
||||
}
|
||||
/// #endif
|
||||
} else {
|
||||
focusElementById(protyle, options.action);
|
||||
}
|
||||
if (options.scrollAttr && !protyle.scroll.element.classList.contains("fn__none")) {
|
||||
// 使用动态滚动条定位到最后一个块,重启后无法触发滚动事件,需要再次更新 index
|
||||
protyle.scroll.updateIndex(protyle, options.scrollAttr.startId);
|
||||
// https://github.com/siyuan-note/siyuan/issues/8224
|
||||
const contentRect = protyle.contentElement.getBoundingClientRect();
|
||||
if (protyle.wysiwyg.element.clientHeight - parseInt(protyle.wysiwyg.element.style.paddingBottom) < protyle.contentElement.clientHeight &&
|
||||
protyle.wysiwyg.element.lastElementChild.getBoundingClientRect().bottom < contentRect.bottom &&
|
||||
protyle.wysiwyg.element.firstElementChild.getBoundingClientRect().top > contentRect.top) {
|
||||
showMessage(window.siyuan.languages.scrollGetMore);
|
||||
}
|
||||
if (!protyle.scroll.element.classList.contains("fn__none")) {
|
||||
// 使用动态滚动条定位到最后一个块,重启后无法触发滚动事件,需要再次更新 index
|
||||
protyle.scroll.updateIndex(protyle, options.scrollAttr.startId);
|
||||
// https://github.com/siyuan-note/siyuan/issues/8224
|
||||
const contentRect = protyle.contentElement.getBoundingClientRect();
|
||||
if (protyle.wysiwyg.element.clientHeight - parseInt(protyle.wysiwyg.element.style.paddingBottom) < protyle.contentElement.clientHeight &&
|
||||
protyle.wysiwyg.element.lastElementChild.getBoundingClientRect().bottom < contentRect.bottom &&
|
||||
protyle.wysiwyg.element.firstElementChild.getBoundingClientRect().top > contentRect.top) {
|
||||
showMessage(window.siyuan.languages.scrollGetMore);
|
||||
}
|
||||
}
|
||||
} else if (options.action.includes(Constants.CB_GET_HL)) {
|
||||
preventScroll(protyle); // 搜索页签滚动会导致再次请求
|
||||
const hlElement = highlightById(protyle, protyle.block.id, true);
|
||||
/// #if !MOBILE
|
||||
if (hlElement && !options.action.includes(Constants.CB_GET_UNUNDO)) {
|
||||
pushBack(protyle, undefined, hlElement);
|
||||
}
|
||||
/// #endif
|
||||
} else if (options.action.includes(Constants.CB_GET_FOCUS)) {
|
||||
focusElementById(protyle, options.action);
|
||||
} else if (options.action.includes(Constants.CB_GET_FOCUSFIRST)) {
|
||||
// settimeout 时间需短一点,否则定位后快速滚动无效
|
||||
const headerHeight = protyle.wysiwyg.element.offsetTop - 16;
|
||||
preventScroll(protyle, headerHeight, 256);
|
||||
protyle.contentElement.scrollTop = headerHeight;
|
||||
focusBlock(protyle.wysiwyg.element.firstElementChild);
|
||||
/// #if !MOBILE
|
||||
if (!options.action.includes(Constants.CB_GET_UNUNDO)) {
|
||||
pushBack(protyle, undefined, protyle.wysiwyg.element.firstElementChild);
|
||||
}
|
||||
/// #endif
|
||||
}
|
||||
if (options.isSyncing) {
|
||||
disabledForeverProtyle(protyle);
|
||||
|
|
@ -243,6 +210,9 @@ const setHTML = (options: {
|
|||
protyle.element.removeAttribute("disabled-forever");
|
||||
setReadonlyByConfig(protyle);
|
||||
}
|
||||
|
||||
focusElementById(protyle, options.action, options.scrollAttr);
|
||||
|
||||
if (options.action.includes(Constants.CB_GET_SETID)) {
|
||||
// 点击大纲后,如果需要动态加载,在定位后,需要重置 block.id https://github.com/siyuan-note/siyuan/issues/4487
|
||||
protyle.block.id = protyle.block.rootID;
|
||||
|
|
@ -269,7 +239,6 @@ const setHTML = (options: {
|
|||
onGet({data: getResponse, protyle, action: [Constants.CB_GET_APPEND, Constants.CB_GET_UNCHANGEID]});
|
||||
});
|
||||
}
|
||||
|
||||
if (options.action.includes(Constants.CB_GET_APPEND) || options.action.includes(Constants.CB_GET_BEFORE)) {
|
||||
protyle.app.plugins.forEach(item => {
|
||||
item.eventBus.emit("loaded-protyle-dynamic", {
|
||||
|
|
@ -279,6 +248,7 @@ const setHTML = (options: {
|
|||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (protyle.options.render.breadcrumb) {
|
||||
protyle.breadcrumb.toggleExit(!options.action.includes(Constants.CB_GET_ALL));
|
||||
protyle.breadcrumb.render(protyle);
|
||||
|
|
@ -387,37 +357,62 @@ export const enableProtyle = (protyle: IProtyle) => {
|
|||
hideTooltip();
|
||||
};
|
||||
|
||||
const focusElementById = (protyle: IProtyle, action: string[]) => {
|
||||
const focusElementById = (protyle: IProtyle, action: string[], scrollAttr?: IScrollAttr) => {
|
||||
let focusElement: Element;
|
||||
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-node-id="${protyle.block.id}"]`)).find((item: HTMLElement) => {
|
||||
if (!hasClosestByAttribute(item, "data-type", "block-render", true)) {
|
||||
focusElement = item;
|
||||
return true;
|
||||
let range: Range;
|
||||
if (scrollAttr && scrollAttr.focusId) {
|
||||
focusElement = protyle.wysiwyg.element.querySelector(`[data-node-id="${scrollAttr.focusId}"]`)
|
||||
if (action.includes(Constants.CB_GET_FOCUS)) {
|
||||
range = focusByOffset(focusElement, scrollAttr.focusStart, scrollAttr.focusEnd) as Range;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-node-id="${protyle.block.id}"]`)).find((item: HTMLElement) => {
|
||||
if (!hasClosestByAttribute(item, "data-type", "block-render", true)) {
|
||||
focusElement = item;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (protyle.block.mode === 4) {
|
||||
preventScroll(protyle);
|
||||
focusElement = protyle.wysiwyg.element.lastElementChild;
|
||||
} else if (!focusElement || action.includes(Constants.CB_GET_FOCUSFIRST)) {
|
||||
focusElement = protyle.wysiwyg.element.firstElementChild
|
||||
}
|
||||
if (focusElement && !protyle.wysiwyg.element.firstElementChild.isSameNode(focusElement)) {
|
||||
if (action.includes(Constants.CB_GET_HL)) {
|
||||
preventScroll(protyle); // 搜索页签滚动会导致再次请求
|
||||
bgFade(focusElement);
|
||||
}
|
||||
if (action.includes(Constants.CB_GET_FOCUS) || action.includes(Constants.CB_GET_FOCUSFIRST)) {
|
||||
focusBlock(focusElement);
|
||||
/// #if !MOBILE
|
||||
if (!action.includes(Constants.CB_GET_UNUNDO)) {
|
||||
pushBack(protyle, undefined, focusElement);
|
||||
pushBack(protyle, range, focusElement);
|
||||
}
|
||||
/// #endif
|
||||
}
|
||||
if (action.includes(Constants.CB_GET_FOCUS) || action.includes(Constants.CB_GET_HL) || action.includes(Constants.CB_GET_FOCUSFIRST)) {
|
||||
focusElement.scrollIntoView();
|
||||
// 减少抖动 https://ld246.com/article/1654263598088
|
||||
setTimeout(() => {
|
||||
} else if (scrollAttr && scrollAttr.scrollTop) {
|
||||
protyle.contentElement.scrollTop = scrollAttr.scrollTop;
|
||||
}
|
||||
// 加强定位
|
||||
protyle.observerLoad = new ResizeObserver((entries) => {
|
||||
if (action.includes(Constants.CB_GET_FOCUS) || action.includes(Constants.CB_GET_HL) || action.includes(Constants.CB_GET_FOCUSFIRST)) {
|
||||
focusElement.scrollIntoView();
|
||||
}, Constants.TIMEOUT_LOAD);
|
||||
} else {
|
||||
focusBlock(protyle.wysiwyg.element.firstElementChild);
|
||||
/// #if !MOBILE
|
||||
if (!action.includes(Constants.CB_GET_UNUNDO)) {
|
||||
pushBack(protyle, undefined, protyle.wysiwyg.element.firstElementChild);
|
||||
} else if (scrollAttr && scrollAttr.scrollTop) {
|
||||
protyle.contentElement.scrollTop = scrollAttr.scrollTop;
|
||||
}
|
||||
/// #endif
|
||||
});
|
||||
protyle.observerLoad.observe(protyle.wysiwyg.element);
|
||||
protyle.observer.unobserve(protyle.wysiwyg.element);
|
||||
setTimeout(() => {
|
||||
protyle.observerLoad.disconnect();
|
||||
protyle.observer.observe(protyle.wysiwyg.element);
|
||||
}, 1000 * 16);
|
||||
|
||||
if (focusElement.isSameNode(protyle.wysiwyg.element.firstElementChild)) {
|
||||
protyle.observerLoad.disconnect();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1050,6 +1050,16 @@ export class WYSIWYG {
|
|||
}
|
||||
|
||||
private bindEvent(protyle: IProtyle) {
|
||||
// 删除块时,av 头尾需重新计算位置
|
||||
protyle.observer = new ResizeObserver((entries) => {
|
||||
const contentRect = protyle.contentElement.getBoundingClientRect();
|
||||
protyle.wysiwyg.element.querySelectorAll(".av").forEach((item: HTMLElement) => {
|
||||
if (item.querySelector(".av__title")) {
|
||||
stickyRow(item, contentRect, "all");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.element.addEventListener("focusout", () => {
|
||||
if (getSelection().rangeCount === 0) {
|
||||
return;
|
||||
|
|
|
|||
2
app/src/types/protyle.d.ts
vendored
2
app/src/types/protyle.d.ts
vendored
|
|
@ -431,6 +431,8 @@ interface IOptions {
|
|||
|
||||
interface IProtyle {
|
||||
getInstance: () => import("../protyle").Protyle,
|
||||
observerLoad?: ResizeObserver,
|
||||
observer?: ResizeObserver,
|
||||
app: import("../index").App,
|
||||
transactionTime: number,
|
||||
id: string,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import {hasClosestBlock, hasClosestByAttribute} from "../protyle/util/hasClosest";
|
||||
import {getEditorRange, getSelectionPosition} from "../protyle/util/selection";
|
||||
|
||||
const bgFade = (element: HTMLElement) => {
|
||||
export const bgFade = (element: Element) => {
|
||||
element.classList.add("protyle-wysiwyg--hl");
|
||||
setTimeout(function () {
|
||||
element.classList.remove("protyle-wysiwyg--hl");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue