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

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

  • [1. 缩进,特殊方式处理------修改原工具栏里的增加缩进量](#1. 缩进,特殊方式处理——修改原工具栏里的增加缩进量)
  • [2 缩进,插件处理](#2 缩进,插件处理)
    • [2.1 下载段落插件 textindent](#2.1 下载段落插件 textindent)
    • [2.2 使用段落插件 textindent](#2.2 使用段落插件 textindent)
    • [2.3 修改textindent插件中的plugins.js文件](#2.3 修改textindent插件中的plugins.js文件)
      • [2.3.1 修改插件按钮提示信息](#2.3.1 修改插件按钮提示信息)
      • [2.3.2 修改插件里的缩进偏移量和缩进单位](#2.3.2 修改插件里的缩进偏移量和缩进单位)
    • [2.4 开启textindent插件 并 看效果](#2.4 开启textindent插件 并 看效果)
      • [2.4.1 开启插件](#2.4.1 开启插件)
      • [2.4.2 段落首行缩进测试](#2.4.2 段落首行缩进测试)
      • [2.4.3 来源word粘贴(保留缩进格式测试)](#2.4.3 来源word粘贴(保留缩进格式测试))
    • [2.5 附核心代码](#2.5 附核心代码)
    • [2.6 关于安装插件的其他详细内容](#2.6 关于安装插件的其他详细内容)
  • [3. 缩进,插件处理------优化(简直完美)](#3. 缩进,插件处理——优化(简直完美))
    • [3.1 如果不优化存在的问题](#3.1 如果不优化存在的问题)
    • [3.2 修改插件的plugin.js------设置缩进2个字体空间](#3.2 修改插件的plugin.js——设置缩进2个字体空间)
      • [3.2.1 直接换单位(rem)](#3.2.1 直接换单位(rem))
      • [3.2.2 更改源码,计算缩进空间](#3.2.2 更改源码,计算缩进空间)
        • [3.2.2.1 更改位置](#3.2.2.1 更改位置)
        • [3.2.2.2 看效果](#3.2.2.2 看效果)
        • [3.2.2.3 核心代码](#3.2.2.3 核心代码)
        • [3.2.2.4 更改后完整 plugin.js 代码](#3.2.2.4 更改后完整 plugin.js 代码)
        • [3.2.2.5 优化后完整 plugin.js 代码](#3.2.2.5 优化后完整 plugin.js 代码)
  • [4. 下载项目](#4. 下载项目)
  • [5. word里有图片的问题(待解决)](#5. word里有图片的问题(待解决))
    • [4.1 问题描述](#4.1 问题描述)
    • [5.1 查看自己的CKEditor4版本号](#5.1 查看自己的CKEditor4版本号)
    • [5.2 关于Paste from Word插件](#5.2 关于Paste from Word插件)
      • [5.2.1 下载Paste from Word插件](#5.2.1 下载Paste from Word插件)
      • [5.3 解压所有插件](#5.3 解压所有插件)

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,如下:

    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,如下:

    javascript 复制代码
    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 核心代码
  • 添加的核心代码如下:

    javascript 复制代码
    // 第一个是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 代码
  • 如下:

    javascript 复制代码
    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处,并且原本也有重复代码,优化后如下:

    javascript 复制代码
    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的版本下载对应插件的版本号,所以先确定一下自己的版本号,在浏览器的控制台中输入命令即可查询,查询版本号的方式如下:

    js 复制代码
    CKEDITOR
    或
    CKEDITOR.version

5.2 关于Paste from Word插件

5.2.1 下载Paste from Word插件

5.3 解压所有插件

相关推荐
Jacob程序员20 小时前
java导出word文件(手绘)
java·开发语言·word
q24985969320 小时前
前端预览word、excel、ppt
前端·word·excel
flashman91120 小时前
python在word中插入图片
python·microsoft·自动化·word
hairenjing11231 天前
使用 Mac 数据恢复从 iPhoto 图库中恢复照片
windows·stm32·嵌入式硬件·macos·word
初九之潜龙勿用2 天前
C#结合JS解决Word添加无效位图导致进程停滞的问题
javascript·ui·c#·word·asp.net
火星技术2 天前
Excel快速转换文档word工具
word·excel
棱角~~3 天前
10款PDF转Word软件工具的使用感受及其亮点!!!
经验分享·pdf·word·学习方法
shujuwa663 天前
什么是开源软件(OSS)?
pdf·编辑器·电脑·word·开源软件
遇见小美好y3 天前
自己生成的页面,保存为图片,并下载word
前端·javascript·word
hairenjing11234 天前
在电脑上免费分区的 5 个有效磁盘分区软件工具
windows·stm32·嵌入式硬件·macos·电脑·word