富文本编辑器CKEditor4简单使用-08(段落首行缩进插件 + 处理粘贴 Microsoft Word 中的内容后保持原始内容格式(包括首行缩进))

发布于:2024-05-09 ⋅ 阅读:(30) ⋅ 点赞:(0)

1. 缩进,特殊方式处理——修改原工具栏里的增加缩进量

2 缩进,插件处理

2.1 下载段落插件 textindent

2.2 使用段落插件 textindent

  • 下载之后解压,然后放在plugins目录下,如下:
    在这里插入图片描述

2.3 修改textindent插件中的plugins.js文件

2.3.1 修改插件按钮提示信息

  • 这个看自己,因为提示信息是一串英文的,所以这里改成明了的汉字,如下:
    在这里插入图片描述

2.3.2 修改插件里的缩进偏移量和缩进单位

  • 如下:
    在这里插入图片描述
    在这里插入图片描述

2.4 开启textindent插件 并 看效果

2.4.1 开启插件

  • 开启插件配置如下:
    在这里插入图片描述
    在这里插入图片描述

2.4.2 段落首行缩进测试

  • 看效果

  • 如果不修改缩进偏移量和缩进单位的话,原本效果如下
    在这里插入图片描述

  • 修改缩进偏移量和缩进单位后的效果,如下:
    在这里插入图片描述

2.4.3 来源word粘贴(保留缩进格式测试)

  • 使用这个插件之后,从word里复制出的内容再粘贴格式保持不变(包括首行缩进格式),如下:
    在这里插入图片描述
    在这里插入图片描述
  • 通过工具栏的按钮粘贴也是一样的可以实现缩进效果,但是不一样的是这种缩进不是缩进的两个字符(2em),而是缩进的两个字体的空间大小(可以理解是保持原文格式不变了)。
  • 注意前提:一定要开启textindent插件,否则首行缩进格式丢失!

2.5 附核心代码

  • text.html,如下:
    <!doctype html>
    <html lang="en">
    
    <head>
      <meta charset="utf-8">
      <meta name="robots" content="noindex, nofollow">
      <title>Setting text part language</title>
      <script src="../ckeditor/ckeditor.js"></script>
    </head>
    
    <body>
      <textarea cols="80" id="editor2" name="editor2" rows="10"></textarea>
    
      <script>
        var editor = CKEDITOR.replace('editor2', {
          
        });
    
        editor.on("beforeCommandExec", function (event) {
            // 显示粘贴按钮的粘贴对话框并右键单击粘贴
            if (event.data.name == "paste") {
                event.editor._.forcePasteDialog = true;
            }
            // 不要显示Ctrl+Shift+V的粘贴对话框
            if (event.data.name == "pastetext" && event.data.commandData.from == "keystrokeHandler") {
                event.cancel();
            }
        });
    
      </script>
    </body>
    
    </html>
    
  • config.js,如下:
    CKEDITOR.editorConfig = function( config ) {
    
    	// 启用皮肤
    	config.skin = 'office2013';
    	
    	// textindent-首行缩进插件
    	config.extraPlugins = 'textindent';
    
    };
    
    

2.6 关于安装插件的其他详细内容

3. 缩进,插件处理——优化(简直完美)

3.1 如果不优化存在的问题

  • 上面我们把缩进量和单位配置成2em,看着测试没什么问题,但是我们通过复制粘贴发现,复制粘贴后缩进保留的还是原文的px,所以我们上面测试看着没问题,那是因为字体刚刚好,如果我们把字体调大或者调小再次点击缩进按钮,问题就暴露出来了,如下:
    在这里插入图片描述
  • 所以,它是一个动态的,我们要做的是如何实现缩进两个字体(根据原文字体的大小缩进),所以我们要设置成动态的缩进2个字体的空间,也就是说:
    当设置为2个字体的空间时,即首行缩进的距离为2个字体大小的距离。例如,如果你的文字大小为16px,那么缩进的距离就是32px。

3.2 修改插件的plugin.js——设置缩进2个字体空间

3.2.1 直接换单位(rem)

  • 但是这个有个问题,如果正文字体大小都一样可以,如果第二段字体大小和第一段字体大小不一样的话,效果不是很理想(这时第一段可以实现效果,但是第二段不行)如下:
    在这里插入图片描述
    在这里插入图片描述

  • 关于emrem
    在 CSS 中,em 和 rem 都是相对长度单位,其中 em 是相对于父元素的字体大小,而 rem 是相对于根元素的字体大小(即 html 元素的字体大小)。具体来说:

    • em:表示相对于当前元素的字体大小。例如,如果当前元素的字体大小为 16px,那么 1em 就等于 16px。
    • rem:表示相对于根元素(即 html 元素)的字体大小。例如,如果根元素的字体大小为 16px,那么 1rem 就等于 16px。
      由于 rem 单位是相对于根元素的字体大小,因此在整个页面中都是一致的。这使得使用 rem 单位更加方便和灵活,可以避免在多层嵌套中计算父元素字体大小的复杂性。
  • 如果字体不一致的话,上面rem可能还是不能满足,这就需要计算了,如何实现,请继续……

