在构建电子邮件模板编辑器时如何处理 tinyMCE 内联模式?

How do you handle tinyMCE inline mode while building an email template editor?

提问人:blogob 提问时间:3/18/2022 更新时间:3/19/2022 访问量:446

问:

我正在创建自己的电子邮件编辑器,我正在使用 tinyMCE。因此,在我的页面上,我有一个侧边栏,上面有一百个按钮(图像),对应于 html 块。当我单击一个按钮时,相应的代码被注入到带有 tinyMCE 的大型可编辑文本区域中。所以我有一个大块,看起来像你在这里看到的:(这个是用 ckeditor 制作的,但我有类似的东西)。

理想情况下,我想要的是看起来像这里可见的“内联”演示的东西:

所以我有几个问题:

我可以在没有所有按钮的情况下将所有块插入到样式化的 div 中吗 等等,并只让块本身可编辑?

我在这里读到内联模式在 td 上不起作用,因此有必要创建 div 并瞄准 id 或类。

那些构建构建器电子邮件的人如何进行?所有电子邮件构建器(stripo、bee、mozaico、designmodo等)都使用内联编辑(ckEditor、专有解决方案或tinyMCE)。那么他们是否用div包围了js中注入的每个html组件,然后在下载文件时将其删除?难道没有更简单的方法吗?我负担不起创建数百个微小的 MCE 实例的费用

如果有人在这方面有经验,我将不胜感激......谢谢

jQuery 电子邮件 模板 tinymce

评论


答:

1赞 user18473608 3/18/2022 #1

您可以拥有多个具有相同类的 div。例如,我们有 4 个 div 具有 .email-editable 类。 所有 .email 可编辑元素都将具有相同的选项。当你想保存所有编辑器时,你需要调用 tinymce.editors 来获取 Tinymce 实例的数组,并为每个实例调用 save():

// create instances of Tinymce for each .email-editable element.
tinymce.init({
  selector: ".email-editable",
  inline: true,
  plugins: "advlist lists link image",
  toolbar: "styleselect | bold italic forecolor | bullist numlist | link image| removeformat",
  menubar: false
});

// this is the action for Click event
// this action will save all editors
document.getElementById('saveB').addEventListener('click', function(){
  // save all editors
  for (var i = 0; i < tinymce.editors.length; i++) {
    tinymce.editors[i].save();
}
  // show html on console
  let html = document.getElementById('email').innerHTML;
  console.log(html);
  // with Jquery:
  // console.log($('#email').html());
});
#email-header{
  margin-bottom: 10px;
  text-align: center;
  color: rgb(64,96,128);
  font-weight: bold;
  font-family: Arial, sans-serif;
  font-size: 30px;
}

#email-footer{
  margin-top: 10px;
  padding: 10px 0;
  color: white;
  background-color: gray;
  text-align: center;
  font-family: Arial, sans-serif;
}

.email-editable{
  font-family: Arial, sans-serif;
}

#saveB{
  margin-top: 30px;
  padding: 10px 0;
  width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.6.0/tinymce.min.js"></script>
<div id="email">
  <div id="email-header">Default header (this is not editable)</div>
  <div class="email-editable"><p>CUSTOM CONTENT 1. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris a mi libero. Morbi condimentum, <strong>ante non feugiat cursus, sapien ante laoreet turpis, fringilla finibus ante erat quis lorem</strong>. Donec cursus sem eget nunc faucibus semper.</p><ul><li>Item 1</li><li>Item 2</li></ul></div>
  <div class="email-editable"><p>CUSTOM CONTENT 2. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris a mi libero. Morbi condimentum, <strong>ante non feugiat cursus, sapien ante laoreet turpis, fringilla finibus ante erat quis lorem</strong>. Donec cursus sem eget nunc faucibus semper.</p></div>
  <div class="email-editable"><p>CUSTOM CONTENT 3. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris a mi libero. Morbi condimentum, <strong>ante non feugiat cursus, sapien ante laoreet turpis, fringilla finibus ante erat quis lorem</strong>. Donec cursus sem eget nunc faucibus semper.</p></div>
  <div class="email-editable"><p>CUSTOM CONTENT 4. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris a mi libero. Morbi condimentum, <strong>ante non feugiat cursus, sapien ante laoreet turpis, fringilla finibus ante erat quis lorem</strong>. Donec cursus sem eget nunc faucibus semper.</p></div>
  <div id="email-footer">2022 &copy; My Company (this is not editable)</div>
  
</div>
<button id="saveB" type="button">Save email</button>


更新的答案

使用 table 元素的新模板。当您单击“保存”按钮时,tbody 的每个 TD 元素都将包含内容(没有 DIV),但会丢失 TinyMCE 编辑器。

