Fullcalendar @fullcalendar/react 样式错乱丢失问题和导致页面卡顿崩溃问题

news2025/1/28 11:54:34

问题描述:

我使用 fullcalendar的react版本时,出现了一个诡异的问题,当我切换到 一个iframe页面时(整个页面是一个iframe嵌入的),再切换回来日历的样式丢失了!不仅丢失了样式还导致页面崩溃了,怎么点击都没反应!

神奇的是只要不切换到带有 iframe的页面就不会出现问题。这是大前提!
我的还使用了qiankun还可能是qiankun影响的。

    "@fullcalendar/core": "^6.1.11",
    "@fullcalendar/daygrid": "^6.1.11",
    "@fullcalendar/interaction": "^6.1.14",
    "@fullcalendar/react": "^6.1.11",
    "@fullcalendar/timegrid": "^6.1.11",

react使用Fullcalendar

正常的样式截图:
正常的样式截图
切换到一个iframe页面再切换回来的截图:
切换到一个iframe页面再切换回来的样式截图
页面崩溃了,控制台也没有报错,只是点击页面没反应,甚至会导致浏览器卡顿。

解决方案:

一开始我我把,页面卡顿崩溃 和样式错乱丢失问题当成两个问题解决。但到了最后实际上都是一个问题。

页面卡顿崩溃问题:

我一开始猜测,是传给日历组件的数据,出现了null 和undefined或者不符合要求的数据。

我检查了数据,给传入的数据都做了,兜底操作,没有的都给一个默认值。
但还是不行,后来,我把数据量从500多条,减到 10条,发现不崩溃了,但页面样式还是错乱的。

从上面的操作,我接着猜想是不是数据有问题,于是我检查了数据,检查很多遍没发现问题。所以先放下了,想先解决样式错乱丢失问题。

总结:如果出现 崩溃问题,先看报错再定位问题,检查传入的数据是不是正确且符合要求。卡顿 尝试减少数据量

样式错乱丢失问题:

因为我的场景很特殊,切换到一个带有 iframe标签的页面后,再次切换回来,样式就丢失了。我单独打开此页面,样式不会出现问题!

排查过程:

我审查元素发现,fullcalendar/react 的样式是通过style 上加一个data-fullcalendar自定义属性实现的:

<style data-fullcalendar=""></style>

在这里插入图片描述
正常是有:root和一系列 css变量和样式的:
在这里插入图片描述

去head标签里找到style上有data-fullcalendar 鼠标右键然后 delete Element会发现删除掉此标签后样式错乱了。
在这里插入图片描述
删除掉后:root和一系列 css变量样式没了:
在这里插入图片描述

所以我猜测,切换到iframe页面后,style data-fullcalendar 的标签没了,但神奇的是切换回来style data-fullcalendar 还在 但 :root和一系列css变量和样式都没了。所以我只要找到为什么 :root和一系列css变量消失了就能解决了。

我去源码里找到了代码:
node_modules@fullcalendar\core\internal-common.js

主要是通过 注入的方式注入了一些列变量和样式:
在这里插入图片描述
registerStylesRoot 、hydrateStylesRoot方法很关键:
registerStylesRoot 方法截图

function registerStylesRoot(rootNode) {
    // 获取根节点的样式元素
    let styleEl = styleEls.get(rootNode);
     console.log(styleEl,"styleEl")
    // 如果根节点没有样式元素或者样式元素没有连接到文档中
    if (!styleEl || !styleEl.isConnected) {
        // 在根节点中查找样式元素
        styleEl = rootNode.querySelector('style[data-fullcalendar]');
        // 如果根节点中没有样式元素
        if (!styleEl) {
            // 创建一个新的样式元素
            styleEl = document.createElement('style');
            // 设置样式元素的data-fullcalendar属性
            styleEl.setAttribute('data-fullcalendar', '');
            // 获取nonce值
            const nonce = getNonceValue();
            // 如果有nonce值,则设置样式元素的nonce属性
            if (nonce) {
                styleEl.nonce = nonce;
            }
            // 获取父元素
            const parentEl = rootNode === document ? document.head : rootNode;
            const insertBefore = rootNode === document
                ? parentEl.querySelector('script,link[rel=stylesheet],link[as=style],style')
                : parentEl.firstChild;
            parentEl.insertBefore(styleEl, insertBefore);
        }
        styleEls.set(rootNode, styleEl);
        hydrateStylesRoot(styleEl);
    }
}