3.2.2 更改源码,计算缩进空间

3.2.2.1 更改位置
  • 如下:
    在这里插入图片描述
    在这里插入图片描述
3.2.2.2 看效果
  • 如下:
    在这里插入图片描述

    在这里插入图片描述

3.2.2.3 核心代码
  • 添加的核心代码如下:

    // 第一个是span,获取span标签
    var child_span = node.$.firstElementChild; 
    // console.log(child_span);
    if(child_span!=null){
        // 获取span里的 font-size属性的值
        var spanFontSize = child_span.style.fontSize;
        indentation = 2 * parseFloat(spanFontSize) + "px"; // 更改缩进量和缩进单位
        // console.log(spanFontSize);
        // console.log(indentation);
    }
    
3.2.2.4 更改后完整 plugin.js 代码
  • 如下:
    CKEDITOR.plugins.add( 'textindent', {
        icons: 'textindent',
        availableLangs: {'pt-br':1, 'en':1},
        lang: 'pt-br, en',
    	init: function( editor ) {
    
            var indentation = editor.config.indentation;
            var indentationKey = editor.config.indentationKey;
    
            if(typeof(indentation) == 'undefined')
                indentation = '2em';
            if(typeof(indentationKey) == 'undefined')
                indentationKey = 'tab';
    
            if(editor.ui.addButton){
    
                editor.ui.addButton( 'textindent', {
                    // label: editor.lang.textindent.labelName,
                    label: '首行缩进',
                    command: 'ident-paragraph',
                });
            }
    
            if( indentationKey !== false){
    
                editor.on('key', function(ev) {
                    if(ev.data.domEvent.$.key.toLowerCase() === indentationKey.toLowerCase().trim() || ev.data.keyCode === indentationKey){
                        editor.execCommand('ident-paragraph');
                        ev.cancel();  
                    }
                });
            }
            
            editor.on( 'selectionChange', function()
                {
                    var style_textindente = new CKEDITOR.style({
                            element: 'p',
                            styles: { 'text-indent': indentation },
                            overrides: [{
                                element: 'text-indent', attributes: { 'size': '0'}
                            }]
                        });
    
                    if( style_textindente.checkActive(editor.elementPath(), editor) )
                       editor.getCommand('ident-paragraph').setState(CKEDITOR.TRISTATE_ON);
                    else
                       editor.getCommand('ident-paragraph').setState(CKEDITOR.TRISTATE_OFF);
                    
            });
    
            editor.addCommand("ident-paragraph", {
                allowedContent: 'p{text-indent}',
                requiredContent: 'p',
                exec: function(evt) {
    
                    var range = editor.getSelection().getRanges()[0]; 
    
                    var walker = new CKEDITOR.dom.walker( range ),
                    node;
    
                    var state = editor.getCommand('ident-paragraph').state;
    
                    while ( ( node = walker.next() ) ) {
                        if ( node.type == CKEDITOR.NODE_ELEMENT ) {
                            if(node.getName() === "p"){
                                // console.log(node);
                                    editor.fire('saveSnapshot');
                                    if( state == CKEDITOR.TRISTATE_ON){
                                        node.removeStyle("text-indent");
                                        editor.getCommand('ident-paragraph').setState(CKEDITOR.TRISTATE_OFF);
                                    }
                                    else{
                                        // 第一个是span,获取span标签
                                        var child_span = node.$.firstElementChild; 
                                        console.log(child_span);
                                        if(child_span!=null){
                                            // 获取span里的 font-size属性的值
                                            var spanFontSize = child_span.style.fontSize;
                                            indentation = 2 * parseFloat(spanFontSize) + "px";  // 更改缩进量和缩进单位
                                        }
                                        node.setStyle( "text-indent", indentation );
                                        editor.getCommand('ident-paragraph').setState(CKEDITOR.TRISTATE_ON);
                                    }
                            }
                        }
                    }
    
                    if(node === null){
                        
                        node = editor.getSelection().getStartElement().getAscendant('p', true);
    
                        console.log(node);
                       
                        // var outerHtml = node.getOuterHtml();
                        // console.log(outerHtml);
    
                        // 获取 childNodes
                        // var childNodes = node.$.childNodes; 
                        // console.log(childNodes);
    
                        // 第一个是span,获取span标签
                        var child_span = node.$.firstElementChild; 
                        // console.log(child_span);
                        if(child_span!=null){
                            // 获取span里的 font-size属性的值
                            var spanFontSize = child_span.style.fontSize;
                            indentation = 2 * parseFloat(spanFontSize) + "px"; // 更改缩进量和缩进单位
                            // console.log(spanFontSize);
                            // console.log(indentation);
                        }
                        
                        editor.fire('saveSnapshot');
    
                        if( state == CKEDITOR.TRISTATE_ON){
                            node.removeStyle("text-indent");
                            editor.getCommand('ident-paragraph').setState(CKEDITOR.TRISTATE_OFF);
                        }
                        else{
                            node.setStyle( "text-indent", indentation );
                            editor.getCommand('ident-paragraph').setState(CKEDITOR.TRISTATE_ON);
                        }
                    }
                    
                }
            });
    	}
    
    });
    
    
