限制 tinyMCE 中的字符数

IT技术 javascript tinymce rte
2021-02-20 17:59:24

tinyMCe用于我的项目。一切正常,但现在我想限制将插入到tinyMcetextarea的字符数

tinyMCE.init({
// General options
mode : "textareas",
theme : "simple",
plugins : "autolink,lists,pagebreak,style,table,save,advhr,advimage,advlink,emotions,media,noneditable,nonbreaking",

// Theme options
theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,fontselect,fontsizeselect",
theme_advanced_buttons2 : "bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,code,|,forecolor,backcolor",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
theme_advanced_statusbar_location : "bottom",
max_chars : "10",
max_chars_indicator : "lengthBox",
theme_advanced_resizing : true
});

我用了 :-

max_chars : "10",
max_chars_indicator : "lengthBox",

但仍然无法正常工作。提前致谢。

6个回答

这适用于 tinyMCE 4.3.12 并捕获粘贴:

编辑:修复了错误和扩展代码以在编辑器下显示字符计数器。可能不是最好的方法,因为它有点依赖于 tinyMCE 的当前 HTML 结构,在隐藏的文本区域之前有编辑器 div。

此版本只计算文本长度,忽略 HTML 标签长度。要计算完整的 HTML 长度,请将所有“innerText”替换为“innerHTML”。

tinymce.init({
    max_chars: 1000, // max. allowed chars
    setup: function (ed) {
        var allowedKeys = [8, 37, 38, 39, 40, 46]; // backspace, delete and cursor keys
        ed.on('keydown', function (e) {
            if (allowedKeys.indexOf(e.keyCode) != -1) return true;
            if (tinymce_getContentLength() + 1 > this.settings.max_chars) {
                e.preventDefault();
                e.stopPropagation();
                return false;
            }
            return true;
        });
        ed.on('keyup', function (e) {
            tinymce_updateCharCounter(this, tinymce_getContentLength());
        });
    },
    init_instance_callback: function () { // initialize counter div
        $('#' + this.id).prev().append('<div class="char_count" style="text-align:right"></div>');
        tinymce_updateCharCounter(this, tinymce_getContentLength());
    },
    paste_preprocess: function (plugin, args) {
        var editor = tinymce.get(tinymce.activeEditor.id);
        var len = editor.contentDocument.body.innerText.length;
        var text = $(args.content).text();
        if (len + text.length > editor.settings.max_chars) {
            alert('Pasting this exceeds the maximum allowed number of ' + editor.settings.max_chars + ' characters.');
            args.content = '';
        } else {
            tinymce_updateCharCounter(editor, len + text.length);
        }
    }
});

function tinymce_updateCharCounter(el, len) {
    $('#' + el.id).prev().find('.char_count').text(len + '/' + el.settings.max_chars);
}

function tinymce_getContentLength() {
    return tinymce.get(tinymce.activeEditor.id).contentDocument.body.innerText.length;
}

参考:如何防止 tinyMCE 的粘贴事件?

如果使用innerHTML,并且您应用了一些格式,则计数器不会更新
2021-05-03 17:59:24
这在var text = $(args.content).text();whenargs.content不是 HTML,而是例如从记事本复制的文本中断
2021-05-04 17:59:24
迟到了,但尽量var text = $('<div/>').html(args.content).text();涵盖所有关于 HMTL/纯文本粘贴的基础。
2021-05-06 17:59:24

TinyMCE 4+
+
jQuery

<textarea id="description_edit" name="description_edit"><?=htmlspecialchars($this->company->description);?></textarea>

<div><span>Characters left:</span> <span id="chars_left"></span></div>


<script type="text/javascript" src="/js/tinymce/tinymce.min.js"></script>
<script>
    var max_chars = 200; //max characters
    var max_for_html = 300; //max characters for html tags
    var allowed_keys = [8, 13, 16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 46];
    var chars_without_html = 0;

    function alarmChars() {
        if (chars_without_html > (max_chars - 25)) {
            $('#chars_left').css('color', 'red');
        } else {
            $('#chars_left').css('color', 'gray');
        }
    }

    $(function () {
        tinymce.init({
            selector: "#description_edit",
            theme: "modern",
            width: 320,
            height: 130,
            plugins: [
                "advlist autolink lists charmap print preview hr anchor pagebreak",
                "searchreplace visualblocks visualchars code insertdatetime media nonbreaking",
                "save table contextmenu directionality paste textcolor"
            ],
            image_advtab: true,
            language: 'en',
            menubar: false,
            statusbar: false,

            setup: function (ed) {
                ed.on("KeyDown", function (ed, evt) {
                    chars_without_html = $.trim(tinyMCE.activeEditor.getContent().replace(/(<([^>]+)>)/ig, "")).length;
                    chars_with_html = tinyMCE.activeEditor.getContent().length;
                    var key = ed.keyCode;

                    $('#chars_left').html(max_chars - chars_without_html);

                    if (allowed_keys.indexOf(key) != -1) {
                        alarmChars();
                        return;
                    }

                    if (chars_with_html > (max_chars + max_for_html)) {
                        ed.stopPropagation();
                        ed.preventDefault();
                    } else if (chars_without_html > max_chars - 1 && key != 8 && key != 46) {
                        alert('Characters limit!');
                        ed.stopPropagation();
                        ed.preventDefault();
                    }
                    alarmChars();
                });
            },

            toolbar: "bold italic underline | alignleft aligncenter alignright alignjustify | forecolor backcolor | bullist numlist | charmap",
            style_formats: [
                {title: 'Bold text', inline: 'b'},
                {title: 'Red text', inline: 'span', styles: {color: '#ff0000'}},
                {title: 'Red header', block: 'h1', styles: {color: '#ff0000'}},
                {title: 'Example 1', inline: 'span', classes: 'example1'},
                {title: 'Example 2', inline: 'span', classes: 'example2'},
                {title: 'Table styles'},
                {title: 'Table row 1', selector: 'tr', classes: 'tablerow1'}
            ]
        });

        chars_without_html = $.trim($("#description_edit").text().replace(/(<([^>]+)>)/ig, "")).length;
        $('#chars_left').html(max_chars - chars_without_html);
        alarmChars();
    });