tinymce.init({
  selector: ".email-editable",
  inline: true,
  plugins: "advlist lists link image",
  toolbar: "styleselect | bold italic forecolor | bullist numlist | link image| removeformat",
  menubar: false
});


document.getElementById('saveB').addEventListener('click', function() {
  // obtain all TD elements where you edit the content
  let blocks = document.getElementById('email-body').getElementsByTagName('td');
  // change all inner HTML for each TD element.
  for (var i = 0; i < tinymce.editors.length; i++) {
    let content = tinymce.editors[i].getContent();
    blocks[i].innerHTML = content; // note that this will remove the TinyMCE editor
  }
  // show html on console
  let html = document.getElementById('email').innerHTML;
  console.log(html);
});
#email-header {
  margin-bottom: 10px;
  text-align: center;
  color: rgb(64, 96, 128);
  font-weight: bold;
  font-family: Arial, sans-serif;
  font-size: 30px;
}

#email-footer {
  margin-top: 10px;
  padding: 10px 0;
  color: white;
  background-color: gray;
  text-align: center;
  font-family: Arial, sans-serif;
}

.email-editable {
  font-family: Arial, sans-serif;
}

#saveB {
  margin-top: 30px;
  padding: 10px 0;
  width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.6.0/tinymce.min.js"></script>
<table id="email">
  <thead>
    <tr>
      <td id="email-header">Default header (this is not editable)</td>
    </tr>
    </thread>
    <tfoot>
      <tr>
        <td id="email-footer">2022 &copy; My Company (this is not editable)</td>
      </tr>
    </tfoot>
    <tbody id="email-body">
      <tr>
        <td>
          <div class="email-editable">
            <p>CUSTOM CONTENT 1. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris a mi libero. Morbi condimentum, <strong>ante non feugiat cursus, sapien ante laoreet turpis, fringilla finibus ante erat quis lorem</strong>. Donec cursus sem
              eget nunc faucibus semper.</p>
            <ul>
              <li>Item 1</li>
              <li>Item 2</li>
            </ul>
          </div>
        </td>
      </tr>
      <tr>
        <td>
          <div class="email-editable">
            <p>CUSTOM CONTENT 2. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris a mi libero. Morbi condimentum, <strong>ante non feugiat cursus, sapien ante laoreet turpis, fringilla finibus ante erat quis lorem</strong>. Donec cursus sem
              eget nunc faucibus semper.</p>
          </div>
        </td>
      </tr>
      <tr>
        <td>
          <div class="email-editable">
            <p>CUSTOM CONTENT 3. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris a mi libero. Morbi condimentum, <strong>ante non feugiat cursus, sapien ante laoreet turpis, fringilla finibus ante erat quis lorem</strong>. Donec cursus sem
              eget nunc faucibus semper.</p>
          </div>
        </td>
      </tr>
      <tr>
        <td>
          <div class="email-editable">
            <p>CUSTOM CONTENT 4. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris a mi libero. Morbi condimentum, <strong>ante non feugiat cursus, sapien ante laoreet turpis, fringilla finibus ante erat quis lorem</strong>. Donec cursus sem
              eget nunc faucibus semper.</p>
          </div>
        </td>
      </tr>
    </tbody>


</table>
<button id="saveB" type="button">Save email</button>

评论

0赞 blogob 3/18/2022
再次感谢Nonameyet..因此,由于我们需要干净的HTML(仅表格等),因此当您导出HTML文件时,该怎么办?你动态删除所有那些不再有用的div?对我来说,这可能是一个问题,因为 div 有时会破坏布局,例如在一个集团中,如果你只需要使标题可编辑,这意味着你必须将 div 放在许多不同的地方,不同的级别。我可以让整个文件可编辑,这不那么性感,更容易出错。如果你有数百个区块,这是一项艰巨的工作!
0赞 3/19/2022
我已经更新了答案并更改了模板。
0赞 blogob 3/19/2022
难以置信,非常感谢NoNameyet。我试着混合你的答案,以找到实现这个项目的最佳方法。一开始,我使用'tinyMCE.activeEditor.setContent(code);'将我所有的代码注入到一个文本区域中,这样整个集团都是可编辑的。现在,由于我想编辑内部内容,因此我必须在普通div中单击时添加内容,并且仅将tinymce应用于内部内容块。所以我必须重建一切。但是您的回答非常有帮助,再次感谢您的帮助!
0赞 blogob 3/19/2022
顺便问一下,你使用保存功能是有原因的吗?因为就我而言,我只需要一个空白的div,在其中注入代码,编辑它,然后导出。也许我错了,但我不需要保存任何东西,对吧?
1赞 blogob 6/10/2022
最后,删除所有Tinymce实例和样式的最后一个解决方案对我不起作用。我在这里创建了一个新问题 stackoverflow.com/questions/72552522/...使用另一个文件。