如何在Quill(富文本编辑器)中检测和修剪前导/后缀空白? [英] How to detect and trim leading/trailing whitespace in Quill (rich text editor)?

查看:49
本文介绍了如何在Quill(富文本编辑器)中检测和修剪前导/后缀空白?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在富文本编辑器 Quill 中检测和删除前导/后缀空白?

例如,下面的示例 HTML 表示文本"\ nHi" Quill 输出.

我们要检测并删除 Quill 创建的每个文本块的前导和尾随空格(而不是整个文档).基本上,为每个嵌入式 Quill 编辑器修剪前导/后缀空格.(我们在同一页面中嵌入了多个编辑器.)

API 似乎没有提供一种简单的方法来实现这一目标,并且需要进行一些黑客操作?

是否有一种优雅的方法可以有效地用 Quill 修剪文本?

 < div class =" ql-editor"data-gramm ="false"contenteditable ="true"spellcheck ="false";autocomplete =关闭";autocorrect =关闭";autocapitalize ="off">< p style ="align-self:center;">< br></p>< p style ="align-self:center;">< span style =" font-family:Lato;颜色:rgb(0,0,0);font-size:80px;行高:1.5;字母间距:0em;字体粗细:400;字体样式:正常;" Hi& nbsp;</span></p></div> 

解决方案

