简体   繁体   中英

CodeMirror with 2 text editors and live preview?

I'm trying to create a live editor like jsfiddle where users can put html in html box (textarea) and css in css box(textarea) and preview the changes live in an iframe .

I am using codemirror as the editor.

So far I can only get the preview of one of the textareas in my iframe and I cannot figure out how to get the values of both textareas (css/html) and display them in my iframe exactly like jsfiddle.

This is what I have so far:

http://jsfiddle.net/vwqgtznv/

and this is my javascript code:

   <script>
      var delay;
      // Initialize CodeMirror editor with a nice html5 canvas demo.
      var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
    lineNumbers: true,
    styleActiveLine: true,
    matchBrackets: true,
        mode: 'text/html'
      });
      editor.on("change", function() {
        clearTimeout(delay);
        //alert("hellooooo");



        delay = setTimeout(updatePreview, 300);
      });

      function updatePreview() {
        var previewFrame = document.getElementById('preview');
        var preview =  previewFrame.contentDocument ||  previewFrame.contentWindow.document;
        preview.open();
        preview.write(editor.getValue());
        preview.close();
      }
      setTimeout(updatePreview, 300);
    </script>

        <script>
      var delay2;
      // Initialize CodeMirror editor with a nice html5 canvas demo.
      var editor2 = CodeMirror.fromTextArea(document.getElementById('codert'), {
    lineNumbers: true,
    styleActiveLine: true,
    matchBrackets: true,
        mode: 'text/html'
      });
      editor2.on("change", function() {
        clearTimeout(delay2);
        //alert("hellooooo");



        delay2 = setTimeout(updatePreview2, 300);
      });

      function updatePreview2() {
        var previewFrame2 = document.getElementById('preview');
        var preview2 =  previewFrame2.contentDocument ||  previewFrame2.contentWindow.document;
        preview2.open();
        preview2.write(editor2.getValue());
        preview2.close();
      }
      setTimeout(updatePreview2, 300);
    </script>

could someone please help me out and advise on this issue?

Thanks in advance.

Your problem is append CSS to iframe head. Use the code below to update your iframe head for CSS.

function loadCSS() {
    var $head = $("#preview").contents().find("head");                
    $head.html("<style>" + editor.getValue() + "</style>");
}; 

HTML textarea should be updated with CSS. Add loadCSS() to your updatePreview2() (html textarea update function).

function updatePreview2() {
    var previewFrame2 = document.getElementById('preview');
    var preview2 =  previewFrame2.contentDocument ||  previewFrame2.contentWindow.document;
    preview2.open();
    preview2.write(editor2.getValue());
    preview2.close();

    // added this line
    loadCSS(); 
}

And when your CSS textarea changes, the preview content will be updated by updatePreview() (CSS textarea update function) with CSS content. It should update head only.

function updatePreview() {
    loadCSS();
}

Here is the Jsfiddle , please take a demo here.

By the way, try to name your variable and function precisely will make more people help you.

Update

A clean JsFiddle version.

Building upon @North's answer and guidance, I propose this answer. If you +1 this answer, please give +1 to North's answer as well. This is an optimization and expansion up North's anwser, building up a jsfiddle-clone. It therefor demo an answer to the question of this current page.

  • Jsfiddle -- richer code to go further
  • Blogpost -- Medium post with some other helpers.

In .html :

 <!-- load the relevant dependencies via script and style/link tags. -->
 <textarea class="code" id="editor-html">
 <textarea class="code" id="editor-css">
 <textarea class="code" id="editor-js">

In .js file :

var editorsSettings = {
  lineWrapping: true,
  lint: true,
  lineNumbers: true,
  foldGutter: true,
  gutters: ["CodeMirror-lint-markers","CodeMirror-linenumbers", "CodeMirror-foldgutter"],
  tabSize: 2,
  indentUnit: 2,
  matchBrackets: true
}

// Editors HTML, CSS, JS : init, bind, define settings.
let editorHTML = CodeMirror.fromTextArea(document.querySelector('#editor-html'), {
  mode : "htmlmixed", // require modes for xml, css, js.
  htmlMode: true,
  ...editorsSettings
});
let editorCSS = CodeMirror.fromTextArea(document.querySelector('#editor-css'), {
  mode: 'text/css',
  ...editorsSettings
});
let editorJS = CodeMirror.fromTextArea(document.querySelector('#editor-js'), {
  mode: 'text/javascript',
  ...editorsSettings
});

// Fetch and organize into results
let updatePreview = function() {
  let preview = document.querySelector('#preview');
  let previewDocument = preview.contentDocument || preview.contentWindow.document;
  previewDocument.open();
  previewDocument.write(editorHTML.getValue());
  previewDocument.write("<script>"+editorJS.getValue()+"<"+"/script>");
  previewDocument.close();
  previewDocument.querySelector('head').innerHTML = '<style>' + editorCSS.getValue() + '</style>';
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM