首页 > 解决方案 > 如何在输入时连续加粗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 生成的代码。我需要相同的功能...

标签: javascripthtmlcss

解决方案


为了在您选择“粗体”时使文本变为粗体,请从当前选择中获取范围并在其中插入元素“强”。

  let range=window.getSelection.getRangeAt(0);
  let elem=document.createElement('strong');
  elem.innerHTML='&#8203;'
  range.insertNode(elem);

这将使文本变为粗体,同样适用于斜体选项。现在问题来了,当您需要禁用它时,我必须清除当前选择范围并将范围设置为“div”的末尾并插入新元素“span”(我将 span 用于普通文本)。

同样,我也处理了以下情况

  1. 当粗体和斜体同时按下时(在这种情况下,您需要存储先前的元素)
  2. 当按下回车时(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='&#8203;'
  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='&#8203;'
 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>


推荐阅读