react如何使用useRef模仿抖音標(biāo)題里面添加標(biāo)簽內(nèi)容

這是抖音的發(fā)布頁面,此篇文章目的就是為了模仿input輸入特定的文本為標(biāo)簽,并且顯示不同的樣式,
本組件使用一個(gè) div 元素作為輸入框,通過 CSS 樣式和 JavaScript 動(dòng)態(tài)操作 DOM,來實(shí)現(xiàn)與傳統(tǒng) input 輸入框相似的功能。用戶在輸入框中輸入以 # 開頭的文本時(shí),組件會(huì)將其解析為標(biāo)簽,并使用不同的樣式進(jìn)行顯示。
import React, { useState, FC, useRef } from 'react';
interface InputTagProps {
value: string;
onChange: (value: string) => void;
}
const InputTag: FC<InputTagProps> = ({ value, onChange }) => {
const myRef = useRef<HTMLDivElement>(null);
const [isEditing, setIsEditing] = useState(false);
interface ParsedText {
type: string;
content: string;
}
const parseText = (input: string): ParsedText[] => {
// 使用新的正則表達(dá)式來分割文本,保留空格
const parts = input.split(/((?<=\s)|(?=\s)|(?=#))/g).filter(Boolean);
return parts.reduce<ParsedText[]>((acc, part) => {
if (part.trim() === '') {
// 保留空格
acc.push({ type: 'space', content: part });
} else if (part.startsWith('#')) {
// 修改標(biāo)簽的正則表達(dá)式,允許單個(gè)#
if (/^#[\w\u4e00-\u9fa5]*$/.test(part)) {
acc.push({ type: 'tags', content: part });
} else {
// 如果不是有效的標(biāo)簽,作為普通文本處理
acc.push({ type: 'text', content: part });
}
} else {
acc.push({ type: 'text', content: part });
}
return acc;
}, []);
};
const handleClick = () => {
setIsEditing(true);
if (myRef.current) {
myRef.current.innerText = ''; // 清空輸入框內(nèi)容
}
};
const handleBlur = () => {
setIsEditing(false);
if (myRef.current) {
const innerText = myRef.current.innerText;
onChange(innerText); // 更新外部值
myRef.current.innerHTML = ''; // 清空現(xiàn)有內(nèi)容
// 根據(jù)解析的文本動(dòng)態(tài)創(chuàng)建子元素
parseText(innerText).forEach((item) => {
const span = document.createElement('span');
span.innerText = item.content;
span.style.color = item.type === 'tags' ? 'green' : 'black';
myRef.current.appendChild(span);
});
}
};
const handleInput = (event: React.FormEvent<HTMLDivElement>) => {
console.log("chu")
if (myRef.current) {
const innerText = myRef.current.innerText;
// 清空內(nèi)容以便重新填充
myRef.current.innerHTML = '';
// 根據(jù)解析的文本動(dòng)態(tài)創(chuàng)建子元素
parseText(innerText).forEach((item) => {
const span = document.createElement('span');
span.innerText = item.content;
span.style.color = item.type === 'tags' ? 'green' : 'black';
myRef.current.appendChild(span);
});
// 保持光標(biāo)在最后
const range = document.createRange();
const selection = window.getSelection();
range.selectNodeContents(myRef.current);
range.collapse(false); // 將光標(biāo)放在最后
selection?.removeAllRanges();
selection?.addRange(range);
}
};
return (
<div
ref={myRef}
style={{
border: '1px solid #ccc',
borderRadius: '4px',
padding: '8px',
width: '100%',
cursor: isEditing ? 'text' : 'pointer',
}}
onClick={handleClick}
onInput={handleInput}
onBlur={handleBlur}
contentEditable="true"
data-placeholder="請(qǐng)輸入內(nèi)容"
data-node="true"
>
</div>
);
};
export default InputTag;
- 動(dòng)態(tài)解析輸入文本:用戶輸入文本后,組件會(huì)實(shí)時(shí)解析輸入的內(nèi)容,并根據(jù)規(guī)則將特定格式的文本(如以
#開頭的標(biāo)簽)動(dòng)態(tài)生成對(duì)應(yīng)的span標(biāo)簽。 - 自定義樣式:標(biāo)簽的樣式可根據(jù)其類型進(jìn)行不同的設(shè)置,例如使用綠色顯示標(biāo)簽,黑色顯示普通文本。
- 支持中文標(biāo)簽:通過修改正則表達(dá)式,組件支持中文字符作為標(biāo)簽的一部分,使其更加靈活和適應(yīng)多語言環(huán)境。

在實(shí)現(xiàn)過程中,遇到了一些問題,例如無法實(shí)時(shí)處理輸入、輸入 # 時(shí)內(nèi)容被清空等。通過不斷調(diào)試和測(cè)試,最終成功解決了這些問題。這一過程提醒我們,在開發(fā)中,細(xì)致入微的測(cè)試是必不可少的。通過對(duì)代碼的逐行檢查和調(diào)試,我們能夠發(fā)現(xiàn)潛在的錯(cuò)誤和性能問題。
到此這篇關(guān)于react使用useRef模仿抖音標(biāo)題里面添加標(biāo)簽內(nèi)容的文章就介紹到這了,更多相關(guān)react使用useRef內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決antd的Table組件使用rowSelection屬性實(shí)現(xiàn)多選時(shí)遇到的bug
這篇文章主要介紹了解決antd的Table組件使用rowSelection屬性實(shí)現(xiàn)多選時(shí)遇到的bug問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
react中的useContext具體實(shí)現(xiàn)
useContext是React提供的一個(gè)鉤子函數(shù),用于在函數(shù)組件中訪問和使用Context,useContext的實(shí)現(xiàn)原理涉及React內(nèi)部的機(jī)制,本文給大家介紹react中的useContext具體實(shí)現(xiàn),感興趣的朋友一起看看吧2023-11-11
ReactNative錯(cuò)誤采集原理在Android中實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了ReactNative錯(cuò)誤采集原理在Android中實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
React中事件綁定this指向三種方法的實(shí)現(xiàn)
這篇文章主要介紹了React中事件綁定this指向三種方法的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
vite+react+tailwindcss的簡(jiǎn)單使用方式
這篇文章主要介紹了vite+react+tailwindcss的簡(jiǎn)單使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01