3.2.2.5 优化后完整 plugin.js 代码
  • 上述代码修改2处,并且原本也有重复代码,优化后如下:
    CKEDITOR.plugins.add( 'textindent', {
        icons: 'textindent',
        availableLangs: {'pt-br':1, 'en':1},
        lang: 'pt-br, en',
    	init: function( editor ) {
    
            var indentation = editor.config.indentation;
            var indentationKey = editor.config.indentationKey;
    
            if(typeof(indentation) == 'undefined')
                indentation = '2em';
            if(typeof(indentationKey) == 'undefined')
                indentationKey = 'tab';
    
            if(editor.ui.addButton){
    
                editor.ui.addButton( 'textindent', {
                    // label: editor.lang.textindent.labelName,
                    label: '首行缩进',
                    command: 'ident-paragraph',
                });
            }
    
            if( indentationKey !== false){
    
                editor.on('key', function(ev) {
                    if(ev.data.domEvent.$.key.toLowerCase() === indentationKey.toLowerCase().trim() || ev.data.keyCode === indentationKey){
                        editor.execCommand('ident-paragraph');
                        ev.cancel();  
                    }
                });
            }
            
            editor.on( 'selectionChange', function()
                {
                    var style_textindente = new CKEDITOR.style({
                            element: 'p',
                            styles: { 'text-indent': indentation },
                            overrides: [{
                                element: 'text-indent', attributes: { 'size': '0'}
                            }]
                        });
    
                    if( style_textindente.checkActive(editor.elementPath(), editor) )
                       editor.getCommand('ident-paragraph').setState(CKEDITOR.TRISTATE_ON);
                    else
                       editor.getCommand('ident-paragraph').setState(CKEDITOR.TRISTATE_OFF);
                    
            });
    
            editor.addCommand("ident-paragraph", {
                allowedContent: 'p{text-indent}',
                requiredContent: 'p',
                exec: function(evt) {
    
                    var range = editor.getSelection().getRanges()[0]; 
    
                    var walker = new CKEDITOR.dom.walker( range ),
                    node;
    
                    var state = editor.getCommand('ident-paragraph').state;
    
                    while ( ( node = walker.next() ) ) {
                        if ( node.type == CKEDITOR.NODE_ELEMENT ) {
                            if(node.getName() === "p"){
                                calculateAndDoFirstLineIndent();
                            }
                        }
                    }
    
                    if(node === null){
                        node = editor.getSelection().getStartElement().getAscendant('p', true);
                        calculateAndDoFirstLineIndent();
                    }
    
                    /**
                     * 计算并处理首行缩进
                     */
                    function calculateAndDoFirstLineIndent(){
                        editor.fire('saveSnapshot');
                        if( state == CKEDITOR.TRISTATE_ON){
                            node.removeStyle("text-indent");
                            editor.getCommand('ident-paragraph').setState(CKEDITOR.TRISTATE_OFF);
                        }
                        else{
                            // 第一个是span,获取span标签
                            var child_span = node.$.firstElementChild; 
                            if(child_span!=null){
                                // 获取span里的 font-size属性的值
                                var spanFontSize = child_span.style.fontSize;
                                // 更改缩进量和缩进单位(缩进2个字体的空间)
                                indentation = 2 * parseFloat(spanFontSize) + "px"; 
                            }
                            node.setStyle( "text-indent", indentation );
                            editor.getCommand('ident-paragraph').setState(CKEDITOR.TRISTATE_ON);
                        }
                    }
                    
                }
            });
    	}
    
    });
    
    

4. 下载项目

5. word里有图片的问题(待解决)

4.1 问题描述

  • 如果粘贴的word里有图片,复制之后图片不展示,如下:
    在这里插入图片描述

5.1 查看自己的CKEditor4版本号

  • 后续下载插件有的会根据CKEditor4的版本下载对应插件的版本号,所以先确定一下自己的版本号,在浏览器的控制台中输入命令即可查询,查询版本号的方式如下:
    CKEDITORCKEDITOR.version
    
    在这里插入图片描述

5.2 关于Paste from Word插件

5.2.1 下载Paste from Word插件

5.3 解压所有插件


网站公告

今日签到

点亮在社区的每一天
去签到