javascript 如何在ckeditor中包装选定的文本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15777407/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 02:04:48  来源:igfitidea点击:

How to wrap selected text in ckeditor

javascriptckeditor

提问by ninjascorner

I wanted to wrap selected words in CKEditorin a <p>element.

我想将选定的单词包装CKEditor在一个<p>元素中。

From:

从:

<p>This is a paragraph. And this is Selected text.</p>

To:

到:

<p>This is a paragraph. And this is</p>
<p class="myclass">Selected text.</p>

I found some code:

我找到了一些代码:

( function() {
    CKEDITOR.plugins.add( 'qna', { 
  ??    init: function( editor ) {
  ????      editor.addCommand( 'insertQnA', { 
  ??????        exec : function( editor ) {??? 
  ????????          if(CKEDITOR.env.ie) {
  ??????????            editor.getSelection().unlock(true); 
  ??????????                var selected_text = editor.getSelection().getNative().createRange().text; 
  ????????          } else { 
  ??????????            var selected_text = editor.getSelection().getNative();
  ????????          }
  ????????          editor.insertHtml('[before]' + selected_text + '[after]'); 
  ??????        } 
  ????      }); 
  ????      editor.ui.addButton( 'qna', { 
                label: 'Insert QnA', 
                command: 'insertQnA', 
                icon: this.path + 'images/qna.png'
            }); 
  ??    } 
    });
})();

I wanted to replace the [before]and [after]with <p class"myclass">and </p>but it doesn't work.

我想更换[before][after]<p class"myclass"></p>,但它不工作。

I'm quite a newbie in JS/Jquery. I hope you can shed some light on it for me.

我是 JS/Jquery 的新手。我希望你能帮我解释一下。

EDIT: From Spon's reply.

编辑:来自 Spon 的回复。

( function() {
  CKEDITOR.plugins.add( 'qna', { 
  ??init: function( editor ) {
  ????editor.addCommand( 'insertQnA', { 
  ??????exec : function( editor ) {??? 
          editor.applyStyle(new CKEDITOR.style({
            Element : 'p', 
            Attributes : { class : 'Myclass' }, 
            Styles : { color : '#ff0000','font-family' : 'Courier'} 
          }));
  ??????} 
  ????}); 
  ????editor.ui.addButton( 'qna', { 
        label: 'Insert QnA', 
        command: 'insertQnA', 
        icon: this.path + 'images/question.png'
      }); 
  ??} 
  });
})();

The above code wraps the selected text/words in a <span>element for some unknown reason.

上面的代码<span>出于某种未知原因将选定的文本/单词包装在一个元素中。

Example:

例子:

From...

从...

<p>This is a paragraph. And this is Selected text.</p>

To...

到...

<p>This is a paragraph. And this is <span>Selected text.</span></p>

This is not what I want.

这不是我想要的。

回答by Spons

exec : function( editor ) {
  var selected_text = editor.getSelection().getSelectedText(); // Get Text
  var newElement = new CKEDITOR.dom.element("p");              // Make Paragraff
  newElement.setAttributes({style: 'myclass'})                 // Set Attributes
  newElement.setText(selected_text);                           // Set text to element
  editor.insertElement(newElement);                            // Add Element
}

This will fix it.. This is the Exec part as you can see.

这将修复它。这是您可以看到的 Exec 部分。

回答by Spons

Duplicate see Stackoverflow: Ckeditor Selection wrapping

重复参见Stackoverflow: Ckeditor Selection wrapping

editor.applyStyle(new CKEDITOR.style({Element : 'p', Attributes : { class : 'Myclass' }, Styles : { color : '#ff0000','font-family' : 'Courier' } ));

This piece of code makes sure that if you have multiple block level selection, that you will keep the same structure. (If you make your p.myclass inline offcourse).

这段代码确保如果您有多个块级别选择,您将保持相同的结构。(如果你让你的 p.myclass 内联课外)。

<p>This is a paragraph. And this is </p><p> Selected text.</p>

this example will be merged and output as:

这个例子将被合并并输出为:

<p>This is a paragraph. </p><p class="myClass">And this is  Selected text.</p>

But this example:

但是这个例子:

<div>This is a paragraph. And this is</div><div>  Selected text.</div>

this example will be merged and output as:

这个例子将被合并并输出为:

<div>This is a paragraph. <P class="myclass">And this is</p></div><div><P class="myclass">  Selected text.</p></div>

回答by aendrew

Worth noting the CKEDITOR.style syntax has (apparently) changed in CKEditor 4; to use editor.applyStyle() (Which is preferable in some cases so you don't get a bunch of nested HTML), change the editor.applyStyle()stanza in the question's second example to:

值得注意的是 CKEDITOR.style 语法在 CKEditor 4 中(显然)发生了变化;要使用 editor.applyStyle() (在某些情况下更可取,因此您不会得到一堆嵌套的 HTML),editor.applyStyle()请将问题第二个示例中的节更改为:

editor.applyStyle(new CKEDITOR.style({
        element : 'p', 
        attributes : { class : 'Myclass' }, 
        styles : { color : '#ff0000','font-family' : 'Courier'} 
      })
);

Notice how the keys are all lowercase now.

注意键现在都是小写的。

It would really help if they'd documentthis -- the only documentation there at the moment says "TODO..."!

如果他们记录下来真的会很有帮助——目前唯一的文件是“待办事项......”!

回答by Nux

In case you want a universal solution that works both select text and any number of elements then this will work:

如果您想要一个适用于选择文本和任意数量元素的通用解决方案,那么这将起作用:

var selectedHtml = "";
var selection = editor.getSelection();
if (selection) {
    selectedHtml = getSelectionHtml(selection);
}
editor.insertHtml('something' + selectedHtml + 'something');

You will need two additional functions:

您将需要两个附加功能:

/**
    Get HTML of a range.
*/
function getRangeHtml(range) {
    var content = range.extractContents();
    // `content.$` is an actual DocumentFragment object (not a CKEDitor abstract)
    var children = content.$.childNodes;
    var html = '';
    for (var i = 0; i < children.length; i++) {
        var child = children[i];
        if (typeof child.outerHTML === 'string') {
            html += child.outerHTML;
        } else {
            html += child.textContent;
        }
    }
    return html;
}
/**
    Get HTML of a selection.
*/
function getSelectionHtml(selection) {
    var ranges = selection.getRanges();
    var html = '';
    for (var i = 0; i < ranges.length; i++) {
        html += getRangeHtml(ranges[i]);
    }
    return html;
}

Note that in CKEditor 4.5 you actually have getHtmlfunction so getRangeHtmlcould be simplified by using content.getHtml(). See documentFragment doc.

请注意,在 CKEditor 4.5 中,您实际上拥有getHtml函数,因此getRangeHtml可以使用content.getHtml(). 请参阅文档片段文档

回答by Shafiqul Islam

It is working for both image and text in ckeditor

它适用于 ckeditor 中的图像和文本

var selection = CKEDITOR.instances['content'].getSelection();
if (selection.getType() == CKEDITOR.SELECTION_ELEMENT) {
  var selectedContent = selection.getSelectedElement().$.outerHTML;
} else if (selection.getType() == CKEDITOR.SELECTION_TEXT) {
  if (CKEDITOR.env.ie) {
    selection.unlock(true);
    selectedContent = selection.getNative().createRange().text;
  } else {
    selectedContent = selection.getNative();
    console.log("The selectedContent is: " + selectedContent);
  }
}

here content is textarea id

这里的内容是 textarea id