不可编辑的内容允许删除。如何限制这个?

我们使用了带有“不可编辑”插件的 TinyMCE 编辑器。我们尝试删除不可编辑的内容,它被删除了。如何限制不可编辑内容的删除(删除/退格)操作?


下面是我的代码:


tinymce.init({

  selector: "#myeditablediv",

  plugins: "advlist table lists image paste link pagebreak noneditable help",

  noneditable_noneditable_class: "mceNonEditable",

  menubar: false,

  inline: true,

  height: 500,

  paste_data_images: true,

  toolbar_sticky: true,

  toolbar:

    "bold italic underline | superscript subscript | formatselect | bullist | code pagebreak | link image | COC | table | removeformat | help",

  formats: {

    editable: {

      inline: "span",

      styles: { borderBottom: "2px solid gray" },

      classes: "mceEditable"

    }

  },

  setup: function (editor) {

    editor.ui.registry.addButton("COC", {

      text: "<b style='font-size:large;font-weight:bold;'>{CC}</b>",

      tooltip: "CopyToClipBoard",

      onAction: function (api) {

        editor.execCommand("Copy");

      }

    });

  },


  toolbar_mode: "floating"

});

<script src="https://cdn.tiny.cloud/1/qagffr3pkuv17a8on1afax661irst1hbr4e6tbv888sz91jc/tinymce/5/tinymce.min.js"></script>


<div class="demo-inline">

  <div id="myeditablediv">

    Hi tiny


    <p class='mceNonEditable'> <b> This is a non editable content</b>

    </p>

    <p> <span class='mceNonEditable'> <b>This part is non editable</b> </span>

      This is a editable content


      <span class='mceNonEditable'> <b>This part is non editable</b> </span>


    </p>

  </div>

</div>

http://img.mukewang.com/6467303c0001a75306560480.jpg

江户川乱折腾
浏览 160回答 2
2回答

哔哔one

TinyMCE 的noneditable插件旨在使内容块不可编辑,但不可删除。相反,它将不可编辑内容的整个部分视为单个字符。要阻止内容被键盘删除,您可以使用 Tiny 的事件处理结构来查找某些按键,然后中断/停止它们。您需要展开它以查看光标在内容中的位置,如果按键的结果会删除您想要保留的内容,则仅在这些情况下停止按键。请注意,此方法不会阻止通过其他方法删除内容,例如将其作为更大选择的一部分删除。

温温酱

编写了一个到目前为止运行良好的 Angular 服务,可能需要针对边缘情况进行一些调整。nonDeletableSelectors包含表示应该不可删除的元素的 CSS 选择器。我注意到显然有一个带有不可编辑元素的 TinyMCE 错误,所以代码比我想象的更复杂。import {Injectable} from '@angular/core';@Injectable({  providedIn: 'root'})export class EditorPreventDeleteService {  constructor() { }  public nonDeletableSelectors = ['.mceNonEditable'];  public preventDelete(editor) {    let self = this;    editor.on('keydown', function(event) {      if (self.keyWillDelete(event)) {        let range = editor.selection.getRng(), selection = editor.selection.getSel();        if (!range.collapsed)          return self.checkSelection(editor, event);        else if (event.keyCode == 8)          self.checkBackspace(editor, event, selection);        else if (event.keyCode == 46)          self.checkDelete(editor, event, selection);      }      return true;    });    editor.on('beforeSetContent', event => {      return self.checkSelection(editor, event);    });    editor.on('dragstart', event => {      if (self.checkNode(event.target, true))        self.cancelEvent(event);    });  }  protected checkNode(node, includeChildren = true) {    if (node && node.nodeType !== Node.TEXT_NODE)      for (let nonDeletableSelector of this.nonDeletableSelectors)        if (node.matches(nonDeletableSelector)            || (includeChildren && node.querySelectorAll(nonDeletableSelector).length > 0))          return true;    return false;  }  protected checkSelection(editor, event) {    const selectedHTMLString = editor.selection.getContent({format : 'html'});    const selectedHTML = new DOMParser().parseFromString(selectedHTMLString, 'text/html').documentElement;    if (this.checkNode(selectedHTML))      return this.cancelEvent(event);    return true;  }  protected checkBackspace(editor, event, selection) {    if (selection.anchorOffset === 0 && this.getPrefixContent(editor, selection).length === 0)      return this.cancelEvent(event);    this.checkCaretDeletion(editor, event, selection, false);  }  protected checkDelete(editor, event, selection) {    this.checkCaretDeletion(editor, event, selection, true);  }  protected checkCaretDeletion(editor, event, selection, forwards = true) { // https://developer.mozilla.org/en-US/docs/Web/API/Selection    let borderingElement = forwards ? selection.anchorNode.nextSibling : selection.anchorNode.previousSibling;    if (selection.anchorNode.nodeType === Node.TEXT_NODE) {      if (this.getTrailingText(selection, forwards, false).length > 0)        return; // not at the border of a text element    } else if (selection.anchorOffset !== (forwards ? selection.anchorNode.childNodes.length : 0)        && this.trimZeroWidthSpaces(selection.anchorNode.textContent).length > 0        && this.checkNode(selection.anchorNode.childNodes.item(selection.anchorOffset + (forwards?0:1))))        return this.cancelEvent(event); // not at the border of anchor, anchor not empty, only neighbouring child is deleted    if (this.checkNode(selection.anchorNode) || this.checkNode(borderingElement))      this.cancelEvent(event);  }  protected getPrefixContent(editor, selection) {    let currentRange = editor.selection.getRng(1), tempRange = currentRange.cloneRange();    tempRange.setStartBefore(editor.getBody().childNodes.item(0));    tempRange.setEndBefore(selection.anchorNode);    editor.selection.setRng(tempRange);    let content = editor.selection.getContent({format: 'html'});    editor.selection.setRng(currentRange);    return this.trimZeroWidthSpaces(content.trim());  }  protected getTrailingText(selection, forwards = true, includeSiblings = false) {    let trailer = '', appendTrailer = function(text) { forwards ? trailer += text : trailer = text + trailer; }    if (selection.anchorNode.nodeType === Node.TEXT_NODE) {      let text = selection.anchorNode.textContent;      appendTrailer(forwards ? text.substr(selection.anchorOffset) : text.substr(0, selection.anchorOffset));    } else {      for (let i=selection.anchorOffset ; i>=0 && i<selection.anchorNode.childNodes.length ; i+=(forwards?-1:1))        appendTrailer(selection.anchorNode.childNodes.item(i).textContent);    }    if (includeSiblings) {      let sibling = selection.anchorNode.previousSibling;      while (sibling) {        appendTrailer(sibling.textContent);        sibling = sibling.previousSibling;      }    }    return this.trimZeroWidthSpaces(trailer);  }  protected cancelEvent(event) {    event.preventDefault();    event.stopPropagation();    return false;  }  protected keyWillDelete(evt) {    let c = evt.keyCode;    if (evt.ctrlKey)      return evt.key == 'x' || [8, 46].includes(c);    return [8, 9, 13, 46].includes(c)        || this.inRange(c, 48, 57)        || this.inRange(c, 65, 90)        || this.inRange(c, 96, 111)        || this.inRange(c, 186, 192)        || this.inRange(c, 219, 222);  }  protected inRange(val, min, max) {    return val >= min && val <= max;  }  protected trimZeroWidthSpaces(text: string) {    return text.replace(/[\u200B-\u200D\uFEFF]/g, '');  }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript