css 从div中删除字符时,光标移动到contenteditable div的结尾

xxhby3vn  于 2023-01-06  发布在  其他
关注(0)|答案(5)|浏览(277)

我正在创建我自己的聊天应用程序,其中我使用了内容可编辑的div作为聊天框。我正在实现提及功能,其中我的提及是用户名 Package 在一个span标签中,后跟一个空格( ),但我的问题是,当我删除空格时,我的光标移动到div的末尾。
有间隔

<html>

<head>
</head>

<body>
  <div contenteditable=true><span contenteditable='false'>UserName</span>&nbsp;</div>
</body>

</html>

无空位

<html>

<head>
</head>

<body>
  <div contenteditable=true><span contenteditable='false'>UserName</span></div>
</body>

</html>

这就是我如何在代码中实现的,而且这个bug只发生在chrome中。

7gyucuyw

7gyucuyw1#

这实际上是 * 浏览器中的一个bug *,我有一个变通方法,但我不知道它会对您有多大帮助,但这是我们目前所能做的最好的。

div>span {
   display:inline-block;
}
<div contenteditable="true"><span contenteditable="true"><span contenteditable="false">UserName</span></span>&nbsp;</div>

没有空间
一个二个一个一个
如果您希望有***完整校样内容***,下面是script结合: before伪内容的解决方案:
这里我取了: before伪元素的宽度,并将其阴影化到div元素padding-left上。我使用脚本时牢记了动态用户名。

var testBox = document.querySelector('.test'),
  pseudoBeforeWidth = window.getComputedStyle(testBox, ':before').width, //getting the width of the parent elemnts `:before`
  pseudoBeforeContent = window.getComputedStyle(testBox, ':before').content;

testBox.style.paddingLeft = pseudoBeforeWidth; //handing the width to the parent elemnts padding left style
var i = 0
var n = 0;
testBox.addEventListener('keydown', function(event) {
  const key = event.key; // const {key} = event; ES6+
  if ((key === "Backspace" || key === "Delete") && n == 0) {
    i++
    console.log(testBox.textContent, i, n);
    if (testBox.textContent == "" && i >= 2) {
      testBox.className += ' userhide ';
      testBox.style.paddingLeft = 0;
      n = 1;
    }
  }
});
div:before {
  content: attr(data-user);
  display: inline-block;
  position: absolute;
  left: 5px;
}

.test.userhide:before {
  display: none;
}
<div class="test" contenteditable="true" data-user="UserName"></div>

希望这对你有帮助。

bis0qfac

bis0qfac2#

分析

想象一个简单的文本编辑器(记事本),您在其中键入了三个字符-TRY
现在,很明显,光标只能放在这里的4个地方,它们是:

  • T之前
  • 在T和R之间
  • 在R和Y之间
  • Y之后

原因很简单,因为这3个字符是此处仅有的可编辑的字符,并且它们是3个单独的实体,无法进一步编辑/分隔。例如,我们无法将光标放在字母"T"之间并将与它分隔开。
您的场景也是如此,因为&nbsp;被清除后,光标会移动到div的末尾,因为contenteditable=true被设置为<div>,而false被设置为<span>。因此,div是此处唯一可编辑的元素,而span不是。因此,光标只能将自己定位在可编辑位置,即位于可编辑元素的开头(在本例中为div)或结尾,并且在两者之间为而不是
由于div是一个块元素,当块元素占据其父元素的整个宽度时,光标移动到页面的末尾。如果将width: 50%;设置为div,我们可以看到光标移动到页面的中间。
溶液
考虑到您对其他答案的评论,您需要保持宽度为100%,解决方案是用另一个也具有属性contenteditable=truediv Package div,并将子div保持为inline-block元素。

<div contenteditable=true>
  <div class="inl-blck" contenteditable=true><span contenteditable='false'>UserName</span>&nbsp;</div>
</div>

CODEPEN

解释

这里,div的父元素和子元素都是可编辑的,父元素占全角(100%),子元素是inline-block元素,只占其内容的空间,因此,一旦&nbsp;被清除,光标就会移动到下一个可编辑内容的末尾,即子元素div
请注意,您需要将子divspan以及&nbsp;保留在代码中的同一行中,否则将在部分中创建额外的字符(空格),这将进一步破坏contenteditable
希望这个有用。

oxalkeyp

oxalkeyp3#

这可以帮助您

<div contenteditable=true style="display: inline-block;background: #000;color:#fff;"><span contenteditable=false>UserName</span>&nbsp;</div>
vjrehmav

vjrehmav4#

信不信由你,这个bug与实际HTML标记本身中的空格有关。
下面是一个工作示例:

.username {
    margin-left: 10px;
}
<div contenteditable="true">
  <span contenteditable="false" class="username">Username</span>
</div>

通过简单地将结束div移到下一行,我们就可以将break传递给html解析器。

alen0pnh

alen0pnh5#

一个简单的修复方法是在contenteditable块中添加<br>

<body>
  <div contenteditable=true><span contenteditable='false'>UserName</span>&nbsp;<br></div>
</body>

相关问题