美文网首页
如何给TextArea文本框中,点击按钮新增一个Tag标签

如何给TextArea文本框中,点击按钮新增一个Tag标签

作者: Poppy11 | 来源:发表于2023-06-20 17:05 被阅读0次

contenteditable

修改元素的可编辑性,使之可以编辑,html就给我们提供了这么个属性,要知道在一个普通元素内插入一个标签要比在textarea中要容易多了。

-webkit-user-modify

  • read-only: 默认值,元素只读,不可编辑;
  • read-write: 可以编辑,支持富文本;
  • read-write-plaintext-only: 可以编辑,不支持富文本;
  • write-only: 使元素仅用于编辑(几乎没有浏览器支持)

Range对象

可以用 Document 对象的 Document.createRange 方法创建 Range,也可以用 Selection 对象的 getRangeAt 方法获取 Range。另外,还可以通过 Document 对象的构造函数 Range() 来得到 Range。我在实现的时候通过的是selection对象(表示用户选择的文本范围或插入符号的当前位置)的方法创建的,通过监听selectionchange事件来响应式的更新我的range,这样我就可以定位到光标的位置,那么对于标签插在哪的问题就解决了。

需求:点击插入问题,会在textArea中新增一个tag,并且在textArea中添加了tag后,按钮是处于禁用的状态,当保存后,编辑该prompt时,内容还是会在,所以此处我使用了dangerouslySetInnerHTML。

image.png

interface TextareaProps {
    defaultValue: string;
    getRange?: (range: Range) => void;
    ref?: React.Ref<any>;
    onChange: (innerHtml: string) => void;
    isHaveTag: (isHaveTag: boolean) => void;
}


const TagTextarea: FC<TextareaProps> = forwardRef((props, ref) => {
    const [contentId, setContentId] = useState(`content${uuid()}`);
    const inputTag = useRef<HTMLDivElement>(null);

    useImperativeHandle(
        ref,
        () => {
            return {
                addTag,
            };
        },
        []
    );

    const handleInput = () => {
        const tagTextareaValue = (inputTag as any).current.innerHTML;
        props.onChange((inputTag as any).current.innerHTML);
        const regex = /id="textarea_tag"/;
        props.isHaveTag(regex.test(tagTextareaValue));
    };

    const selecthandler = () => {
        const sel = window.getSelection();
        const range = sel ? (sel.rangeCount > 0 ? sel?.getRangeAt(0) : null) : null;
        if (range && range.commonAncestorContainer.ownerDocument?.activeElement?.id === contentId) {
            props.getRange && props.getRange(range);
        }
    };

    useEffect(() => {
        handleInput();
    }, []);

    useEffect(() => {
        document.addEventListener('selectionchange', selecthandler);
        return () => {
            document.removeEventListener('selectionchange', selecthandler);
        };
    }, []);

    const insertNode = (node: Element, range: Range) => {
        range && range.deleteContents();
        range && range.insertNode(node);
        handleInput();
    };

    const addTag = (text: string, range: Range) => {
        const tag = (
            <div id='textarea_tag' className='textarea_tag'>
                {text}
            </div>
        );
        const componentString = ReactDOMServer.renderToString(tag);
        const componentElement: any = new DOMParser().parseFromString(componentString, 'text/html').body
            .firstChild;
        insertNode(componentElement, range);
    };

    return (
        <div className='tagTextArea'>
            <div
                contentEditable='true'
                className='overflow-auto myTextArea px-3 py-1.5 outline-none bg-white text-[#303030] text-sm block rounded-md border-0 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6'
                onInput={handleInput}
                ref={inputTag}
                id={contentId}
                dangerouslySetInnerHTML={{ __html: props.defaultValue }}
            ></div>
        </div>
    );
});


.myTextArea {
    -webkit-user-modify: read-write-plaintext-only !important;
    border: 1px solid #ccc;
    overflow: hidden;
    box-sizing: border-box;
    word-break: break-word;
    height: 60px;
}

.textarea_tag {
    color: #c41d7f;
    background: #fff0f6;
    border-color: #ffadd2;
    -webkit-user-modify: read-only;
    display: inline;
    margin: 0 6px;
    font-size: 12px;
    padding-inline: 7px;
    border: 1px solid #d9d9d9;
    border-radius: 4px;
}

相关文章

  • 点击cell获取当前的indexPath

    如果一个cell中有多个按钮,要点击任何一个按钮给cell设置tag值,然后添加代理方法实现点击不同的按钮

  • input,textarea的区别

    在HTML中有两种方式表达文本框,一个是用input标签的单行文本框,一种是textarea标签多行文本框。那我们...

  • 如何在jsp页面中添加文框存储和获取

    首先在jsp页面中添加文本框(text/textarea)、id()。 添加数据库新增字段(first_info)...

  • HTML表单

    HTML表单 input 标签 两个单行文本框和一个提交按钮的表单 直接点击 Submit 按钮, 表单数据将会被...

  • vue2.0 + elementUi 实现无限tab式页面

    使用elementUi的tabs组件 + vuex 实现点击菜单或者点击按钮新增一个tab标签页 一、思路 由于之...

  • 第一次作业第一题

    作业要求 点击显示按钮标签中显示Hello World!点击清除按钮清除标签内容,点击弹出按钮弹出消息框。 代码 ...

  • 移动端HTML5点击事件闪现灰色背景解决方案

    隐藏文本框阴影 input, textarea{-webkit-appearance:@none;} 取消手机点击...

  • HTML笔记 - 草稿

    accesskey属性,可以用快捷键进行某种操作。 textarea标签 多行文本框

  • 第四天

    1、Form:包裹标签,action:# Input:文本框,单选按钮,多选按钮。提交的按钮,按钮,重置的按钮。 ...

  • JS基础学习:操作DOM案例

    点击按钮显示图片 点击按钮修改a标签的地址和热点文字 点击按钮修改p标签的内容 点击按钮修改多个p标签的文字 点击...

网友评论

      本文标题:如何给TextArea文本框中,点击按钮新增一个Tag标签

      本文链接:https://www.haomeiwen.com/subject/vxnyydtx.html