Contribute to this guide

指南字数和字符数

字数统计功能允许您跟踪编辑器中的字数和字符数。这有助于您控制内容的篇幅并检查工作的进度。

# 演示

添加或删除一些内容,看看编辑器下方的计数器如何实时变化。

泰姬陵是一座陵墓,由沙贾汗皇帝于 1631 年至 1648 年间在阿格拉为纪念他心爱的妻子 Mumtaz Mahal 而建造,Mumtaz Mahal 的遗体就安葬在那里。它耗费了 20,000 名工人才建成,这座建筑的卓越之处体现在每一块砖瓦中。

1983 年,泰姬陵被列为联合国教科文组织世界遗产,因为它“是印度穆斯林艺术的瑰宝,也是世界遗产中举世公认的杰作之一”。

此演示展示了一组有限的功能。请访问功能丰富的编辑器示例,以了解更多实际应用。

上面的示例是通过使用以下 HTML 页面结构创建的

<div id="editor">
    <p>Hello world.</p>
</div>
<div id="word-count"></div>

您可以使用以下代码设置具有字数和字符数功能的 WYSIWYG 编辑器,如上面的示例所示。

ClassicEditor
    .create( document.querySelector( '#editor' ), {
        // Configuration details.
    } )
    .then( editor => {
        const wordCountPlugin = editor.plugins.get( 'WordCount' );
        const wordCountWrapper = document.getElementById( 'word-count' );

        wordCountWrapper.appendChild( wordCountPlugin.wordCountContainer );
    } );

# 安装

⚠️ 新的导入路径

版本 42.0.0 开始,我们更改了导入路径的格式。本指南使用新的、更短的格式。如果您使用的是旧版本的 CKEditor 5,请参阅旧版设置中的包指南。

安装编辑器后,将功能添加到您的插件列表和工具栏配置中

import { ClassicEditor, WordCount } from 'ckeditor5';

ClassicEditor
    .create( document.querySelector( '#editor' ), {
        plugins: [ WordCount, /* ... */ ],
    } )
    .then( /* ... */ )
    .catch( /* ... */ );

# 配置

字数和字符数功能非常灵活,提供了一些可用的配置选项。

# 配置容器

有两种方法可以将字数统计信息注入您的页面

字数统计插件将其输出呈现为

<div class="ck ck-word-count">
    <div class="ck-word-count__words">Words: %%</div>
    <div class="ck-word-count__characters">Characters: %%</div>
</div>

如果您希望以不同的方式呈现统计信息,请参阅update 事件

# 更改输出

有两个可用的配置选项可以更改字数和字符数功能的输出

# 对更新做出反应

您可以在每次内容统计信息更改时执行自定义回调,方法是在编辑器配置中定义config.wordCount.onUpdate

ClassicEditor
    .create( document.querySelector( '#editor' ), {
        plugins: [ WordCount, /* ... */ ],
        wordCount: {
            onUpdate: stats => {
                // Prints the current content statistics.
                console.log( `Characters: ${ stats.characters }\nWords: ${ stats.words }` );
            }
        }
    } )
    .then( /* ... */ )
    .catch( /* ... */ );

注意:出于性能原因,您的回调将被节流,并且可能不是最新的。使用characterswords 插件属性按需检索准确的数字。

您可以在下面玩一个演示帖子编辑器,它有一个 120 个字符的软限制。下方的进度表指示内容中的字符数。当数字接近或超过限制时,图表会改变颜色。在编辑器中键入以查看功能的实际应用。在本节下面列出的代码中,您可以看到用于创建演示的代码。

带字数统计的帖子编辑器

游客经常承认泰姬陵“根本无法用语言形容”。

const maxCharacters = 120;
const container = document.querySelector( '.demo-update' );
const progressCircle = document.querySelector( '.demo-update__chart__circle' );
const charactersBox = document.querySelector( '.demo-update__chart__characters' );
const wordsBox = document.querySelector( '.demo-update__words' );
const circleCircumference = Math.floor( 2 * Math.PI * progressCircle.getAttribute( 'r' ) );
const sendButton = document.querySelector( '.demo-update__send' );

BalloonEditor
    .create( document.querySelector( '#demo-update__editor' ), {
        // Editor configuration.
        wordCount: {
            onUpdate: stats => {
                const charactersProgress = stats.characters / maxCharacters * circleCircumference;
                const isLimitExceeded = stats.characters > maxCharacters;
                const isCloseToLimit = !isLimitExceeded && stats.characters > maxCharacters * .8;
                const circleDashArray = Math.min( charactersProgress, circleCircumference );

                // Set the stroke of the circle to show how many characters were typed.
                progressCircle.setAttribute( 'stroke-dasharray', `${ circleDashArray },${ circleCircumference }` );

                // Display the number of characters in the progress chart. When the limit is exceeded,
                // display how many characters should be removed.
                if ( isLimitExceeded ) {
                    charactersBox.textContent = `-${ stats.characters - maxCharacters }`;
                } else {
                    charactersBox.textContent = stats.characters;
                }

                wordsBox.textContent = `Words in the post: ${ stats.words }`;

                // If the content length is close to the character limit, add a CSS class to warn the user.
                container.classList.toggle( 'demo-update__limit-close', isCloseToLimit );

                // If the character limit is exceeded, add a CSS class that makes the content's background red.
                container.classList.toggle( 'demo-update__limit-exceeded', isLimitExceeded );

                // If the character limit is exceeded, disable the send button.
                sendButton.toggleAttribute( 'disabled', isLimitExceeded );
            }
        }
    } );

