-
淡入淡出效果 整体思路:
-
input撑开宽度 整体思路:
可以把span的字体设置成透明的,然后把input的字体设置成想要的颜色(因为color可以继承)
<Span>
{name}
<input style={width:"100%"} value={name} onInput={(e)=>{const {name}=e.target.value setName(name)}}/>
</span>
- 需求实战:
function HomeTimeWithWelcomes(){
const _name = localStorage.getItem(LocalStorageKey.HOME_USER_NAME) || "";
const _fadeInIndex = Number(localStorage.getItem(LocalStorageKey.HOME_HELLO_INDEX)) || 0;
let _fadeOutIndex = _fadeInIndex - 1;
if (_fadeInIndex === 0) {
_fadeOutIndex = 2;
}
const [ name, setName ] = useState(_name);
const [ tempName, setTempName ] = useState(name);
const [ showInput, setShowInput ] = useState(false);
const [ fadeOutIndex, setFadeOutIndex ] = useState(_fadeOutIndex);
const [ fadeInIndex, setFadeInIndex ] = useState(_fadeInIndex);
const [ isFadeActive, setIsFadeActive ] = useState(true); // 必须是true,这样可以让fadeInEle展示在页面上
const [ boxWidth, setBoxWidth ] = useState("");
// 招呼语切换文案
const [ switchTextArr ] = useState([
"上午好",
"Good morning",
"勇攀高峰"]);
// 每次fadeInIndex改变,拿到fadeInEle的宽度;
const fadeInEle = useRef(null);
useEffect(() => {
setBoxWidth(fadeInEle.current.offsetWidth);
}, [ fadeInIndex ]);
return <div>
<div
style={{
height: 52,
overflow: "hidden",
display: "inline-block", // 招呼语不是独占一行,后面还有昵称
width: boxWidth, // 根据fadeInEle的宽度,动态改变自己的宽度,并添加动画
transition: "all 500ms ease-in-out",
}}
onClick={()=>{
// 取消动画
setIsFadeActive(false);
// 开启动画,用setTimeout的原因:等视图更新后,再更改这个状态
setTimeout(() => {
setIsFadeActive(true);
});
// 更新两个item中的内容
setFadeOutIndex(fadeOutIndex === 2 ? 0 : fadeOutIndex + 1);
setFadeInIndex(fadeInIndex === 2 ? 0 : fadeInIndex + 1);
localStorage.setItem(LocalStorageKey.HOME_HELLO_INDEX,
fadeInIndex === 2 ? 0 : fadeInIndex + 1);
}}>
<div
className={`${isFadeActive ?
"home-time-hello-fade-active0" : "home-time-hello-fade-active0-not"}
home-time-hello home-time-hello-fade-active`}
>{switchTextArr[fadeOutIndex]}</div>
<div
ref={fadeInEle}
className={`${isFadeActive ?
"home-time-hello-fade-active1" : "home-time-hello-fade-active1-not"}
home-time-hello home-time-hello-fade-active marginRight12`}
>{switchTextArr[fadeInIndex]}{fadeInIndex !== 2 ? "," : ""}</div>
</div>
// 需求: 双击更改昵称,清空昵称无效,仍未之前昵称,只能更改昵称;
<span
className={`${tempName.length === 0 &&
"empty-under-line"}
home-time-hello-span flex-row-center home-time-hello `}
id="home-time-hello-span"
onDblClick={()=>{
setShowInput(true);
}}
>
{tempName.slice(0, isCN(tempName) ? 8 : 16)}
// 由于input是不会被撑开宽度的,所以外套span,用span的文字撑起宽度,让input的宽度设为100%,随span变宽
{showInput && <input
type="text"
id="home-time-hello-input"
className="home-time-hello-input"
value={tempName} // 必须是tempName,这样input显示的值才是动态变化的
autoFocus={showInput} // 显示input时自动聚焦
onKeyDown={event => {
if (event.keyCode == 13) {
document.getElementById("home-time-hello-input").blur();
}
}}
onChange={e=> {
// 输入时,span的文字会与输入的字重叠,
// 所以需要把span的文字设置成透明的;由于color是可继承的,所以需要手动再改变input的color颜色
document.getElementById("home-time-hello-span").style.color = "rgba(255,255,255,0)";
document.getElementById("home-time-hello-input").style.color = "#FFFFFF";
const { value } = e.target;
// 由于不确定他是不是在清空input,就把输入的值存在临时的TempName里,不去更改真实的name
// 这种能来回改动的值,就必须写在span里了,因为能随时改变宽度
setTempName(value);
if (value.length === 0) {
//因为一旦TempName为0了,span就会有自己的下划线
document.getElementById("home-time-hello-input").style.borderBottom = "none";
} else {
document.getElementById("home-time-hello-input").style.borderBottom = "#FFFFFF solid 3px";
}
}}
onFocus={e=>{
document.getElementById("home-time-hello-span").style.color = "rgba(255,255,255,0)";
document.getElementById("home-time-hello-input").style.color = "#FFFFFF";
if (tempName.length === 0) {
document.getElementById("home-time-hello-input").style.borderBottom = "none";
}
}}
onBlur={e=>{
// 失焦若发现他清空了input,就把TempName改为没有更改过的name;
const { value } = e.target;
if (value.length === 0) {
setTempName(name);
localStorage.setItem(LocalStorageKey.HOME_USER_NAME, name);
} else {
setName(value);
localStorage.setItem(LocalStorageKey.HOME_USER_NAME, value);
}
setShowInput(false);
document.getElementById("home-time-hello-span").style.color = "#FFFFFF";
}}
/>}
</span>
<span className="home-time-hello-input-end">.</span>
</div>
}