Possible to populate and save text entered from inside a iframe in designMode?

北慕城南 提交于 2019-12-20 04:23:05

问题


i am just about to start writing my own rich text editor but need to know if its possible to populate the text area and also how to save / use the data inside it.

I am currently using ckEditor, but its too clunky and large for what i want.

Ill be using this as a base:

http://jsfiddle.net/Kxmaf/6/

I need to run certain checks on the data as well to check its length.

Thanks.

code if needed:

HTML:

 <a id="bold" class="font-bold">B</a>
 <a id="italic" class="italic">I</a>
 <select id="fonts">
     <option value="Arial">Arial</option>
     <option value="Comic Sans MS">Comic Sans MS</option>
     <option value="Courier New">Courier New</option>
     <option value="Monotype Corsiva">Monotype</option>
     <option value="Tahoma">Tahoma</option>
     <option value="Times">Times</option>
 </select>
 <br/>
 <iframe id="textEditor" style="width:500px; height:170px;">
 </iframe> 

JS:

$(document).ready(function(){
 document.getElementById('textEditor').contentWindow.  document.designMode="on";
 document.getElementById('textEditor').contentWindow.  document.close();
$("#bold").click(function(){

if($(this).hasClass("selected"))
{
    $(this).removeClass("selected");
}else
{
    $(this).addClass("selected");
}
    boldIt();
});
$("#italic").click(function(){

if($(this).hasClass("selected"))
{
    $(this).removeClass("selected");
}else
{
    $(this).addClass("selected");
}ItalicIt();
});
$("#fonts").change(function(){
changeFont($("#fonts").val());
});

});

function boldIt()
{  
   var edit = document.getElementById("textEditor").contentWindow;
   edit.focus(); 
   edit.document.execCommand("bold", false, ""); 
   edit.focus();
}

function ItalicIt()
 {  
    var edit = document.getElementById("textEditor").contentWindow;
    edit.focus(); 
    edit.document.execCommand("italic", false, ""); 
    edit.focus();
 }

function changeFont(font)
{
    var edit = document.getElementById("textEditor").contentWindow;
    edit.focus(); 
    edit.document.execCommand("FontName", false, font); 
    edit.focus();
}

回答1:


DEMO

To let you start from somewhere, Here's your HTML:

<div id="textEditorTab">
    <span data-cmd="bold"><b>B</b></span>
    <span data-cmd="italic"><i>I</i></span>

    <select id="fonts">
        <option value="Arial">Arial</option>
        <option value="Comic Sans MS">Comic Sans MS</option>
        <option value="Courier New">Courier New</option>
        <option value="Monotype Corsiva">Monotype</option>
        <option value="Tahoma">Tahoma</option>
        <option value="Times">Times</option>
    </select>
</div>

<div id="textEditor"></div>

The all the basic JS/jQ you need is:

$(function() {

  var $editor = $('#textEditor').prop('contenteditable', true);
  var $btn = $('span[data-cmd]');

  // EXECUTE COMMAND
  function execCmd(cmd, arg){      
    document.execCommand(cmd,false,arg);
  }

  $btn.mousedown(function(e) {
    e.preventDefault();
    $(this).toggleClass("selected");
    execCmd(this.dataset.cmd);
  });

  $("#fonts").change(function() {
    execCmd("FontName", this.value);       
  });

});

AND HERE'S A jsBin DEMO

Now, I've seen that you want, on button click make it state ACTIVE, but if you think twice what you'll achieve is a mess for one reason:

User enters text -> selects a portion and clicks BOLD, now it jumps with the cursot to the beginning of line where there's no BOLD text... but wait, your button still has the active state...

to prevent such UX, you need to keep track of the child element the user has selected, and accordingly turn ON all the buttons from your options tab that match the selected tag criteria.

I won't let you down so here's an example:

$(function() {

  var $editor = $('#textEditor').prop('contenteditable', true);
  var $btn = $('span[data-cmd]');
  var tag2cmd = {"B":'bold', "I":'italic'};

  // HIGHLIGHT BUTTONS on content selection
  function findParentNode(el) {

    $btn.removeClass('selected');

    var tagsArr = [];
    var testObj = el.parentNode || '';
    if(!testObj){return;}

    var c = 1;
    tagsArr.push(el.nodeName);
    if(el.tagName!='DIV'){
        while(testObj.tagName != 'DIV') {
            c++;
            tagsArr.push(testObj.nodeName);
            testObj = testObj.parentNode;   
        }
        for(i=0;i<c;i++){
            $('[data-cmd="'+ tag2cmd[tagsArr[i]] +'"]').addClass('selected');
        }
      console.log( tagsArr );
    }

  } 
  // EXECUTE COMMAND
  function execCmd(cmd, arg){      
    document.execCommand(cmd,false,arg);
  }

  $btn.mousedown(function(e) {
    e.preventDefault();
    $(this).toggleClass("selected");
    execCmd(this.dataset.cmd);
  });

  $("#fonts").change(function() {
    execCmd("FontName", this.value);       
  });


  // Having a button click toggleClass is not enough cause you'd also want 
  // to change button state when the user tlicks on different
  // elements tag inside the editor.

  var $lastSelected;
  $editor.on('mouseup', function( e ){
    e.stopPropagation();
    $lastSelected = e.target;
    findParentNode($lastSelected); // auto highlight select buttons
  });  

});

AND IT'S DEMO

So you see, only one 'idea' and the code gets immediately huge, so if you really want to keep it simple, avoid such stuff and have fun!



来源:https://stackoverflow.com/questions/23120809/possible-to-populate-and-save-text-entered-from-inside-a-iframe-in-designmode

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!