工作问题记录React(持续更新中)

news/2024/5/19 4:25:00

一、backdrop-filter:blur(20px);

毛玻璃效果,在安卓机上有兼容问题,添加兼容前缀也无效;
解决方案:让设计师调整渐变,不要使用该属性!

在这里插入图片描述

复制代码

background: radial-gradient(33% 33% at 100% 5%, #e9e5e5 0%, rgba(254, 251, 243, 0) 100%),radial-gradient(54% 54% at -5% 6%,#d2d1cf 0%,#ebe9e2 30%,#fdfaf0 42%,rgba(255, 255, 255, 0) 100%),linear-gradient(160deg, #edeae3 0%, #fffdfe 31%, #ffeff7 94%),linear-gradient(180deg, rgba(255, 255, 255, 0.6) 0%, #ffffff 32%);

二、如何实现倒计时效果

首先我们需要一个时间差,并且这个差值根据现在的差值一直在递减
其次我们需要维护一个时间状态,每隔一秒钟就需要更新这个状态从而触发页面的更新
JavaScript
复制代码

useEffect(()=>{let timer = null;// 注意月份是从0开始的,所以4月是3const targetTime = new Date(2024, 3, 20, 20, 0, 0).getTime();timer = setInterval(() => {const currentTime = new Date().getTime();if (new Date(2024, 3, 20, 0, 0, 1).getTime() >= new Date(2024, 3, 20, 0, 0, 0).getTime()) {setShowCount(true);} else {return;}const remainingTime = targetTime - currentTime;if (remainingTime >= 0) {const total = remainingTime / 1000; // 剩余秒数const hh = parseInt(total / (60 * 60)); // 剩余小时const day = parseInt(hh / 24); // 剩余天数const h = hh - parseInt(day * 24);const mm = parseInt((total - hh * 60 * 60) / 60); // 剩余分钟const ss = parseInt(total % 60); // 剩余秒setTime({day,h,m: mm,s: ss,});} else {clearInterval(timer);}}, 1000);return () => {if (timer) clearInterval(timer);};
},[]);
<View className="header">距离直播开始{time.day}天{time.h}小时{time.m.toString().padStart(2, '0')}分钟{time.s.toString().padStart(2, '0')}秒钟
</View>

三、如何实现两个动画丝滑的切换

大概的思路基本上是只针对url的切换,但是只是这样局部更新url 并不会引起容器里动画的更新

const initLottieRef = useRef();// 展示动画的容器
const [url, setUrl] = useState('https://g.alicdn.com/ani-assets/1bb995ac4ad001ab8f091e412dc5e7c0/0.0.1/lottie.json',
);
const curlt = useRef();// 用来接第一个动画实例
useEffect(() => {curlt.current = lottie.loadAnimation({container: initLottieRef.current,renderer: 'svg',loop: true,autoplay: true,path: url, // 替换为你的第一个动画的 JSON 文件路径});
}, [url]);const onClick = () => {// 停止第一个动画并移除其容器curlt.current.stop();// 清空容器以移除第一个动画initLottieRef.current.innerHTML = ''; // 初始化并显示第二个动画setUrl('https://g.alicdn.com/ani-assets/93cbb9eeb82ff32a1fd746bc7a284e04/0.0.1/lottie.json');};

四、弹窗组件如何阻止点击滚动穿透

蒙层级别提高,在容器点击阻止冒泡和默认行为

onClick={(e) => e.stopPropagation()}
onTouchMove={(e) => e.preventDefault()}设置了这个可能回影响本身的滚动
const onAppear = () => {// 防止蒙层滚动穿透document.body.style.overflow = 'hidden';goldlog.realtime('pending-payment-prompt-pop', 'EXP', 'pending-payment-prompt-pop-express');};const onClose = () => {setIsShow(false);document.body.style.overflow = 'auto';};

五、实现淡入淡出

用原生js 动态添加类名的方式试了好久,还是不行
reatc 组件有自己的更新机制,即使添加上了类名但没有遵守react 更新规则并不会触发更新

<div className={`${classlist.join(' ')}`} ></div>
const [classlist, setClasslist] = useState(['container', 'show-pop']);
const onClose = () => {goldlog.realtime('equity-comparison-pop', 'CLK', 'equity-comparison-pop-close');setClasslist(['container', 'hide-pop']);setTimeout(() => {setIsShow(false);document.body.style.overflow = 'auto';setClasslist(['container', 'show-pop']);}, 300);};
.show-pop {animation: show-pop 0.3s ease-in-out forwards;
}
.hide-pop {animation: hide-pop 0.3s ease-in-out forwards;
}@keyframes show-pop {0% {transform: translateY(100%); /* 初始位置:屏幕底部之外 */opacity: 0; /* 初始透明度为0,实现淡入效果 */}100% {transform: translateY(0); /* 结束位置:屏幕顶部 */opacity: 1; /* 结束透明度为1,完全显示 */}
}@keyframes hide-pop {0% {transform: translateY(0); /* 结束位置:屏幕顶部 */opacity: 1; /* 结束透明度为1,完全显示 */}100% {transform: translateY(100%); /* 初始位置:屏幕底部之外 */opacity: 0; /* 初始透明度为0,实现淡入效果 */}
}

六、实现骨架屏

先上关键代码

 background: linear-gradient(90deg,rgba(190, 190, 190, 0.2) 25%,rgba(129, 129, 129, 0.24) 37%,rgba(190, 190, 190, 0.2) 63%);background-size: 400% 100%;animation: skeleton 1.4s ease infinite; @keyframes skeleton {0% {background-position: 0% 0%;}100% {background-position: 100% 0%;}}

为什么这样能实现?
以下是这段代码的工作原理:

背景渐变: background: linear-gradient(90deg, …); 定义了一个从左到右的线性渐变。渐变中有三个颜色停止点:

rgba(190, 190, 190, 0.2) 25%: 在25%的位置,颜色为浅灰色,透明度为20%。
rgba(129, 129, 129, 0.24) 37%: 在37%的位置,颜色为深灰色,透明度为24%。
rgba(190, 190, 190, 0.2) 63%: 在63%的位置,再次变为浅灰色,透明度为20%。 这样的渐变在视觉上产生了一种类似条纹的效果,模拟数据加载时的动态感。
背景尺寸: background-size: 400% 100%; 设置背景的尺寸为元素宽度的400%。这使得背景图像是元素宽度的4倍,为动画提供了足够的空间。

动画: animation: skeleton 1.4s ease infinite; 应用名为skeleton的动画,持续时间为1.4秒,缓动函数为ease(意味着动画开始和结束时速度较慢,中间速度快),并且无限循环。

@keyframes定义了一个动画,从0%到100%的动画过程中,背景的位置从0%平移到100%,即从左到右移动一个完整背景的长度。由于背景尺寸是元素宽度的400%,所以在动画过程中,这个条纹效果会来回移动,模拟数据加载的进度。

这个简单动画组合起来就形成了一个骨架屏效果,给人一种数据正在加载的感觉。当然,真正的骨架屏通常会包含更复杂的形状和元素来匹配页面的实际布局。

七、隐藏滚动条

 <style>{` #scroll-list::-webkit-scrollbar { display: none }`}</style><div className="root" id="scroll-list">

八、实现吸顶效果

使用粘性定位来实现,他的参考点是距离它最近的一个拥有滚动机制的祖先元素,不设置默认就是当前窗口

  position: -webkit-sticky; /* Safari */position: sticky;top: 30px;

九、实现回到顶部,按钮带动画效果

按钮实现从右向左出现,从左向右消失

import React, { useState, useEffect } from 'react';
import './styles.css'; // 引入样式const ScrollToTopButton = () => {const [isVisible, setIsVisible] = useState(false);const [isAnimating, setIsAnimating] = useState(false);const scrollToTop = () => {window.scrollTo({ top: 0, behavior: 'smooth' });};useEffect(() => {const toggleVisibility = () => {if (window.pageYOffset > 300) {setIsVisible(true);setIsAnimating(true);} else {setIsAnimating(false);setTimeout(() => {setIsVisible(false);}, 1000); // 动画持续时间加一点延迟,确保动画完成后再重置}};window.addEventListener('scroll', toggleVisibility);// 清理函数,移除滚动事件监听器return () => window.removeEventListener('scroll', toggleVisibility);}, [])return ({isVisible && <button className={`back-top ${isAnimating ? 'fade-in-right' : 'fade-out-left'}`} onClick={scrollToTop}>top</button>});
};export default ScrollToTopButton;
.fade-in-right {animation: fade-in-right 1s ease-in-out forwards;
}.fade-out-left {animation: fade-out-left 1s ease-in-out forwards;
}@keyframes fade-in-right {0% {transform: translateX(100%);opacity: 0;}100% {transform: translateX(0);opacity: 1;}
}@keyframes fade-out-left {0% {transform: translateX(0);opacity: 1;}100% {transform: translateX(100%);opacity: 0;}
}

十、轮播

滚动的方式:
1 transform
2 scrollto
3 绝对定位移动left
困惑 :滚完就反向弹回了第一个,怎么让他继续滚?
要解决视觉上回弹的问题只需要在滚到最初位置的时候取消过渡效果

import React, { useEffect, useRef } from 'react';
import './index.css'; // 假设你有一个外部CSS文件来定义样式const Slider = () => {const images = ['1', '2', '3', '4']const currentIndex = useRef(0);const sliderRef = useRef(null);// 自动切换到下一张的逻辑useEffect(() => {const timer = setInterval(() => {const nextIndex = currentIndex.current === images.length - 1 ? 0 : currentIndex.current + 1;const translateX = nextIndex * -100 + '%'; // 假设每张图片占据100%的宽度。sliderRef.current.style.transform = `translateX(${translateX})`;if (translateX === '0%') {sliderRef.current.style.transition = '';//取消过渡视觉上不会出现反向滚动} else {sliderRef.current.style.transition = 'transform 0.5s ease-in-out';}currentIndex.current = nextIndex;}, 2000);// 清理函数,防止内存泄漏return () => {clearInterval(timer);};}, []);return (<div ref={sliderRef} ><div style={{ display: 'flex' }}>{images.map((image, index) => (<div style={{ width: '100%', height: 100, border: '1px solid red', flexShrink: 0, boxSizing: 'border-box' }}>slide {index + 1}</div>))}</div></div>);
};export default function App() {return (<div className="App"><Slider /></div>);
}

十一、下拉刷新

import React, { useState, useEffect, useRef } from 'react';
import './index.css';let startY;
// 提取防抖函数到组件外
const debounce = (func, wait) => {let timeout;return function (...args) {clearTimeout(timeout);timeout = setTimeout(() => {try {func.apply(this, args);} catch (error) {console.error('Error in debounced function:', error);}}, wait);};
};
const MyComponent = () => {const scrollRef = useRef(null);const [loading, setLoading] = useState(false);const [refresh, setRefresh] = useState(false);const fetachData = () => new Promise(resolve => setTimeout(() => {console.log('数据刷新完成');setLoading(false);resolve();}, 1000));const fetchNewData = debounce(async () => {await fetachData();}, 500); // 防抖延迟时间const onTouchStart = (e) => {startY = e.touches[0].clientY;}const onTouchmove = (e) => {requestAnimationFrame(() => { // 使用 requestAnimationFrame 优化const moveY = e.touches[0].clientY;const diffY = moveY - startY;scrollRef.current.style.transform = `translateY(${diffY > 100 ? 100 : diffY}px)`;if (diffY > 90) {setRefresh(true);// 发起请求if (!loading) {setLoading(true);fetchNewData();}}});};const onTouchend = () => {requestAnimationFrame(() => { // 使用 requestAnimationFrame 优化scrollRef.current.style.transform = `translateY(0)`;scrollRef.current.style.transition = 'transform 0.3s ease';setRefresh(false);setLoading(false);});}useEffect(() => {const element = scrollRef.current;element.addEventListener('touchstart', onTouchStart);element.addEventListener('touchmove', onTouchmove);element.addEventListener('touchend', onTouchend);return () => {element.removeEventListener('touchstart', onTouchStart);element.removeEventListener('touchmove', onTouchmove);element.addEventListener('touchend', onTouchend);};}, []);useEffect(() => {if (refresh && !loading) {setTimeout(() => {scrollRef.current.style.transform = `translateY(0)`;scrollRef.current.style.transition = 'transform 0.3s ease';setRefresh(false);}, 500)}}, [loading]);return (<div ref={scrollRef} >{refresh && <div className='top-container'>{loading ? '数据刷新中...' : '刷新成功了'}</div>}<div className='tabbar'>我是导航栏</div><div className='content'>{Array.from({ length: 10 }, (v, i) => {return <div key={i} className='content-item'>我是内容{i}</div>})}</div></div >);
};export default MyComponent;

http://www.mrgr.cn/p/32608622

相关文章

SQL注入漏洞--报错/union/布尔盲注/时间盲注

之前介绍了数据库的基本操作&#xff0c;今天这篇文章就来实操SQL注入。 阅读本文前可以先看一下基本操作&#xff0c;有助于更好理解本文。。。 https://blog.csdn.net/weixin_60885144/article/details/138356410?spm1001.2014.3001.5502 what SQL---结构化查询语言---S…

spring项目创建

从spring initializer下载一个demo Spring boot 在idea中 需要配置java版本和maven版本之后:mvn package不需要下载tomcat,Spring里面pom中包含内置tomcat<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-…

库存管理系统开源啦

软件介绍 ModernWMS是一个针对小型物流仓储供应链流程的开源库存管理系统。该系统的开发初衷是为了满足中小型企业在有限IT预算下对仓储管理的需求。通过总结多年ERP系统研发经验&#xff0c;项目团队开发了这套适用于中小型企业的系统&#xff0c;以帮助那些有特定需求的用户。…

华为鸿蒙系统(Huawei HarmonyOS)

华为鸿蒙系统&#xff08;华为技术有限公司开发的分布式操作系统&#xff09; 华为鸿蒙系统&#xff08;HUAWEI HarmonyOS&#xff09;&#xff0c;是华为公司在2019年8月9日于东莞举行的华为开发者大会&#xff08;HDC.2019&#xff09;上正式发布的分布式操作系统。 华为鸿蒙…

数仓开发:DIM层数据处理

一、了解DIM层 这个就是数仓开发的分层架构 我们现在是在DIM层&#xff0c;从ods表中数据进行加工处理&#xff0c;导入到dwd层&#xff0c;但是记住我们依然是在DIM层&#xff0c;而非是上面的ODS和DWD层。 二、处理维度表数据 ①先确认hive的配置 -- 开启动态分区方案 -- …

高一下三调|ssy的队列|hash dp|题解

SSY的队列题目链接 解析: 考场上看到这个题第一眼是绝望的,毕竟数论咱是一窍不通. 但是往下细看了看这个数据范围,N是很小的,就想了想模拟. 然而只骗到10分. 这个题绩效较高的解法是状压dp,在N<15的范围之内均可薄纱(ppllxx_9G也是成功拿到这70 rank 1了 orz),可得70,但是一…

Git——关于Git的一些补充(1)

Git——关于Git的一些补充(1) 提示:图床在国外且动图比较多的情况下,需要时间加载。 目录: 目录Git——关于Git的一些补充(1)提示:图床在国外且动图比较多的情况下,需要时间加载。目录:Git基础Git文件的生命周期Git文件的存储空间的划分Git安装过程补充说明Git的撤销…

UHF RFID 使用小记

1,概念 UHF:Ultra High Frequency;超高频。 RFID:Radio Frequency Identification;射频识别。 电子标签:即RFID标签,是RFID的俗称。 PDA:Personal Digital Assistant;个人数字助理。 发卡器:对卡进行读写操作的工具。 EPC:Electronic product code;电子产品代码。 …

企业计算机服务器中了lockbit勒索病毒如何处理,lockbit勒索病毒解密流程建议

在虚拟的网络世界里&#xff0c;人们利用网络获取信息的方式有很多&#xff0c;网络为众多企业提供了极大便利性&#xff0c;也大大提高了企业生产运营效率&#xff0c;方便企业开展各项工作业务。但随着网络技术的不断发展与应用&#xff0c;越来越多的企业开始关注企业网络数…

RAGFlow:安装与体验

服务器需要有docker,或者直接访问官方提供的demo: https://demo.ragflow.io/ docker-compose安装 需要确保 vm.max_map_count 不小于 262144 【更多】:sysctl -w vm.max_map_count=262144 克隆仓库:$ git clone https://github.com/infiniflow/ragflow.git 进入 doc…

文学作品|在线阅读

分享文字和音频类的文学作品,陶冶情操,宣传正能量。#wh-tab{font-size:20px;text-align:center;}a:link {text-decoration: none;}td{font-size: 16px;text-align:center;}td:empty:after{content:虚位以待;color:grey;} 前言 若有空,将古今中外的常见文学作品挂载在网络上,…

[转]ptp(precision time protocol)时钟同步

一、介绍1:什么是ptpPTP(Precision Time Protocol) 是一个通过网络同步时钟的一个协议。当硬件支持时,PTP 精度能达到亚微秒,比 NTP(Network Time Protocol)精度更高。 2:ptp应用场景1)数据中心数据中心需要NTP/PTP同步,以确保集群的时域运行。同步对于虚拟机计算是必不…

轨道交通巡检机器人的应用范围

在现代轨道交通系统的庞大网络中&#xff0c;无数的轨道、设备和设施交织在一起&#xff0c;如同一个精密的机器在高效运转。而在这背后&#xff0c;轨道交通巡检机器人正悄然登场&#xff0c;它们如同一个个智能的守护者&#xff0c;穿梭于各个场景之中。那么&#xff0c;这些…

3. SpringBoot 整合第三方技术

1. 整合Junit 一般来说是不需要进行处理的 ,因为在创建SpringBoot 工程时 ,会自动整合junit​的 要说怎么配置的话?也可以写一下相关的配置:以下就是SpringBoot 整合 Junit 相关步骤导入相关依赖 <dependency><groupId>org.springframework.boot</groupId&g…

5.5

推一下手机壁纸

内核workqueue框架

workqueue驱动的底半部实现方式之一就是工作队列&#xff0c;作为内核的标准模块&#xff0c;它的使用接口也非常简单&#xff0c;schedule_work或者指定派生到哪个cpu的schedule_work_on。 还有部分场景会使用自定义的workqueue&#xff0c;这种情况会直接调用queue_work和qu…

[转]IRIG-B码授时工作原理

在授时设备中有一种是B码授时的,但是大部分人不太清楚何为B码授时?这种类型的授时工作原理是怎么样? 首先我们要知道什么是B码,然后再介绍它的授时工作原理,B码是一种电力术语,它是IRIG-B码的通俗叫法,英文全称是inter-range instrumentationgroup-B,是在2020年公布的电…

环形链表的约瑟夫问题

typedef struct ListNode ListNode;//创建新节点ListNode* buyNode(int x){ListNode* node(ListNode*)malloc(sizeof(ListNode));if(nodeNULL){exit(1);}node->valx;node->nextNULL;return node;}//创建环形链表ListNode* createCircle(int n){ListNode* pheadbuyNode(1)…

my-room-in-3d中的电脑,电视,桌面光带发光原理

1. my-room-in-3d中的电脑&#xff0c;电视&#xff0c;桌面光带发光原理 最近在github中&#xff0c;看到了这样的一个项目&#xff1b; 项目地址 我看到的时候&#xff0c;蛮好奇他这个光带时怎么做的。 最后发现&#xff0c;他是通过&#xff0c;加载一个 lightMap.jpg这个…

2024 年12个好用的开源 Wiki 软件工具盘点

Wiki是一个集中式的、基于网络的平台,使员工可以轻松地访问和记录信息。简单来说,它是一个可靠信息的统一来源。在任何成功的公司中,部门间的知识共享是至关重要的。如果没有一个简单的信息交流方法,团队怎样才能有效合作呢?Wiki软件提供了一种创建、组织及在全公司范围内…