如何处理contentEditable div内内容可编辑错误跨度的删除?

问题描述 投票:0回答:1

这就是我的 React 组件的样子 -

<div id="test" class="content-editable" contenteditable="true">hi! <div>welcome to&nbsp;</div><div><span contenteditable="false">hey|test('<span class="editable-cas-skip" contenteditable="true">default</span>')</span><br></div></div>

当我按退格键,并且光标位于末尾时,它应该删除整个范围。

javascript reactjs contenteditable wysiwyg rich-text-editor
1个回答
0
投票

您可以通过添加

key.down
事件侦听器来实现此目的,以在
span
末尾识别它,如果是这样,请删除
span

参考以下代码:

import React, { useEffect, useRef } from 'react';

const ContentEditable = () => {
  const contentRef = useRef(null);

  useEffect(() => {
    const handleKeyDown = (e) => {
      if (e.key === 'Backspace') {
        const selection = window.getSelection();
        if (!selection.rangeCount) return;
        
        const range = selection.getRangeAt(0);
        const { startContainer, startOffset, collapsed } = range;
        
        if (collapsed && startContainer.nodeType === Node.ELEMENT_NODE && startContainer.hasAttribute('contenteditable')) {
          const lastChild = startContainer.lastChild;
          
          if (lastChild && lastChild.nodeType === Node.ELEMENT_NODE && lastChild.hasAttribute('contenteditable') && lastChild.getAttribute('contenteditable') === 'false') {
            if (startOffset === startContainer.childNodes.length) {
              e.preventDefault();
              startContainer.removeChild(lastChild);
            }
          }
        }
      }
    };

    const contentEditableElement = contentRef.current;
    if (contentEditableElement) {
      contentEditableElement.addEventListener('keydown', handleKeyDown);
    }

    return () => {
      if (contentEditableElement) {
        contentEditableElement.removeEventListener('keydown', handleKeyDown);
      }
    };
  }, []);

  return (
    <div
      id="test"
      className="content-editable"
      contentEditable="true"
      ref={contentRef}
      dangerouslySetInnerHTML={{ __html: 'hi! <div>welcome to&nbsp;</div><div><span contenteditable="false">hey|test(\'<span class="editable-cas-skip" contenteditable="true">default</span>\')</span><br></div>' }}
    />
  );
};

export default ContentEditable;

© www.soinside.com 2019 - 2024. All rights reserved.