所以我找到问题在这个方法里,因为!styleEl || !styleEl.isConnected 这个条件不满足所以没走hydrateStylesRoot 从而没走appendStylesTo。
在这里插入图片描述
appendStylesTo主要是给 style标签的sheet属属性赋值,sheet也能赋值样式跟直接写在 style标签里是一样的效果。

// 函数appendStylesTo用于将样式文本添加到样式元素中
function appendStylesTo(styleEl, styleText) {
    // 获取样式元素的sheet属性
    const { sheet } = styleEl;
    // 获取样式元素的cssRules属性的长度
    const ruleCnt = sheet.cssRules.length;
    // 将样式文本按照'}'进行分割
    styleText.split('}').forEach((styleStr, i) => {
        // 去除样式文本的首尾空格
        styleStr = styleStr.trim();
        // 如果样式文本不为空
        if (styleStr) {
            // 在样式元素的cssRules属性中插入样式文本
            sheet.insertRule(styleStr + '}', ruleCnt + i);
        }
    });
}

正常的 styleEl是unll或者undefined
切换到iframe后就变成了一个标签所以就导致不会走判断,从而导致样式丢失:
错误的

解决方案:

经过上面的排查,发现registerStylesRoot里!styleEl || !styleEl.isConnected 不满足条件导致的,所以我想直接 先注释掉这个判断,然后竟然不会出现问题了。

注释截图
这个判断,主要是做个优化,有标签的话就不重新注入样式了,但不知道为什么切换到 iframe页面后,切换回来,虽然标签还在,但是里面的sheet被清空了。

isConnected 是一个 DOM 属性,用于判断一个节点(元素)是否连接到文档的 DOM 树中。它是一个只读属性,返回一个布尔值:  
如果元素已连接到文档中,返回 true。
如果元素不在文档中,返回 false。

注意事项:
isConnected 属性在所有现代浏览器中都得到支持,并且可以用于所有类型的节点(如元素节点、文本节点等),但对元素节点的使用更为普遍。

在 JavaScript 中使用 isConnected 可以方便地检验元素是否仍然存在于页面中,从而进行更灵活的 DOM 操作和状态管理。
这种属性非常适合在复杂的交互中判断元素的存在状态。希望这个解释能帮助您理解 isConnected 属性的用法!如果您有其他问题,请随时询问!

主要是styleEl也就是 style标签不在页面中了,但我审查元素确实是在的,因为比较忙,也暂时没深究为什么这样。

比较神奇的是,注释掉这个判断后,连页面崩溃的问题都没有了。

总结:

我的场景很特殊,大部分人都不会遇到,我只是做个笔记,记录一下。

我的场景里即:切换到 一个iframe页面时,再切换回来日历的样式丢失了!不仅丢失了样式还导致页面崩溃了,怎么点击都没反应。

最终都是由于!styleEl || !styleEl.isConnected 这个条件不满足,导致的,所以解决方案就是 注释掉这个判断。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2283666.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

dm8在Linux环境安装精简步骤说明(2024年12月更新版dm8)

dm8在Linux环境安装详细步骤 - - 2025年1月之后dm8 环境介绍1 修改操作系统资源限制2 操作系统创建用户3 操作系统配置4 数据库安装5 初始化数据库6 实例参数优化7 登录数据库配置归档与备份8 配置审计9 创建用户10 屏蔽关键字与数据库兼容模式11 jdbc连接串配置12 更多达梦数据…

