1

我正在使用 Fullcalendar v4 并试图将浏览器前进/后退按钮连接到 FC 导航中。prev单击月份显示中的 FC 按钮后尝试使用浏览器按钮时出现问题。

我尝试创建一个小提琴并使用 codepen,但我认为这些网站使用的包装器会干扰浏览器按钮事件的某些方面。我在 这里设置了一个修剪过的样本

预期行为的一个示例是:

  • 访问上面的链接;单击Go to calendar链接(为了测试,我需要一个启动页面来测试来自真实日历“主页”页面的后退按钮操作)。

  • 查看日历工具栏的顶部右侧,然后依次单击月份和日期按钮。

  • 使用浏览器后退/前进按钮在视图之间移动。

有缺陷的行为示例:

  • 转到月视图。查看日历工具栏的左上角,然后单击“<”prev按钮。这会将显示向后移动一个月。

  • 尝试使用浏览器返回按钮返回到最初的月份视图,但没有任何反应。

我正在通过 管理日历状态window.history.state。在我看来,当第一次访问页面时,它window.history.state是空的。在 Fullcalendar 初始化和渲染之后发生的第一件事就是渲染和datesRender调用初始视图。

我检查是否window.history.state为空,如果是,我使用window.history.replaceState设置默认视图状态。然后我要么使用,replaceState要么pushState添加或更新状态信息。

    'datesRender': function (info) {
        if (window.history.state === null) {
            //
            // seems like when a page is first visited the history
            // for that page has a null state.  Add a default state.
            const tempState = {
                'view': info.view.type,
                'range': {
                    'start': moment(info.view.activeStart)
                        .local().format(dateFormatHuman),
                    'end': moment(info.view.activeEnd)
                        .local().format(dateFormatHuman)
                },
                'url': window.location.href,
                'comment': "INIT"
            };

            window.history.replaceState(
                tempState,
                "INIT",
                window.location.href
            );
        } else {
            //
            // if state.comment = POP then we are here after a
            // BACK button press.  Change the comment to "dateRender".
            if (window.history.state.comment === "POP") {
                const tempState = window.history.state;
                tempState.comment = "datesRender";

                window.history.replaceState(
                    tempState,
                    "From pop",
                    window.location.href
                );
            } else {
                //
                // there is current state and we need to change views.
                // add new state for the new view
                const state = {
                    'view': info.view.type,
                    'range': {
                        'start': moment(info.view.activeStart)
                            .local().format(dateFormatHuman),
                        'end': moment(info.view.activeEnd)
                            .local().format(dateFormatHuman)
                    },
                    'url': window.location.href,
                    'comment': "datesRender"
                };

                window.history.pushState(
                    state,
                    "datesRender",
                    window.location.href
                );
            }
        }
    },

当按下浏览器的前进/后退按钮时,将window.onpopstate触发该事件。当处理程序运行时,“当前”window.history.state是浏览器按钮 POP 之后的状态。我更新状态注释以将其标记为浏览器按钮事件,然后调用 FullcalendarchangeView方法来更新视图。

    function handleStatePopEvent(event) {
        try {
            const tempState = window.history.state;
            tempState.comment = "POP";

            window.history.replaceState(
                tempState,
                tempState.comment,
                tempState.url
            );

            calendar.changeView(
                window.history.state.view,
                window.history.state.range
            );
        } catch (e) {
            throw `handleStatePopEvent: ${e.message}`;
        }
    }

问题似乎是在 Fullcalendarprev按钮单击后,FC 内部状态发生了一些变化——尽管我无法证明这一点。中的window.history.state已正确更改datesRender。当点击浏览器后退按钮时,window.onpopstate会触发事件并且视图和日期范围正确,可以返回到上个月的视图,但changeView调用不会呈现任何内容。

changeView在这种情况下,我已经使用了浏览器的开发者工具调试器,并且一路走来。没有什么戏剧性的事情发生在我身上,只是在某个时候有一个标志似乎在说“我需要渲染任何东西吗?” 设置为false

难道我做错了什么?

4

0 回答 0