Quill使用 Delta 类来描述富文本格式,我们可以使用Quill getContents 方法来获取所有内容条目,这些条目将采用以下格式:

  Delta {操作:插入:↵↵↵Hello↵world!↵↵"]} 

我们必须使用循环遍历所有这些条目来创建逻辑,检测并消除开头和结尾的换行符.

我们使用两个数组,一个数组将存储新的增量条目,另一个数组用于存储可能会或可能不会附加到新的增量条目数组的未完成的换行符.我们还将有一个标志,指示我们是否已修复了引行换行.

此解决方案使用此方法处理模糊事件" 来检测模糊事件.

Quill模糊代码和代码段(运行以查看实际效果):

请阅读内嵌评论

 让羽毛笔= [];[... document.getElementsByClassName('quill-editor')].forEach((el,idx)=> {const quill = new Quill(el,{模块:{工具栏:[[{标头:[1、2,假]}],[粗体",斜体",下划线"],['image','code-block']]},占位符:撰写史诗...",主题:"snow"//或"bubble"});quill.on('selection-change',function(range,oldRange,source){if(range === null&& oldRange!== null){const delta = quill.getContents();让leadFixed = false;让newDelta = [];让tempDelta = [];if(delta.ops.length === 1){//如果只有一个条目,请检查它是否为字符串并修剪LF的开头和结尾让{插入,属性} = delta.ops [0];if(typeof(insert)==='字符串'){insert = insert.replace(/^ \ n + | \ n + $/g,'');}newDelta = [{insert,attribute}];} 别的 {//其他所有插入项delta.ops.forEach(({{insert,attribute},idx)=> {//创建一个布尔值以指示我们是否在最后一个条目const isLast = idx === delta.ops.length-1;//如果条目是字符串(不是图像/资产)if(typeof(insert)==='字符串'){//如果我们还没有解决领导问题if(!leaderFixed){//如果条目以LF开头if(/^ \ n +/.test(insert)){//使用干净的前导LF创建一个字符串让cleanText = insert.replace(/^ \ n +/,``);//清除LF后是否有文字if(cleanText.length> 0){//将文本添加到newDeltanewDelta.push({插入:cleanText,属性});//设置前导标志以指示我们已修复前导LeadingFixed = true;}//否则,如果条目不是以LF开头} 别的 {//如果条目不是以LF开头//将tempDelta中可能存在的所有未决条目添加到newDeltanewDelta = newDelta.concat(tempDelta);//添加现有条目newDelta.push({插,属性});//清除所有待处理的条目tempDelta = [];//并设置前导标志以指示我们已修复前导LeadingFixed = true;}//否则,如果我们已经固定了领先} 别的 {//如果有一个带有结尾LF的条目if(/\ n + $/.test(insert)){//使用干净的结尾LF创建一个字符串让cleanText = insert.replace(/\ n + $/,``);//如果这是最后一个条目if(isLast){//清除LF后是否有文字if(cleanText.length> 0){//将tempDelta中可能存在的所有未决条目添加到newDeltanewDelta = newDelta.concat(tempDelta);//添加已清除的条目newDelta.push({插入:cleanText,属性});}//否则(如果不是最后一个条目)} 别的 {//清除LF后是否有文字if(cleanText.length> 0){//将tempDelta中可能存在的所有未决条目添加到newDeltanewDelta = newDelta.concat(tempDelta);//添加现有条目newDelta.push({插,属性});//清除所有待处理的条目tempDelta = [];//否则在清除LF后如果没有文本} 别的 {//将条目添加到temp delta中,以便以后需要时使用它们tempDelta.push({插入,属性});}}//否则,如果条目不以LF结尾} 别的 {//将tempDelta中可能存在的所有未决条目添加到newDeltanewDelta = newDelta.concat(tempDelta);//添加现有条目newDelta.push({插,属性});//清除所有待处理的条目tempDelta = [];}}//如果条目不是字符串} 别的 {//然后清除所有前导文本/换行符(如果有的话)//因此,设置前导标志是安全的LeadingFixed = true;//将tempDelta中可能存在的所有未决条目添加到newDeltanewDelta = newDelta.concat(tempDelta);//添加现有条目newDelta.push({插,属性})//清除所有待处理的条目tempDelta = [];}});}quill.setContents(newDelta);}/*否则,如果(range!== null&& oldRange === null){console.log('focus');} */});quills.push(羽毛笔);});  

  .editors {显示:flex;}.quill-editor-container {flex:1;}.quill-editor {高度:100px!}  

 < script src ="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.core.js完整性=" sha256-jvauzib5XGeoiDyHV6mlZnpuKsEAcjhruilbo0e + L6k ="crossorigin =" anonymous</script>< script src ="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.js"完整性="sha256-CN8TogJAzCcMj0uYishm9mmawPUFKJeJh//zR/CfCO8 =" crossorigin ="anonymous"></script>< link rel ="stylesheet" href ="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.core.css"完整性="sha256-2kIq + 5smyR4blGwdXXCCVrPLENwavLyrG8 + kLPfDPJk =" crossorigin=匿名"/>< link rel ="stylesheet" href ="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.bubble.css"完整性="sha256-2hxHujXw890GumwDHPWrwJCtdZZdrJanlGsrOTSfXnc =" crossorigin ="anonymous"/>< link rel ="stylesheet" href ="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.snow.css"完整性="sha256-jyIuRMWD + rz7LdpWfybO8U6DA65JCVkjgrt31FFsnAE =" crossorigin =匿名"/>< div class ="editors">< div class ="quill-editor-container">< div class ="quill-editor"></div></div>< div class ="quill-editor-container">< div class ="quill-editor"></div></div></div>  

我已经用图像资源和格式对其进行了测试,并且看起来效果很好.当然,可以进一步优化甚至简化代码.

如果您还可以检查 Stackblitz项目想分叉并进行一些测试.

How can you detect and delete leading/trailing whitespace in Quill, which is a rich text editor?

For instance, the sample HTML below represents Quill output for the text "\nHi".

We want to detect and delete leading and trailing whitespace for each block of the text created by Quill (not for an entire document). Basically, trim leading/trailing whitespace for each embedded Quill editor. (We embed multiple editors within the same page.)

The API doesn't seem to offer a simple way to achieve this and would require some hacking?

Is there an elegant way to trim text with Quill effectively?

<div class="ql-editor" 
     data-gramm="false" 
     contenteditable="true" 
     spellcheck="false" 
     autocomplete="off" 
     autocorrect="off" 
     autocapitalize="off">
   <p style="align-self: center;">
       <br>
   </p>
   <p style="align-self: center;">
        <span style="font-family: Lato; color: rgb(0, 0, 0); font-size: 80px; line-height: 1.5; letter-spacing: 0em; font-weight: 400; font-style: normal;">Hi&nbsp;</span>
     </p>
</div>

解决方案

Quill uses the Delta class to describe the rich text format and we can use Quill getContents method to get all content entries which will be in the following format:

Delta {
  ops: [
    insert: "↵↵↵Hello↵world!↵↵"
  ]
}

We have to create a logic using a loop through all these entries, detect and eliminate leading and ending line feeds.

We use two arrays, one array that we'll store the new delta entries and one for storing the pending ending line feeds that we may or may not append to the new delta entries array. We'll also have a flag indicating whether we've fixed the leading line feeds.

This solution uses this method "handling blur event" to detect the blur event.

Quill blur code and snippet (run to see it in action):

Please read inline comments

let quills = [];

[...document.getElementsByClassName('quill-editor')].forEach((el, idx) => {
  const quill = new Quill(el, {
    modules: {
      toolbar: [
        [{ header: [1, 2, false] }],
        ['bold', 'italic', 'underline'],
        ['image', 'code-block']
      ]
    },
    placeholder: 'Compose an epic...',
    theme: 'snow'  // or 'bubble'
  });

  quill.on('selection-change', function(range, oldRange, source) {
    if (range === null && oldRange !== null) {
      const delta = quill.getContents();

      let leadingFixed = false;
      let newDelta = [];
      let tempDelta = [];

      if(delta.ops.length === 1) {
        // If there is only one entry, check if it's a string and trim leading and ending LF
        let { insert, attributes } = delta.ops[0];
        if(typeof(insert) === 'string') {
          insert = insert.replace(/^\n+|\n+$/g, '');
        }
        newDelta = [{ insert, attributes }];
      } else {
        // Else go through all the insert entries
        delta.ops.forEach(({ insert, attributes }, idx) => {
          // Create a boolean to indicate if we're at the last entry
          const isLast = idx === delta.ops.length - 1;

          // If the entry is a string (not image/asset)
          if(typeof(insert) === 'string') {
            // If we haven't fixed the leading
            if(!leadingFixed) {
              // If the entry begins with LFs
              if(/^\n+/.test(insert)) {
                // Create a string witrh clean leading LFs
                let cleanText = insert.replace(/^\n+/, '');

                // If there is text after cleaning the LFs
                if(cleanText.length > 0) {
                  // Add the text to the newDelta
                  newDelta.push({
                    insert: cleanText,
                    attributes
                  });
                  // Set leading flag to indicate we've fixed the leading
                  leadingFixed = true;
                }
              // Else if the entry does not start with LFs
              } else {
                // If the entry does not begin with LFs
                // Add any pending entries that may exists in tempDelta to the newDelta
                newDelta = newDelta.concat(tempDelta);
                // Add the existing entry
                newDelta.push({
                  insert,
                  attributes
                });
                // Clean the any pending entries
                tempDelta = [];
                // And set the leading flag to indicate we've fixed the leading
                leadingFixed = true;
              }
            // Else if we have fixed the leading
            } else {
              // If there an entry with ending LFs
              if(/\n+$/.test(insert)) {
                // Create a string witrh clean ending LFs
                let cleanText = insert.replace(/\n+$/, '');

                // If this is the last entry
                if(isLast) {
                  // If there is text after cleaning the LFs
                  if(cleanText.length > 0) {
                    // Add any pending entries that may exists in tempDelta to the newDelta
                    newDelta = newDelta.concat(tempDelta);
                    // Add the cleaned entry
                    newDelta.push({
                      insert: cleanText,
                      attributes
                    });
                  }
                // Else if this is not the last entry
                } else {
                  // If there is text after cleaning the LFs
                  if(cleanText.length > 0) {
                    // Add any pending entries that may exists in tempDelta to the newDelta
                    newDelta = newDelta.concat(tempDelta);
                    // Add the existing entry
                    newDelta.push({
                      insert,
                      attributes
                    });
                    // Clean the any pending entries
                    tempDelta = [];
                  // Else if there is no text after cleaning the LFs
                  } else {
                    // Add the entry to the temp deltas so to use them later if its needed
                    tempDelta.push({ insert, attributes });
                  }
                }
              // Else if the entry does not end with LFs
              } else {
                // Add any pending entries that may exists in tempDelta to the newDelta
                newDelta = newDelta.concat(tempDelta);
                // Add the existing entry
                newDelta.push({
                  insert,
                  attributes
                });
                // Clean the any pending entries
                tempDelta = [];
              }
            }
          // If the entry is not a string
          } else {
            // Then all leading text/line feeds have been cleared if there were any
            // so, it's safe to set the leading flag
            leadingFixed = true;
            // Add any pending entries that may exists in tempDelta to the newDelta
            newDelta = newDelta.concat(tempDelta);
            // Add the existing entry
            newDelta.push({
              insert,
              attributes
            })
            // Clean the any pending entries
            tempDelta = [];
          }
        });
      }

      quill.setContents(newDelta);
    } /*else if (range !== null && oldRange === null) {
      console.log('focus');
    }*/
  });

  quills.push(quill);
});

.editors {
  display: flex;
}

.quill-editor-container {
  flex: 1;
}
.quill-editor {
  height: 100px !important;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.core.js" integrity="sha256-jvauzib5XGeoiDyHV6mlZnpuKsEAcjhruilbo0e+L6k=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.js" integrity="sha256-CN8TogJAzCcMj0uYishm9mmawPUFKJeJh//zR/CfCO8=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.core.css" integrity="sha256-2kIq+5smyR4blGwdXXCCVrPLENwavLyrG8+kLPfDPJk=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.bubble.css" integrity="sha256-2hxHujXw890GumwDHPWrwJCtdZZdrJanlGsrOTSfXnc=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.snow.css" integrity="sha256-jyIuRMWD+rz7LdpWfybO8U6DA65JCVkjgrt31FFsnAE=" crossorigin="anonymous" />

<div class="editors">
  <div class="quill-editor-container"><div class="quill-editor"></div></div>
  <div class="quill-editor-container"><div class="quill-editor"></div></div>
</div>

I've tested it with image assets and formatting and it seems to work pretty well. Of course the code can be further optimized and maybe simplified.

You can also check this Stackblitz project if you wanna fork it and make some tests.

这篇关于如何在Quill(富文本编辑器)中检测和修剪前导/后缀空白?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