【问题标题】:Bold/Italic/Underline User Text Input粗体/斜体/下划线用户文本输入
【发布时间】:2020-08-14 01:18:26
【问题描述】:

我有一个文本输入,我使用 DOM 来获取文本,我显示文本。问题是我希望用户能够加粗/斜体/下划线某些单词或部分文本。我正在考虑让用户在文本周围写粗体/斜体/下划线,搜索这个词的索引,并使用 javascript 应用更改。我已经可以完成前两个步骤,但我不知道如何应用更改。
我正在寻找使用 document.createElement("B"); 的 JavaScript 将文本变为粗体的方法,但使用这种方法很复杂,因为它只是特定的单词或句子。

var bold = {}; var bld = 0;
var str = 'string BOLD of BOLD the ITALIC input text ITALIC that i UNDERLINE get UNDERLINE using dom';
var show = document.createElement("P");
//Here I use .includes() and .matchAll() to get an array with all the indexes
var regexp = new RegExp("BOLD","g");
let arraybold = [...str.matchAll(regexp)].map(a => a.index);
//ex: arraybold[0] = 7 and arraybold[1] = 15. 
for(key in arraybold) {
    bld = bld + 1;
}
regexp = new RegExp("ITALIC","g");
let arrayitalic = [...str.matchAll(regexp)].map(a => a.index);
regexp = new RegExp("UNDERLINE","g");
let arrayunderline = [...str.matchAll(regexp)].map(a => a.index);
//Here I'm suppose to create the bold/italic/underline tags on the specific words. 
for(i = 1; i <= (bld/2); i++) {
var bold[i] = document.createElement("B");
bold[i].innerText = str.slice(arraybold[i]+4, arraybold[i+1]);
//str.replace(the part of the text with the bold tag that i create);
}
show.innerText = str;
document.body.appendChild(show);

Ps:我不能使用innerHTML,因为我稍后会使用dom。我更喜欢用香草 javascript 来做这件事。 预期结果:

//<p>string <strong> of </strong> the <i> input text </i> that i <u> get</u> using dom</p>

编辑:@cpprookie 建议使用 let 代替 var

【问题讨论】:

  • 您必须使用contenteditable 部分。
  • @DanielA.White 我研究了 contenteditable,这是一个很酷的功能,但我不明白这如何解决我的问题,我希望用户能够将文本变为粗体/斜体/下划线和将此信息发送给我以便稍后显示。
  • 可能是某种类型的降价插件?这样,如果有些东西用斜体,它会显示如下:*My italic text*
  • 在我的项目中,我们使用 CKEditor |智能所见即所得 HTML 编辑器 |协作丰富... (ckeditor.com) 允许用户输入具有不同格式属性的文本,例如您所描述的。

标签: javascript dom user-input


【解决方案1】:

尝试拆分字符串并用结构类似于{ text: 'string', type: 'noStyle/BOLD/ITALIC/UNDERLINE' }的数据填充数组,最后根据类型字段生成节点。

  • 首先拆分并遍历整个字符串。根据对应的关键字(BOLD/ITALIC/UNDERLINE)填充textList;
var textList = [];
var boldText = '';
var italicText = '';
var underlineText = '';
var markAsBold = false;
var markAsItalic = false;
var markAsUnderline = false;

var str = 'string BOLD of BOLD the ITALIC input text ITALIC that i UNDERLINE get UNDERLINE using dom';

str.split(' ').forEach(s => {
  if (s === 'BOLD') {
     // match left BOLD
     if (!markAsBold) {
        markAsBold = true;
     } else {
        // match right BOLD and clear boldText;
       textList.push({
         text: boldText,
         style: 'BOLD'
       });
       boldText = '';
       markAsBold = false;
     } else if (s === 'ITALIC') {
        // same as 'BOLD' process
     } else if (s === 'UNDERLINE') {
        // same as 'BOLD' process
     } else {
        if (markAsBold) {
            boldText += boldText.length > 0 ? s : (' ' + s);
        } else if (markAsItalic) {
            italicText += italicText.length > 0 ? s : (' ' + s);
        } else if (markAsUnderline) {
            underlineText += underlineText.length > 0 ? s : (' ' + s);
        } else {
            textList.push({
                text: s,
                style: 'noStyle'
            })
        }
     }
  }
})
  • 根据 textList 中的类型创建节点。
  textList.forEach(item => {
    let node;
    if (item.style === 'noStyle') {
      // create a span node
    } else if (item.style === 'BOLD') {
      // create a bold node
    } else if (item.style === 'ITALIC') {
      // create a italic node
    } else {
      // create a node and underline it with css.
    }
    // Append to parentNode at last.
  })

【讨论】:

  • 我没有考虑过创建跨度节点。尽管为每个纯文本创建跨度似乎有些夸张,但这可能是唯一的解决方案。谢谢。
  • @SarahY。别客气!如果您不能使用 innerHtml,看起来没有更好的解决方案。顺便说一句,如果你可以使用Array.prototype.matchAll 和扩展运算符,为什么不使用letconst 来避免命名空间污染?
猜你喜欢
  • 2020-01-25
  • 1970-01-01
  • 1970-01-01
  • 2010-11-25
  • 2011-05-23
  • 2020-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多