- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
第
react编写可编辑标题示例详解
目录需求初始需求方案设计方案一span+contentEditable思路代码如下在这个方案中遇到的问题存在的问题方案二直接用input处理展示和编辑踩到的坑
需求
因为自己换工作到了新公司,上周入职,以前没有使用过react框架,虽然前面有学习过react,但是并没有实践经验
这个需求最终的效果是和石墨标题修改实现一样的效果
初始需求
文案支持可编辑用户点击位置即光标定位处超过50字读的时候,超出部分进行截断当用户把所有内容删除时,失去焦点时文案设置为无文案三个字编辑区域随着编辑内容的宽度而变化,最大宽度1000px500px失去焦点时保存文案内容
方案设计
在看到第一眼需求的时候,想到的时候用span和input进行切换,但是这个肯定是满足不了需求中第2点,所以首先这个需求肯定不会是两个标签切换,只能一个标签承担展示和编辑的功能,第一反应是用html属性contentEditable,就有了我的第一个套方案,后因为需求的第三点实现上存在问题,所以被迫换了方案二(使用input标签),下面我们详细说说为啥弃用方案1选用方案二以及在这过程中遇到的问题。
方案一span+contentEditable
思路
利用h5提供contentEditble,可实现需求点的1/2/5监听focus事件和input时间,可以实现需求点4监听blur事件,可以实现需求点3
但是需求点中的3点,因为是用字数做的截断,在这个方案中是实现不了的,所以我给出的建议方案是编辑的时候不做截断,非编辑的时候做截断段(是否失去焦点可用作判断是否为编辑态的依据)
代码如下
演示demo:
importReact,{useState,useRef,useEffect}fromreact;
importReactDomfromreact-dom;
interfaceEditTextProps{
text:string;
//告知父组件文案已被修改
changeText:(text:string)=void;
constEditText=function(props:EditTextProps){
useEffect(()={
setShowText(props.text);
},[props.text]);
const[showText,setShowText]=useState();
const[isBlank,setIsBlank]=useState(false);
const[isFocus,setIsFocus]=useState(false);
consttextRef=useRefHTMLDivElement(null);
constonFocus=()={
setIsFocus(true)
constonInput=()={
//避免失去焦点的时候,标题区域明显的闪动
setIsBlank(!textRef.current.innerHTML);
constonBlur=()={
constnewTitle=textRef.current.innerHTML||无标题;
constoldTitle=props.text;
setIsFocus(false);
setIsBlank(false);
//文案更新
if(newTitle!==oldTitle){
props.changeText(newTitle);
setShowText(getCharsByLength(newTitle,50));
else{
//文案不更新
setShowText(getCharsByLength(newTitle,50));
if(textRef.current){
textRef.current.innerHTML=getCharsByLength(newTitle,50)
//获取前length个字符
constgetCharsByLength=(title:string,length:number)={
consttitleLength=title.length;
//假设都是非中文字符,一个中文字符的宽度可以显示两个非
文档评论(0)