通过 Chrome 扩展程序和 creating/canceling 新日历事件附加 DIV 后防止在 Google 日历中滚动

Prevent scroll in Google Calendar after appending DIV via Chrome Extension and creating/canceling new calendar event

我正在为 Google 日历编写一个 Chrome 扩展,它在 Google 日历的 header 部分下添加了一个 div。

为简单起见,这实际上是 Chrome 扩展内容脚本中发生的事情,您可以将此代码粘贴到 calendar.google.com 的控制台中以检查发生了什么:

let header = document.querySelector("header[role='banner']");
let appContainer = document.createElement('DIV');
appContainer.style.height = '200px';
appContainer.style.backgroundColor = 'red';
header.parentNode.insertBefore(appContainer, header.nextSibling);

我遇到的问题是,在日历视图中创建或取消创建事件后,window 向上滚动并且现在不显示页面 header。

有人知道如何在日历视图中创建或取消事件后保持页面稳定,并保持 div 我通过 Chrome 扩展内容脚本追加吗?

编辑:以下是事件 creation/cancel 和之后的截图:

通常,如果没有您的扩展名,header.parentElement 包含两个计入 header.parentElement.clientHeight 的元素:header,以及包含日历本身的 div

(它还包含一些浮动按钮和隐藏的 div 和东西,但这些在这里并不重要。)

这两个元素 headercalendar 具有专门计算的高度,因此 header.clientHeight + calendar.clientHeight 等于页面的高度。在正常情况下,这是完美的,因为这意味着不需要滚动。

但是,在您的情况下,您添加了一个额外的 div,这会将 calendar 向下推:

通常您可以自己向下滚动以查看 calendar 的底部,但由于滚动条被禁用,您不能。但是,当您创建一个事件时,您的浏览器会发现您正在尝试访问 calendar 的底部,因此它会自动向下滚动以显示 calendar 的底部。由于整个页面现在向下滚动以使页面底部可见,因此页面顶部现在不可见,从而导致您描述的行为。

解决此问题的方法是调整 calendar 的高度,使 header.clientHeight + appContainer.clientHeight + calendar.clientHeight 等于页面高度,而不仅仅是 header.clientHeight + calendar.clientHeight。这可以通过添加以下代码来完成:

//Getting calendar can be a bit tricky since it's just one dive among others.
//While it does have a CSS class, I don't know how that name is determined or if it will change in future versions of Google Calendar, so it's best not to use it.
//What I do here instead is that I select the first child of header.parentElement that has parts outside of the page frame
const getCalendar = () => [...header.parentElement.querySelectorAll(":scope > div")].find(d => {
    let boundingRect = d.getBoundingClientRect();
    return boundingRect.y + boundingRect.height > document.body.clientHeight;
});
let calendar = getCalendar();

//This function adjusts the height of calendar
const adjustHeight = () => {
    calendar = calendar || getCalendar();    //calendar may be null in the beginning before all the elements were set, so if it's null try to select it again
    if(calendar != null){
        calendar.style.height = (calendar.parentElement.clientHeight - header.clientHeight - appContainer.clientHeight) + "px";    //Adjust the height of calendar
    }
};

window.addEventListener("resize", adjustHeight);    //Adjust the height whenever the window gets resized
window.addEventListener("load", adjustHeight);    //Adjust the height on page load