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

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

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

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

所以我有几个问题:

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

我读到 here 内联模式在 td 上不起作用,因此有必要创建 div 并定位一个 id 或 class。

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

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

您可以有多个 div 具有相同的 class。例如,我们有 4 个 divs with .email-editable class。所有 .email-editable 元素都将具有相同的选项。当你想保存所有编辑器时,你需要调用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 元素的新模板。当你点击 Save 按钮时,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>