以下是用于创建上面自定义单词和字符计数实现的 HTML 结构。

<style>
    .demo-update {
        border: 1px solid var(--ck-color-base-border);
        border-radius: var(--ck-border-radius);
        box-shadow: 2px 2px 0px hsla( 0, 0%, 0%, 0.1 );
        margin: 1.5em 0;
        padding: 1em;
    }

    .demo-update h3 {
        font-size: 18px;
        font-weight: bold;
        margin: 0 0 .5em;
        padding: 0;
    }

    .demo-update .ck.ck-editor__editable_inline {
        border: 1px solid hsla( 0, 0%, 0%, 0.15 );
        transition: background .5s ease-out;
        min-height: 6em;
        margin-bottom: 1em;
    }

    .demo-update__controls {
        display: flex;
        flex-direction: row;
        align-items: center;
    }

    .demo-update__chart {
        margin-right: 1em;
    }

    .demo-update__chart__circle {
        transform: rotate(-90deg);
        transform-origin: center;
    }

    .demo-update__chart__characters {
        font-size: 13px;
        font-weight: bold;
    }

    .demo-update__words {
        flex-grow: 1;
        opacity: .5;
    }

    .demo-update__limit-close .demo-update__chart__circle {
        stroke: hsl( 30, 100%, 52% );
    }

    .demo-update__limit-exceeded .ck.ck-editor__editable_inline {
        background: hsl( 0, 100%, 97% );
    }

    .demo-update__limit-exceeded .demo-update__chart__circle {
        stroke: hsl( 0, 100%, 52% );
    }

    .demo-update__limit-exceeded .demo-update__chart__characters {
        fill: hsl( 0, 100%, 52% );
    }
</style>

<div class="demo-update">
    <h3>Post editor with word count</h3>
    <div id="demo-update__editor">
        <p>Tourists frequently admit that <a href="https://en.wikipedia.org/wiki/Taj_Mahal">Taj Mahal</a> “simply cannot be described with words”.</p>
    </div>
    <div class="demo-update__controls">
        <span class="demo-update__words"></span>
        <svg class="demo-update__chart" viewbox="0 0 40 40" width="40" height="40" xmlns="http://www.w3.org/2000/svg">
            <circle stroke="hsl(0, 0%, 93%)" stroke-width="3" fill="none" cx="20" cy="20" r="17" />
            <circle class="demo-update__chart__circle" stroke="hsl(202, 92%, 59%)" stroke-width="3" stroke-dasharray="134,534" stroke-linecap="round" fill="none" cx="20" cy="20" r="17" />
            <text class="demo-update__chart__characters" x="50%" y="50%" dominant-baseline="central" text-anchor="middle"></text>
        </svg>
        <button type="button" class="demo-update__send">Send post</button>
    </div>
</div>

CKEditor 5 提供其他可以提高工作效率的功能,您可能会发现它们很有用。

# 通用 API

WordCount 插件提供

  • wordCountContainer 属性。它返回一个自更新的 HTML 元素,该元素会根据编辑器中当前的单词和字符数量进行更新。您可以通过适当配置 config.wordCount.displayWordsconfig.wordCount.displayCharacters 选项来删除“单词”或“字符”计数器。

  • update 事件,每当插件更新已计数的单词和字符数量时触发。您可以使用它来使用更新的值运行自定义回调函数。

    editor.plugins.get( 'WordCount' ).on( 'update', ( evt, stats ) => {
        // Prints the current content statistics.
        console.log( `Characters: ${ stats.characters }\nWords:      ${ stats.words }` );
    } );
    

    或者,您可以使用 config.wordCount.onUpdate 通过编辑器配置注册类似的回调函数。

    注意:出于性能原因,update 事件已节流,因此统计信息可能不是最新的。使用 characterswords 插件属性按需检索精确的数字。

  • characterswords 属性,您可以在任何时候从这些属性中检索统计信息。

我们建议使用官方的 CKEditor 5 检查器 进行开发和调试。它将为您提供有关编辑器状态的大量有用信息,例如内部数据结构、选择、命令等等。

# 贡献

该功能的源代码在 GitHub 上提供,地址为 https://github.com/ckeditor/ckeditor5/tree/master/packages/ckeditor5-word-count.