react如何使用useRef模仿抖音標(biāo)題里面添加標(biāo)簽內(nèi)容
這是抖音的發(fā)布頁面,此篇文章目的就是為了模仿input輸入特定的文本為標(biāo)簽,并且顯示不同的樣式,
本組件使用一個 div
元素作為輸入框,通過 CSS 樣式和 JavaScript 動態(tài)操作 DOM,來實現(xiàn)與傳統(tǒng) input
輸入框相似的功能。用戶在輸入框中輸入以 #
開頭的文本時,組件會將其解析為標(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á)式,允許單個# 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ù)解析的文本動態(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ù)解析的文本動態(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="請輸入內(nèi)容" data-node="true" > </div> ); }; export default InputTag;
- 動態(tài)解析輸入文本:用戶輸入文本后,組件會實時解析輸入的內(nèi)容,并根據(jù)規(guī)則將特定格式的文本(如以
#
開頭的標(biāo)簽)動態(tài)生成對應(yīng)的span
標(biāo)簽。 - 自定義樣式:標(biāo)簽的樣式可根據(jù)其類型進(jìn)行不同的設(shè)置,例如使用綠色顯示標(biāo)簽,黑色顯示普通文本。
- 支持中文標(biāo)簽:通過修改正則表達(dá)式,組件支持中文字符作為標(biāo)簽的一部分,使其更加靈活和適應(yīng)多語言環(huán)境。
在實現(xiàn)過程中,遇到了一些問題,例如無法實時處理輸入、輸入 #
時內(nèi)容被清空等。通過不斷調(diào)試和測試,最終成功解決了這些問題。這一過程提醒我們,在開發(fā)中,細(xì)致入微的測試是必不可少的。通過對代碼的逐行檢查和調(diào)試,我們能夠發(fā)現(xiàn)潛在的錯誤和性能問題。
到此這篇關(guān)于react使用useRef模仿抖音標(biāo)題里面添加標(biāo)簽內(nèi)容的文章就介紹到這了,更多相關(guān)react使用useRef內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決antd的Table組件使用rowSelection屬性實現(xiàn)多選時遇到的bug
這篇文章主要介紹了解決antd的Table組件使用rowSelection屬性實現(xiàn)多選時遇到的bug問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08ReactNative錯誤采集原理在Android中實現(xiàn)詳解
這篇文章主要為大家介紹了ReactNative錯誤采集原理在Android中實現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02