Javascript 如何在contenteditable元素中粘贴多行文本,使每行始终位于其自己的div中?

Javascript 如何在contenteditable元素中粘贴多行文本,使每行始终位于其自己的div中?,javascript,html,contenteditable,Javascript,Html,Contenteditable,运行代码,将任意两行纯文本复制并粘贴到框中。它将以我想要的方式粘贴,每一行都有自己的div 现在删除所有内容并按enter键创建一个空div,然后将文本粘贴到该div中。将看到不需要的行为 有更多不一致行为的例子。 例如,删除所有内容并再次粘贴文本。现在,选择全部并粘贴到所选内容上。它会表现得像我想要的那样。现在,按enter键在两个现有div下面创建一个新div,选择所有文本并再次粘贴。将看到不需要的行为 有些问题似乎与生成的break标记有关。我试着解决这个问题,但一次修复会破坏其他东西

运行代码,将任意两行纯文本复制并粘贴到框中。它将以我想要的方式粘贴,每一行都有自己的div

现在删除所有内容并按enter键创建一个空div,然后将文本粘贴到该div中。将看到不需要的行为

有更多不一致行为的例子。 例如,删除所有内容并再次粘贴文本。现在,选择全部并粘贴到所选内容上。它会表现得像我想要的那样。现在,按enter键在两个现有div下面创建一个新div,选择所有文本并再次粘贴。将看到不需要的行为

有些问题似乎与生成的break标记有关。我试着解决这个问题,但一次修复会破坏其他东西

.text\u区域{
宽度:200px;
高度:100px;
边框:1px实心;
填充物:2em 2em 2em 3em;
溢出:自动;
}
.text_区域>div{
边框:1px实心浅灰色;
保证金:0.33em0;
最小高度:1.2米;
}

如果您总是希望每一行都位于
div
中,则必须确保内容始终有一个
div

使用内部
div
初始化contenteditable元素以开始。这确保了当用户单击时,他们已经处于正确的环境中

在“输入”上使用带有事件侦听器的JavaScript,您可以测试contenteditable元素是否变为空。您必须记住,该区域中的

将被视为非空。这就是导致您的enter问题的原因。在
之前有一个

。如果contenteditable区域的innerHTML不包括

和多余的空白,则需要将该
div
追加回contenteditable区域的子项

最后,在复制和粘贴时,您得到了
div
嵌套。这是因为在contenteditable区域中粘贴的默认行为是使用HTML格式。因此,如果您复制
ab
并将其粘贴到
中,您将得到嵌套。您可以通过只从剪贴板获取“文本/纯文本”来避免这种情况

//确保将文本复制为纯文本而不是HTML(修复嵌套Divs问题)
document.querySelector(“[contenteditable]”)。addEventListener('paste',(事件)=>{
event.preventDefault();
document.execCommand('inserttext',false,event.clipboardData.getData('text/plain');
});
document.querySelector(“[contenteditable]”)。addEventListener('input',(event)=>{
//删除所有BR
如果(event.target.childNodes.length>0){
for(让br代替event.target.querySelectorAll('br')){
br.删除();
}
}
//如果删除BRs后DIV变为空
if(event.target.innerHTML.trim().length==0){
//重新填充初始DIV
event.target.innerHTML='';
event.target.appendChild(document.createElement('div');
}
});
.text\u区域{
宽度:200px;
高度:100px;
边框:1px实心;
填充物:2em 2em 2em 3em;
溢出:自动;
}
.text_区域>div{
边框:1px实心浅灰色;
保证金:0.33em0;
最小高度:1.2米;
}


就快到了。尝试以下操作:在默认子项
div
中键入一个字符,然后按
backspace
两次。再次输入一个字符,然后按一次
backspace
。在第一个子
div
之前创建
br
,光标进入
文本区域本身,而不是子
div
。好的。在输入事件触发和追加新子级之间有一些延迟,这允许在div出现之前进行一些键入。在追加子项以处理此情况之前,我添加了一行以清空div。如果按backspace键,然后输入单个字符,然后选择all,按enter键,则顶部会再次出现一个
字符。我想我已经在代码的底部解决了这个问题:
if(event.target.firstElementChild?.localName==“br”){event.target.firstElementChild.remove();}
或者我可以在您的代码之后执行此操作:
[…event.target.querySelectorAll('br')].forEach(br=>br.remove());log(event.target.outerHTML)你觉得怎么样?这似乎很有效。更新为包含
br
删除,并修复第二个条件,即不再使用字符串替换

,因为这是单独处理的。我做了一点小小的修改。因为您希望每一行都在它自己的div中。
br
不应出现在可编辑区域中。因为所有东西都在它自己的分区中,所以需要定义一些新选项。但是,使用选择和范围来解决这个特殊的问题会非常繁琐,因为如果您希望带换行符的文本显示在单独的div中,而不是折叠成单个div,则必须自己处理和放置每个元素。