react如何使用useRef模仿抖音標題里面添加標簽內容

這是抖音的發(fā)布頁面,此篇文章目的就是為了模仿input輸入特定的文本為標簽,并且顯示不同的樣式,
本組件使用一個 div 元素作為輸入框,通過 CSS 樣式和 JavaScript 動態(tài)操作 DOM,來實現(xiàn)與傳統(tǒng) input 輸入框相似的功能。用戶在輸入框中輸入以 # 開頭的文本時,組件會將其解析為標簽,并使用不同的樣式進行顯示。
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[] => {
// 使用新的正則表達式來分割文本,保留空格
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('#')) {
// 修改標簽的正則表達式,允許單個#
if (/^#[\w\u4e00-\u9fa5]*$/.test(part)) {
acc.push({ type: 'tags', content: part });
} else {
// 如果不是有效的標簽,作為普通文本處理
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 = ''; // 清空輸入框內容
}
};
const handleBlur = () => {
setIsEditing(false);
if (myRef.current) {
const innerText = myRef.current.innerText;
onChange(innerText); // 更新外部值
myRef.current.innerHTML = ''; // 清空現(xiàn)有內容
// 根據(jù)解析的文本動態(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;
// 清空內容以便重新填充
myRef.current.innerHTML = '';
// 根據(jù)解析的文本動態(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 range = document.createRange();
const selection = window.getSelection();
range.selectNodeContents(myRef.current);
range.collapse(false); // 將光標放在最后
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="請輸入內容"
data-node="true"
>
</div>
);
};
export default InputTag;
- 動態(tài)解析輸入文本:用戶輸入文本后,組件會實時解析輸入的內容,并根據(jù)規(guī)則將特定格式的文本(如以
#開頭的標簽)動態(tài)生成對應的span標簽。 - 自定義樣式:標簽的樣式可根據(jù)其類型進行不同的設置,例如使用綠色顯示標簽,黑色顯示普通文本。
- 支持中文標簽:通過修改正則表達式,組件支持中文字符作為標簽的一部分,使其更加靈活和適應多語言環(huán)境。

在實現(xiàn)過程中,遇到了一些問題,例如無法實時處理輸入、輸入 # 時內容被清空等。通過不斷調試和測試,最終成功解決了這些問題。這一過程提醒我們,在開發(fā)中,細致入微的測試是必不可少的。通過對代碼的逐行檢查和調試,我們能夠發(fā)現(xiàn)潛在的錯誤和性能問題。
到此這篇關于react使用useRef模仿抖音標題里面添加標簽內容的文章就介紹到這了,更多相關react使用useRef內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
react-native android狀態(tài)欄的實現(xiàn)
這篇文章主要介紹了react-native android狀態(tài)欄的實現(xiàn),使狀態(tài)欄顏色與App顏色一致,使用戶界面更加整體。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-06-06
React中setState/useState的使用方法詳細介紹
這篇文章主要介紹了React中setState/useState的使用方法,useState 和 setState 在React開發(fā)過程中 使用很頻繁,但很多人都停留在簡單的使用階段,并沒有正在了解它們的執(zhí)行機制2023-04-04
React組件中監(jiān)聽函數(shù)獲取不到最新的state問題
這篇文章主要介紹了React組件中監(jiān)聽函數(shù)獲取不到最新的state問題問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01

