2

我即将开始编写自己的富文本编辑器,但需要知道是否可以填充文本区域以及如何保存/使用其中的数据。

我目前正在使用 CKEditor,但它对于我想要的东西来说太笨重而且太大了。
我将以此为基础: http: //jsfiddle.net/Kxmaf/6/
我还需要对数据进行某些检查以检查其长度。

如果需要,代码:

// Stack Code Snippets does not work with Iframe. Here's the code anyways:

$(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();
}
<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>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

谢谢。

4

1 回答 1

1

要创建您的右文本编辑器,您可以使用元素contenteditable上的属性<div>或通过 JS designMode。你不需要一个<iframe>.

注意:虽然execCommand适用于所有主要浏览器的怪癖和差异 - 它现在已被弃用(但没有任何合理的解决方法,但创建自己的内联内容编辑软件或使用Input-Events)所以小心使用。

让你从某个地方开始,

$(function() {

  var $editor = $('#textEditor');
  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);
  });

});
* {margin: 0; padding: 0;}

#textEditorTab span {
  cursor: pointer;
  display: inline-block;
  padding: 0px 10px 0px 10px;
}

#textEditorTab span:hover {
  background: #eee;
}

#textEditorTab span.selected {
  background-color: orange;
}

#textEditor {
  width: 300px;
  height: 120px;
  border: 1px solid #ddd;
  padding: 5px;
}
<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" contenteditable>Lorem ipsum dolor sit amet</div>


<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

现在,我已经看到您想要在按钮单击时使其状态为ACTIVE,但是如果您三思而后行,那么您将实现的结果是一团糟,原因有一个:

用户输入文本-> 选择一个部分并单击BOLD,现在它与光标一起跳到没有 BOLD 文本的行首...但是等等,您的按钮仍然处于活动状态...

为了防止这种 UX,您需要跟踪用户选择的子元素,并相应地打开选项选项卡中与所选tag条件匹配的所有按钮。

为了不让你失望 - 这是一个例子:

$(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
  });

});
* {margin: 0; padding: 0;}

#textEditorTab span {
  cursor: pointer;
  display: inline-block;
  padding: 0px 10px 0px 10px;
}

#textEditorTab span:hover {
  background: #eee;
}

#textEditorTab span.selected {
  background-color: orange;
}

#textEditor {
  width: 300px;
  height: 120px;
  border: 1px solid #ddd;
  padding: 5px;
}
<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">Lorem ipsum dolor sit amet</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

所以你看,只有一个“想法”,代码会立即变得庞大,所以如果你真的想保持简单,避免这些东西,玩得开心!

于 2014-04-16T23:13:12.397 回答