S4 HANA更改Tax base Amount的字段控制

本文主要介绍在S4 HANA OP中Tax base Amount的字段控制相关设置。具体请参照如下内容&#xff1a; 1. 更改Tax base Amount的字段控制 以上配置用于控制FB60/FB65/FB70/FB75/MIRO的页签“Tax”界面是否可以修改“Tax base Amount”&#xff0c; 如果勾选Change 表示可以修改T…

JVM堆空间

一、堆空间的核心概述 一个JVM实例只存在一个堆内存&#xff0c;堆也是Java内存管理的核心区域。Java堆区在JVM启动的时候即被创建&#xff0c;其空间大小也就确定了。是JVM管理的最大一块内存空间。 堆内存的大小是可以调节的。堆可以处于物理上不连续的内存空间中&#xff…

《深入解析:DOS检测的技术原理与方法》

DDOS入侵检测与防御 一、实现Linux下DDOS的入侵检测与防御 利用Python编程实现对wrk的泛洪攻击检测&#xff0c;并让程序触发调用Linux命令实现防御: 1、泛洪攻击的检测&#xff0c;可以考虑使用的命令&#xff0c;这些命令可以通过Python进行调用和分析 (1) netstat -ant …

PID如何调试,如何配置P,I,D值,如何适配pwm的定时器配置,如何给小车配电源

首先你要搞清楚PID公式原理 PID算法解析PID算法解析_pid滤波算法-CSDN博客 然后你要明白调试原理 首先要确定一个电源 电源决定了你后面调试时电机转动速度大小和pwm占空比的关系&#xff0c;电源电压越大那要转到同一速度所需的占空比越小&#xff0c;反之电源电压越小那要…

小马模拟器-第三方全街机游戏模拟器

链接&#xff1a;https://pan.xunlei.com/s/VOHSiB6st-f3RWlIK01MS2fUA1?pwd44v7# 1.小马模拟器是一款完全免费的游戏模拟器软件&#xff0c;支持街机&#xff08;FBA,MAME,PGM2&#xff09;,3DS,WII,NGC,DC,SS,DOS,MD,WSC,NDS,JAVA,PCE,FC,SFC,GBA,GBC,PSP,PS,N64等多种游戏…

微信小程序date picker的一些说明

微信小程序的picker是一个功能强大的组件&#xff0c;它可以是一个普通选择器&#xff0c;也可以是多项选择器&#xff0c;也可以是时间、日期、省市区选择器。 官方文档在这里 这里讲一下date picker的用法。 <view class"section"><view class"se…

【算法】递归型枚举与回溯剪枝初识

递归型枚举与回溯剪枝初识 1.枚举子集2.组合型枚举3.枚举排列4.全排列问题 什么是搜索&#xff1f;搜索&#xff0c;是一种枚举&#xff0c;通过穷举所有的情况来找到最优解&#xff0c;或者统计合法解的个数。因此&#xff0c;搜索有时候也叫作暴搜。搜索一般分为深度优先搜索…

rocketmq-product-send方法源码分析

先看有哪些send方法 首先说红圈的 有3个红圈。归类成3种发送方式。假设前提条件&#xff0c;发送的topic&#xff0c;有3个broker&#xff0c;每个broker总共4个write队列&#xff0c;总共有12个队列。 普通发送。负载均衡12个队列。指定超时时间指定MessageQueue,发送&#…

69.在 Vue 3 中使用 OpenLayers 拖拽实现放大区域的效果(DragPan)

引言 在现代 Web 开发中&#xff0c;地图功能已经成为许多应用的重要组成部分。OpenLayers 是一个功能强大的开源地图库&#xff0c;支持多种地图源和交互操作。Vue 3 是一个流行的前端框架&#xff0c;以其响应式数据和组件化开发著称。本文将介绍如何在 Vue 3 中集成 OpenLa…

