【问题标题】:Contenteditable element's cursor doesn't go back to original place when inserting new line and deleting插入新行和删除时,Contenteditable 元素光标不会回到原来的位置
【发布时间】:2022-10-03 00:56:04
【问题描述】:

我有这个简单的 html 代码:

span{
  outline: none;
}
hello
<span contenteditable=\"true\">
  world
</span>

我注意到每次我按下进入contenteditable 跨度中,光标按预期转到新行,但是当按下退格光标不会回到原来的位置,它会向左+向上移动更多,并且只有在按下时退格再次,它回到原来的地方:

这是一个错误吗?有什么解决方法吗?
谢谢

    标签: html contenteditable


    【解决方案1】:

    使用 Chrome 调试器时,您会注意到按 Enter 键后会出现两个换行符跨度内产生。正如您仅在第二次按退格键时才注意到的那样,您删除了第二个换行符,这可能是您遇到的间距不规则的原因。

    据我所知,这是正常的,因为换行符以某种方式与空格相互作用

    编辑:我花了很长时间玩这个,结果与你假设的游标有三个位置相反:

    1. 在 contenteditable span 中存在文本时,游标与其内容框对齐
    2. 如果没有文本且在其后出现换行符,光标将与前一个文本对齐
    3. 由于某些特殊原因,没有文本也没有换行符,游标位于跨度内容框的略下方。

      为什么会发生这一切,遗憾的是我不知道,但希望你能利用这些信息来发挥你的优势

      编辑2:在第三种情况下找到光标所在的位置,即它在您的情况下捕捉到父内容框的底部,这将是正文元素

      这是我为您编写的代码,您可以自己查看:

      span[contenteditable="true"] {
              outline: none;
              background-color: red;
              border: 2px solid blue;
              line-height: 2em;
            }
            span.first {
              font-size: 0.8em;
              border:2px solid violet
            }
            br{
              border: 2px solid green;
            }
            body {
              font-size: 10rem;
              border: 2px solid aqua
            }
      <!DOCTYPE html>
      <html>
        <body>
          <span class="first">
            hello
          </span>
          <span contenteditable="true"> world </span>
      </html>

    【讨论】:

    • 'As far as i know this is normal since line breaks interact with whitespace in some way' 为什么这是正常的? textarea 不会发生这种情况
    • 我刚刚意识到这将是对您的问题的更好扩展,而不是答案,因此请随时使用我的研究来更新问题
    • 感谢您的回答!,我终于找到了解决方案。
    【解决方案2】:

    最后,我设法使用ZeroWidthSpace 字符来欺骗浏览器,该字符始终插入到元素innerHTML 的开头。据我了解,错误(?)仅在元素中没有文本时才会出现,因此插入“non-text”字符即可解决。

    这是我使用自定义Web Component 制作的一个 sn-p,它可以自动解决问题:

    class CeElement extends HTMLElement {
            constructor() {
                super();
            }
            connectedCallback(){
                this.addEventListener("input", function() {
                    if(!this.innerHTML || this.innerHTML==0) {
                        this.innerHTML = "&#8203;";
                    }
                }, false);
                this.innerHTML = "&#8203;" + this.innerHTML;
                this.contentEditable = true; 
            }
    }
    window.customElements.define('ce-element', CeElement);
    ce-element{
      outline: none;
    }
    <span style="white-space: pre;">hello </span>  <! -- the span is only for the saving the space with 'white-space: pre;' -->
    <ce-element>
    world
    </ce-element>

    【讨论】:

      猜你喜欢
      • 2015-01-16
      • 2014-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-07
      • 2020-11-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多