javascript - 在 contenteditable div 中创建一个具有随机名称的新段落
问题描述
每次有人单击该Enter
键时,我都想添加一个随机名称。例如:如果有人按下 Enter 键,它应该创建一个段落块,其名称与 Medium.com文本编辑器相同。
但像往常一样 contenteditable div 只是在Enter
按下键时复制前一个元素。但我不想复制元素。我想创建一个具有唯一名称的新块。
.root {
border: 1px solid #212121;
}
<div class="root" contenteditable>
<p name="kLdnD" class="block">Block with random name</p>
<p name="uIDlf" class="block">Second block</p>
</div>
解决方案
以下代码依赖于浏览器在新行上复制可编辑 div 的最后一个子元素的事实。在 key down 时,我们处理还没有子元素的情况,我们确保第一个元素是一个段落,让浏览器自动创建更多段落。
为了设置新创建段落的 id 和名称,我们使用突变观察者 API 在添加段落时获得通知。
另一个特点是如果第一次击键是 Enter,我们添加的第二段。我们需要这个,因为浏览器显示一个空 div 和一个带有一个空段落的 div 相同。
<html>
<head>
<script>
function loaded()
{
// https://stackoverflow.com/questions/105034/how-to-create-guid-uuid
function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
const zzz = document.getElementById("zzz");
zzz.onkeydown = function(e)
{
if(!zzz.children.length)
{
let element = document.createElement("p");
element.innerHTML = "<br />";
zzz.appendChild(element);
if(e.code == "Enter")
{
element = document.createElement("p");
element.innerHTML = "<br />";
zzz.appendChild(element);
}
window.getSelection().collapse(element, 0);
e.preventDefault();
}
}
const observer = new MutationObserver(function(mutationList, observer)
{
for(let ilength = mutationList.length, i = 0; i < ilength; ++i)
{
const addedNodes = mutationList[i].addedNodes;
for(let jlength = addedNodes.length, j = 0; j < jlength; ++j)
{
const node = addedNodes[j];
const randomNumber = uuidv4();
node.id = "pid" + randomNumber;
node.setAttribute("name", "pn" + randomNumber);
}
}
});
observer.observe(zzz, { childList: true });
}
</script>
</head>
<body onload="javascript:loaded();">
<div id="zzz" contenteditable="true"></div>
</body>
</html>
推荐阅读
- node.js - 模拟使用 sequelize-auto 包创建的自动生成的模型函数
- c - int a = (2, 3, 4, 5); & int a = {2, 3, 4, 5}; 这些语句在 C/C++ 中是如何工作的?
- java - 如何解决:“无法解决:com.github.GoodieBag:Pinview:v1.4”
- c - f = fopen("textfile","a") 的代码在另一个设备中为 f 返回 NULL,但在我的设备上运行完美
- google-apps-script - 为循环错误发送相同的多封电子邮件而不是 1 封电子邮件
- laravel - 在 Laravel8 中的每个 URL/路由上获取相同的页面
- automated-tests - 有没有办法将多个环境变量输入到 URL 中以在 Postman 上进行测试?
- reactjs - 警报自动消失功能
- scala - Akka http 传出连接卡住
- solidity - 仅通过 API 允许 NFT 铸造