</script>
如果您在一页上有多个 textarea,这将不起作用
2021-04-23 17:59:24

楼上的回答太好了!我做了一个小的修改,以便我们可以通过将 max_chars 作为属性添加到 textarea 元素本身来设置它

setup : function(ed) {
        ed.onKeyDown.add(function(ed, evt) {
            //if ( $(ed.getBody()).text().length+1 > ed.getParam('max_chars')){
            if ( $(ed.getBody()).text().length+1 > $(tinyMCE.get(tinyMCE.activeEditor.id).getElement()).attr('max_chars')){
                evt.preventDefault();
                evt.stopPropagation();
                return false;
            }
        });
    } 
仅供Uncaught TypeError: Cannot read property 'add' of undefined使用ed.on('keyDown', function(e) { ... });:)
2021-04-17 17:59:24
亲爱的敏锐,我试过这个解决方案,但萤火虫说 onKeyDown 事件未知,我做错了什么?
2021-04-20 17:59:24
这个解决方案有一个非常丑陋的错误。可以工作,但是当您输入的字符数超过允许的数量时,它不会让您按更多键,甚至不能按退格键/删除键:P
2021-04-22 17:59:24
我在 Chrome 上尝试了这个解决方案,但它给了我 Uncaught TypeError: Cannot read property 'add' of undefined
2021-05-09 17:59:24

提供对退格键和删除键的支持。我的版本:

max_chars : 2000,
max_chars_indicator : ".maxCharsSpan",

setup : function(ed) {  
    wordcount = 0;
    wordCounter = function (ed, e) {
        text = ed.getContent().replace(/<[^>]*>/g, '').replace(/\s+/g, ' ');
        text = text.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
        this.wordcount = ed.getParam('max_chars') - text.length;
        $(ed.getParam('max_chars_indicator')).text( this.wordcount + " (out of " +ed.getParam('max_chars')+ ") char(s) left." );
    };

    ed.onKeyUp.add( wordCounter );

    ed.onKeyDown.add(function(ed, e) {
    if (this.wordcount <= 0 && e.keyCode != 8 && e.keyCode != 46) {
         tinymce.dom.Event.cancel(e);
    }
});

这是对我有用的解决方案。

我基本上采用了@needfulthing 提供的代码并修复了错误并对其进行了改进。

function initTinymce(){

        tinymce.init({
            selector: '.richtext-editable',
            plugins: ['paste'],

            max_chars: 50000, // max. allowed chars

            setup: function (ed) {                              
                var allowedKeys = [8, 13, 16, 17, 18, 20, 33, 34, 35, 36, 37, 38, 39, 40, 46];
                ed.on('keydown', function (e) {
                    if (allowedKeys.indexOf(e.keyCode) != -1) return true;
                    if (tinymce_getContentLength() + 1 > this.settings.max_chars) {
                        e.preventDefault();
                        e.stopPropagation();
                        return false;
                    }
                    return true;
                });
                ed.on('keyup', function (e) {
                    tinymce_updateCharCounter(this, tinymce_getContentLength());
                });                             
            },

            init_instance_callback: function () { // initialize counter div
                $('#' + this.id).prev().append('<div class="char_count" style="text-align:right"></div>');
                tinymce_updateCharCounter(this, tinymce_getContentLength());
            },

            paste_preprocess: function (plugin, args) {                             
                var editor = tinymce.get(tinymce.activeEditor.id);
                var len = editor.contentDocument.body.innerText.length;                             
                if (len + args.content.length > editor.settings.max_chars) {
                    alert('Pasting this exceeds the maximum allowed number of ' + editor.settings.max_chars + ' characters for the input.');
                    args.content = '';
                }                                   
                tinymce_updateCharCounter(editor, len + args.content.length);                               
            }

        });

        function tinymce_updateCharCounter(el, len) {
            $('#' + el.id).prev().find('.char_count').text(len + '/' + el.settings.max_chars);
        }

        function tinymce_getContentLength() {
            return tinymce.get(tinymce.activeEditor.id).contentDocument.body.innerText.length;
        }

}
祝愿 2019 NY 繁荣昌盛!我试图采用您的解决方案作为 TinyMCE 的自定义插件,但它不起作用。Thx 如果你看我的问题stackoverflow.com/q/53986299/2637838
2021-04-28 17:59:24
与我的帖子相关,您似乎删除了 tinymce.init 部分。我使用它的方式是在某个初始时刻调用 initTinymce() 函数,例如在页面加载时。您还删除了选择器:'.richtext-editable' 部分,我通过将该标签设置为输入元素的类样式来使用它。
2021-05-02 17:59:24