【问题标题】:Email editor with tinymce : how to export a clean html file?带有 tinymce 的电子邮件编辑器:如何导出干净的 html 文件?
【发布时间】:2022-06-11 19:31:21
【问题描述】:

我设法创建了一个电子邮件编辑器,以 this example 为模型。在文件末尾我添加了一个下载按钮,以便用户可以检索他编辑的文件。

我的问题是tinymce 注入了大量我想在导出期间删除的代码、标记、类、属性和ID。是否有一个函数或插​​件可以在不引用 tinymce 的情况下检索其文件?

目前我“手动”删除每个元素,这在我看来根本不是最佳的。元素太多(随处可见的属性),我相信有更简单的方法..

 function saveTextAsFile(){
        clean();
              for (var i = 0; i < tinymce.editors.length; i++) {
                tinymce.editors[i].save();
              }

              var full = new XMLSerializer().serializeToString(document.doctype);
              var innercontent = document.documentElement.outerHTML;
              var content = full + innercontent;
              
              var textFileAsBlob = new Blob([content], {type:'text/html'});
              var fileNameToSaveAs = "index.html";
              var downloadLink = document.createElement("a");
              downloadLink.download = fileNameToSaveAs;
              downloadLink.innerHTML = "Téléchargez le fichier html actualisé";
              downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
              
              downloadLink.click();
              };
          
 function clean() {
    var div =  document.querySelectorAll("button~div");
    div.forEach((element) => element.remove());//removes all unwanted divs at the end of the file
    var contentToDelete = document.querySelectorAll("script,div.mce-tinymce,#mceDefaultStyles,.mce-widget,#u0,#u1,button");
    contentToDelete.forEach((element) => element.remove());//remove element and children
    var styleattr = document.querySelectorAll("[data-mce-style]");
    styleattr.forEach((element) => element.removeAttribute('data-mce-style'));//remove all data-mce-style attributes
    var hrefattr = document.querySelectorAll("[data-mce-href]");
    hrefattr.forEach((element) => element.removeAttribute('data-mce-href'));//remove all data-mce-href attributes
    var hrefattr = document.querySelectorAll("[data-mce-bogus]");
    hrefattr.forEach((element) => element.removeAttribute('data-mce-bogus'));//remove all data-mce-bogus attributes
    var txtboxes = document.querySelectorAll('.content');
      txtboxes.forEach(box => {
      box.replaceWith(...box.childNodes);//remove only  div.content itself not the children
    });
    var foo = document.querySelectorAll("table");
    foo.forEach((element) => element.classList.remove("mce-item-table"));//remove only className .mce-item-table
    }
 
//at the end of my html file
<button type="button" id="btnHtml" type="button" onClick="saveTextAsFile()">download</button>

【问题讨论】:

    标签: javascript html jquery tinymce


    【解决方案1】:

    是否有一个函数或插​​件可以在不引用 tinymce 的情况下检索其文件?

    是的,函数是getContent。我可以向您展示一个使用 jQuery 3.6.0 和 TinyMCE 5.6.0 的示例:

    // 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,
    });
    
    document.getElementById('save').addEventListener('click', function() {
    
      let $email = $('#email');
      
      // Get content from all editors 
      for (var i = 0; i < tinymce.editors.length; i++) {
        //tinymce.editors[i].save(); // I don't need to save each editor, but you can
        let editable = $email.find('.email-editable')[i];
        editable.innerHTML = tinymce.editors[i].getContent();
        editable.removeAttribute('spellcheck');
    
        // If you remove "contenteditable" then this node will not open TinyMCE when you click on it.
        editable.removeAttribute('contenteditable');
        editable.classList.remove('mce-content-body');
    
        // Note that the "getContent" function omits the TinyMCE metadata. Try it with "console.log". ;-)
        console.log(tinymce.editors[i].getContent());
      }
    
      // For this example, serialize only the #email element and their children
      let emailContent = new XMLSerializer().serializeToString($('#email')[0]);
      let blob = new Blob([emailContent], {
        type: 'text/html'
      });
    
      // Create download link and then download.
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.download = "index.html";
      a.style.display = 'none';
      a.href = url;
      //document.body.appendChild(a);
    
      // this link will not work here so try it on "codepen.io" or on your computer
      a.click();
    
      // Release object URL
      window.URL.revokeObjectURL(url);
    });
    #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;
    }
    
    #save {
      margin-top: 30px;
      padding: 10px 0;
      width: 100%;
    }
    
    .special {
      color: #7ae;
    }
    <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">Unmodifiable header :)</div>
      <div class="email-editable">Insert your text here</div>
      <div class="email-editable">
        <ul>
          <li>Some text and more text...</li>
          <li><span class="special">Special item</span> for you.</li>
        </ul>
      </div>
      <div id="email-footer">2022 &copy; Unmodifiable footer :)</div>
    
    </div>
    <button id="save" type="button">Export to html</button>

    请注意,在我的示例中,我只删除了 TinyMCE 为我生成的容器的属性(我的意思是 .email-editable 元素),因此您也可以删除其他属性。

    还要注意我使用URL.revokeObjectURL。来自https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL

    当你使用完一个对象 URL 后调用这个方法,让浏览器知道不再保留对文件的引用。




    目前我“手动”删除每个元素,这在我看来根本不是最佳的。元素太多(随处可见的属性),我相信有更简单的方法..

    你做得对。另一种方法是通过扩展 jQuery 对象来添加一个函数。在网页https://www.geeksforgeeks.org/how-to-remove-all-attributes-of-an-html-element-using-jquery/ 上,您有一个示例来添加一个删除节点所有属性的函数。也许您可以编辑该函数以添加白名单(字符串数组)作为输入参数。

    示例代码(来自 GeeksForGeeks.org)是:

    $.fn.removeAllAttributes = function() {
        return this.each(function() {
            $.each(this.attributes, function() {
                this.ownerElement.removeAttributeNode(this);
            });
        });
    };
    
    $('textarea').removeAllAttributes();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-21
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      相关资源
      最近更新 更多