javascript - 如何在输入时连续加粗div中的文本
问题描述
我有一个待办事项应用程序,我被要求添加更多功能,例如:为粗体和斜体文本添加一些按钮。在输入中,在我按下粗体按钮后,将要输入的文本以粗体显示,而将之前的文本(我按下粗体按钮之前的文本)保持原样,常规。我知道没有办法在输入中加粗一段文本,所以我用 div 模拟了一个输入:
const div = document.querySelector('div');
div.innerHTML = '';
const bold = document.getElementById('boldBtn');
const italic = document.getElementById('italicBtn')
bold.style.backgroundColor = 'white';
let previousText = '';
let boldString = '';
boldBtn.addEventListener('click', () => {
boldBtn.classList.toggle('bold-selected');
if (boldBtn.classList.contains('bold-selected')) {
boldBtn.style.backgroundColor = "gray";
previousText = div.innerHTML;
console.log(previousText)
div.addEventListener('keydown', boldText)
}
else {
bold.style.backgroundColor = "white";
div.removeEventListener('keydown', boldText);
}
})
function boldText(e) {
div.innerHTML = div.innerHTML.substr(1)
console.log("Previous text: " + previousText);
const NOT_ALLOWED = ['Backspace', 'Shift', 'Control', 'Alt'];
if (!NOT_ALLOWED.includes(e.key)) {
boldString += e.key;
console.log("Bold text: " + boldString)
console.log(previousText + boldString)
div.innerHTML = previousText + "<strong>" + boldString + "</strong>"
}
}
div {
border: 1px solid black;
width: 200px;
height: 20px;
}
.font-style {
border: 1px solid blue
}
<div contenteditable="true"></div>
<button id="boldBtn" class="font-style">Bold</button>
<button id="italicBtn" class="font-style">Italic</button>
尝试在 div 中写“酷”之类的内容,然后按粗体按钮,然后键入一个字母。你会看到 div 得到了这个 innerHTML:letter+cool+boldletter。并且光标设置在 div 内容的开头。请帮助我或至少给出一个提示来完成想要的行为!我已经花了3-4个小时,我准备放弃了......
编辑:我想我没有说清楚:我不想让 div 的全部内容变粗,而只是它的一部分/部分/部分。如果没有按下按钮,要写的文字应该是规则的,如果按下粗体按钮,要写的文字应该是粗体,与斜体按钮相同。也许如果同时选择粗体和斜体,未来的文本应该是粗体和斜体。但这是另一个问题......我想要的一个例子是https://html-online.com/editor/。删除默认文本,只在左侧面板上写字,并尝试使用上面的粗体、斜体按钮。在左侧面板中将有 HTML 生成的代码。我需要相同的功能...
解决方案
为了在您选择“粗体”时使文本变为粗体,请从当前选择中获取范围并在其中插入元素“强”。
let range=window.getSelection.getRangeAt(0);
let elem=document.createElement('strong');
elem.innerHTML='​'
range.insertNode(elem);
这将使文本变为粗体,同样适用于斜体选项。现在问题来了,当您需要禁用它时,我必须清除当前选择范围并将范围设置为“div”的末尾并插入新元素“span”(我将 span 用于普通文本)。
同样,我也处理了以下情况
- 当粗体和斜体同时按下时(在这种情况下,您需要存储先前的元素)
- 当按下回车时(div被创建并产生问题,所以我不得不设置keydown监听器并使用document.execCommand不创建div而是创建br)
如果有人有兴趣更新我的解决方案以使其有效,欢迎您
var boldButton=document.querySelector('#boldBtn'),
italicButton=document.querySelector('#italicBtn'),
contentDiv=document.querySelector('#content'),
bold=false,italic=false,range,prevElement,selection;
;
contentDiv.addEventListener('keydown',function(e){
if (e.keyCode === 13) {
window.document.execCommand('insertLineBreak', false, null);
range=window.getSelection().getRangeAt(0);
range.collapse();
prevElement=undefined;
if(bold) addElement('strong');
if(italic) addElement('i');
e.preventDefault();
return false;
}
return true;
});
boldButton.addEventListener('click',function(){
debugger
bold=!bold;
boldButton.classList.toggle('border-black');
if(!bold)
disable('bold');
else
addElement('strong');
});
italicButton.addEventListener('click',function(){
debugger;
italic=!italic;
italicButton.classList.toggle('border-black');
if(!italic)
disable('italic');
else
addElement('i');
});
function addElement(element){
if(!selection)selection=window.getSelection()
range=selection.getRangeAt(0);
let elem=document.createElement(element);
elem.innerHTML='​'
if(prevElement)
range.selectNodeContents(prevElement);
range.collapse();
range.insertNode(elem);
elem.focus();
prevElement=elem;
}
function disable(elem){
if(italic && bold) return;
setRangeAtEnd();
let element=document.createElement('span');
if(italic)
element=document.createElement('i');
else if(bold)
element=document.createElement('strong');
element.innerHTML='​'
range.insertNode(element);
range.setStart(element,1);
element.focus();
}
function setRangeAtEnd(){
let childNodes=contentDiv.childNodes;
range=document.createRange();
range.setStartAfter(childNodes[childNodes.length-1]);
prevElement=undefined;
if(!selection)selection=window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
}
#content{
border:1px solid black;
height:150px;
}
.border-black{
border:2px dotted black;
}
<div id="content" contenteditable="true"></div><br>
<button id="boldBtn" class="font-style">Bold</button>
<button id="italicBtn" class="font-style">Italic</button>
推荐阅读
- java - Benefits of internal iterations
- c - How to print result in order even if using threads in c?
- javascript - 局部变量在 eventBus.emit 之后更新
- excel - How to fix Range of object failed while using autofilter
- excel - value and matche in rows
- java - 如何使用流从实际数组列表中获取子列表
- sorting - 在 go 1.2 中按时间日期字段对结构切片进行排序,而不创建二级结构
- python - 在 shutil.copy 中禁用 SameFileError 异常
- git - git显示.pack中所有已删除的文件以及如何有选择地删除文件?
- java - Maven 版本未在 Eclipse 终端中正确返回