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

时间:2013-04-03 01:35:53

标签: javascript ckeditor

我想在CKEditor元素的<p>中包含选定的字词。

自:

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

要:

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

我找到了一些代码:

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

我想将[before][after]替换为<p class"myclass"></p>但不起作用。

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

编辑:来自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'
      }); 
    } 
  });
})();

上面的代码将选定的文本/单词包装在<span>元素中,原因不明。

示例:

...从

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

要...

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

这不是我想要的。

7 个答案:

答案 0 :(得分:21)

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
}

这将解决它..这是你可以看到的Exec部分。

答案 1 :(得分:4)

重复,请参阅Stackoverflow: Ckeditor Selection wrapping

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

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

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

此示例将合并并输出为:

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

但是这个例子:

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

此示例将合并并输出为:

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

答案 2 :(得分:1)

值得注意的是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'} 
      })
);

注意键现在都是小写的。

如果他们document这是真的有帮助 - 目前唯一的文件说“TODO ......”!

答案 3 :(得分:1)

它适用于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);
  }
}

这里的内容是textarea id

答案 4 :(得分:1)

如果你想要一个同时适用于文本和任意数量元素的通用解决方案,那么这将有效:

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

您需要另外两个功能:

/**
    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;
}

请注意,在CKEditor 4.5中,您实际上具有getHtml功能,因此可以使用getRangeHtml简化content.getHtml()。请参阅documentFragment doc

答案 5 :(得分:0)

此代码示例为 CK 编辑器添加带有按钮的插件,该编辑器使用类“vip-content”包装 html。 这会处理每种类型的元素:单击文本内部、单击元素(例如 img)或选择某些元素(某些代码行)。

(function () {
const WRAP_CONTENT_CLASS = 'vip-content';

function getSelectionHtml(selection) {
    var ranges = selection.getRanges();
    var html = '';

    for (var i = 0; i < ranges.length; i++) {
        html += ranges[i].extractContents().getHtml();
    }

    return html;
}

CKEDITOR.plugins.add('wrapcontent', {
    init: function (editor) {
        editor.addCommand('WrapContent', {
            exec: function () {
                var selection = editor.getSelection();
                var div = new CKEDITOR.dom.element('div').addClass(WRAP_CONTENT_CLASS);

                // Process element
                if (selection.getSelectedElement()) {
                    div.append(selection.getSelectedElement());
                    editor.insertElement(div);

                    return;
                }

                if (selection.getNative().type === 'Caret') {
                    editor.applyStyle(new CKEDITOR.style({
                        element: 'div',
                        attributes: {class: WRAP_CONTENT_CLASS},
                    }));
                } else {
                    var html = getSelectionHtml(selection);
                    if (html !== '') {
                        div.setHtml(html);
                        editor.insertElement(div);
                    }
                }
            }
        });

        editor.ui.addButton('WrapContent', {
            label: 'Wrap content',
            toolbar: 'insert',
            command: 'WrapContent',
            icon: this.path + 'icons/icon.png'
        });
    }
});
})();

答案 6 :(得分:0)

我发现这种方式更好地获得样式的添加删除效果:

CKEDITOR.plugins.add('my_style', {
    
    init: function (editor) {
        'use strict';
        editor.addCommand('my_style', {
            exec: function (editor) {
                var myStyle = new CKEDITOR.style({
                    element: 'span',
                    attributes: {class: 'my_style'}
                });

                if (myStyle.checkActive(editor.elementPath(), editor)) {
                    editor.removeStyle(myStyle);
                } else {
                    editor.applyStyle(myStyle);
                }
            }
        });
    }
});