77,【1】.[CISCN2019 华东南赛区]Web4

有句英文&#xff0c;看看什么意思 好像也可以不看 进入靶场 点击蓝色字体 我勒个豆&#xff0c;百度哇 所以重点应该在url上&#xff0c;属于任意文件读取类型 接下来该判断框架了 常见的web框架如下 一&#xff0c;Python 框架 1.Flask URL 示例 1&#xff1a;http://…

手撕B-树

一、概述 1.历史 B树&#xff08;B-Tree&#xff09;结构是一种高效存储和查询数据的方法&#xff0c;它的历史可以追溯到1970年代早期。B树的发明人Rudolf Bayer和Edward M. McCreight分别发表了一篇论文介绍了B树。这篇论文是1972年发表于《ACM Transactions on Database S…

一文简单回顾复习Java基础概念

还是和往常一样&#xff0c;我以提问的方式回顾复习&#xff0c;今天回顾下Java小白入门应该知道的一些基础知识 Java语言有哪些特点呢&#xff1f; Java语言的特点有&#xff1a; 面向对象&#xff0c;主要是封装、继承、多态&#xff1b;平台无关性&#xff0c;“一次编写…

GCC之编译(8)AR打包命令

GCC之(8)AR二进制打包命令 Author: Once Day Date: 2025年1月23日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章请查看专栏: Linux实践记录_Once-Day的博客-C…

2.1.3 第一个工程,点灯!

新建工程 点击菜单栏左上角&#xff0c;新建工程或者选择“文件”-“新建工程”&#xff0c;选择工程类型“标准工程”选择设备类型和编程语言&#xff0c;并指定工程文件名及保存路径&#xff0c;如下图所示&#xff1a; 选择工程类型为“标准工程” 选择主模块机型&#x…

图像处理算法研究的程序框架

目录 1 程序框架简介 2 C#图像读取、显示、保存模块 3 C动态库图像算法模块 4 C#调用C动态库 5 演示Demo 5.1 开发环境 5.2 功能介绍 5.3 下载地址 参考 1 程序框架简介 一个图像处理算法研究的常用程序逻辑框架&#xff0c;如下图所示 在该框架中&#xff0c;将图像处…

计算机工程:解锁未来科技之门!

计算机工程与应用是一个充满无限可能性的领域。随着科技的迅猛发展&#xff0c;计算机技术已经深深渗透到我们生活的方方面面&#xff0c;从医疗、金融到教育&#xff0c;无一不在彰显着计算机工程的巨大魅力和潜力。 在医疗行业&#xff0c;计算机技术的应用尤为突出。比如&a…

Linux初识——基本指令(2)

本文将继续从上篇末尾讲起&#xff0c;讲解我们剩下的基本指令 一、剩余的基本指令 1、mv mv指令是move&#xff08;移动&#xff09;的缩写&#xff0c;其功能为&#xff1a;1.剪切文件、目录。2.重命名 先演示下重命名&#xff0c;假设我想把当前目录下的di34改成dir5 那…

单片机-STM32 WIFI模块--ESP8266 (十二)

1.WIFI模块--ESP8266 名字由来&#xff1a; Wi-Fi这个术语被人们普遍误以为是指无线保真&#xff08;Wireless Fidelity&#xff09;&#xff0c;并且即便是Wi-Fi联盟本身也经常在新闻稿和文件中使用“Wireless Fidelity”这个词&#xff0c;Wi-Fi还出现在ITAA的一个论文中。…

80,【4】BUUCTF WEB [SUCTF 2018]MultiSQL

53&#xff0c;【3】BUUCTF WEB october 2019 Twice SQLinjection-CSDN博客 上面这个链接是我第一次接触二次注入 这道题也涉及了 对二次注入不熟悉的可以看看 BUUCTF出了点问题&#xff0c;打不开&#xff0c;以下面这两篇wp作为学习对象 [SUCTF 2018]MultiSQL-CSDN博客 …