26

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",

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

4

16 回答 16

20

这适用于 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 的粘贴事件?

于 2016-06-15T15:51:51.460 回答
11

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>
于 2013-09-07T16:55:25.803 回答
9

上面的答案很棒!我做了一个小的修改,以便我们可以通过将 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;
            }
        });
    } 
于 2013-03-13T03:57:49.620 回答
4

Providing support to backspace and delete keys. My version:

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);
    }
});
于 2013-08-14T23:03:32.367 回答
4

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

我基本上采用了@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;
        }

}
于 2018-12-03T18:13:16.620 回答
3

只是为了改进 Vladimir Miroshnichenko 给出的好例子,以获得更准确的计数,主要是针对带有重音字符的语言。

我还包括 Javascript SpellChecker,因为 tinyMCE 的一个(4.1)不能再使用了。因此 ed.addButton() 将在工具栏中包含一个按钮来调用 $Spelling.SpellCheckInWindow('editors')。这与 tinyMCE 4.1.7 完美配合。

如果您更喜欢在单词而不是字符上触发警报,我还添加了单词计数。

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

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

<script type="text/javascript" src="tinymce/tinymce.min.js"></script>
<script type="text/javascript" src="JavaScriptSpellCheck/include.js"></script>

<script>
var max_chars    = 300; //max characters
var max_for_html = 1000; //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: "textarea#paragraph1",
        theme: "modern",
        plugins: [
            "advlist autolink lists charmap preview hr anchor pagebreak",
            "visualblocks visualchars insertdatetime nonbreaking",
            "directionality paste textcolor"
        ],
        menubar:false,
        statusbar:false,

        toolbar: "bold italic underline | alignleft aligncenter alignright alignjustify | forecolor backcolor | bullist numlist | charmap | preview | Spellcheck", 

        setup : function(ed) {
            ed.addButton('Spellcheck', {
                title : 'Spellcheck',
                image : '/img/dict.png',
                onclick : function() {
                    // Add you own code to execute something on click
                    $Spelling.SpellCheckInWindow('editors');
                }
            });

            ed.on("KeyDown", function(ed,evt) {
                    whtml = tinyMCE.activeEditor.getContent();

                    without_html = whtml.replace(/(<([^>]+)>)/ig,"");
                    without_html = without_html.replace(/&([A-za- z])(?:acute|cedil|caron|circ|grave|orn|ring|slash|th|tilde|uml);/ig,'$1');
                    without_html = without_html.replace(/&hellip;/ig,'...');
                    without_html = without_html.replace(/&rsquo;/ig,'\'');
                    without_html = $.trim(without_html.replace(/&([A-za-z]{2})(?:lig);/ig,'$1'));

                    chars_without_html = without_html.length;
                    chars_with_html    = whtml.length;

                    wordscount = without_html.split(/[ ]+/).length;  // Just to get the wordcount, in case...

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

    whtml = $("#paragraph1").text();

    without_html = whtml.replace(/(<([^>]+)>)/ig,"");
    without_html = without_html.replace(/&([A-za-z])(?:acute|cedil|caron|circ|grave|orn|ring|slash|th|tilde|uml);/ig,'$1');
    without_html = without_html.replace(/&hellip;/ig,'...');
    without_html = without_html.replace(/&rsquo;/ig,'\'');
    without_html = $.trim(without_html.replace(/&([A-za-z]{2})(?:lig);/ig,'$1'));

    chars_without_html = without_html.length;

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

我希望它会有所帮助,因为 tinyMCE 团队似乎在这个问题上有点固执......

于 2015-01-08T12:37:17.437 回答
2

除了您自己实现之外,没有 tinymce 配置设置max_chars

tinyMCE.init({
   ...
   max_chars : "10",
   setup : function(ed) {
      ed.onKeyDown.add(function(ed, evt) {

        if ( $(ed.getBody()).text().length > ed.getParam('max_char')){
          e.preventDefault();
          e.stopPropagation();
          return false;
        } 

      });
   }
});
于 2012-07-05T13:15:17.600 回答
2
    // Returns text statistics for the specified editor by id
function getStats(id) {
    var body = tinymce.get(id).getBody(), text = tinymce.trim(body.innerText || body.textContent);

    return {
        chars: text.length,
        words: text.split(/[\w\u2019\'-]+/).length
    };
} 





function submitForm() {
        // Check if the user has entered less than 10 characters
        if (getStats('content').chars < 10) {
            alert("You need to enter 1000 characters or more.");
            return;
        }

        // Check if the user has entered less than 1 words
        if (getStats('content').words < 1) {
            alert("You need to enter 1 words or more.");
            return;
        }

        // Submit the form
        document.forms[0].submit();
    }

http://www.tinymce.com/wiki.php/How_to_limit_number_of_characters/words

希望能帮助到你

于 2012-07-05T11:04:04.080 回答
2

该解决方案对我有用,但有一个小错误。如果您看到字符数不正确,那是因为您使用

ed.on("KeyDown")

将其更改为

ed.on("KeyUp") 

,然后它会正常工作。我没有用('Change')测试它。它也可能有效!

于 2015-05-13T13:09:44.883 回答
2

tinyMCE 不提供任何方法来限制字符并限制用户输入更多字符,唯一的方法是使用任何显式插件或您的逻辑。下面的代码显示了我提出的问题,它工作正常。

这用于具有 idsummary和另一个character_count用于显示字符数的段落 id 的 textarea。用户无法输入超过max限制的字符,在这种情况下,只有退格键有效。如果键在条件中,您可以通过提供 ascii 值来自由使用任何键。

tinymce.init({
  selector: '#summary',  // change this value according to your HTML
  auto_focus: 'element1',
  statusbar: false,
  toolbar: 'undo redo | styleselect | bold italic underline | formatselect | aligncenter | fontselect',
  setup: function (ed) {
            ed.on('KeyDown', function (e) { 
                var max = 150;
                var count = CountCharacters();
                if (count >= max) {
                        if(e.keyCode != 8 && e.keyCode != 46)
                          tinymce.dom.Event.cancel(e);
                          document.getElementById("character_count").innerHTML = "Maximun allowed character is: 150";

                } else {
                    document.getElementById("character_count").innerHTML = "Characters: " + count;
                 }
            });

        }
 });

 function CountCharacters() {
    var body = tinymce.get("summary").getBody();
    var content = tinymce.trim(body.innerText || body.textContent);
    return content.length;
};
于 2016-03-31T11:41:38.450 回答
2

下面的解决方案对我很有用: 1 - 在 textarea 的 html 代码中,必须包含 maxlength 的值和 textarea 的 id。
2 - 在脚本部分,代码如下。如果需要,请取消注释 alert() 行,然后输入您的消息。

<script type="text/javascript">
  tinymce.init ({
    ...
    ...
      setup: function(ed) {
        var maxlength = parseInt($("#" + (ed.id)).attr("maxlength"));
        var count = 0;
        ed.on("keydown", function(e) {
          count++;
          if (count > maxlength) {
            // alert("You have reached the character limit");
            e.stopPropagation();
            return false;
          }
        });
     },
<textarea type="text" id="test" name="test" maxlength="10"></textarea>

于 2018-05-23T19:57:38.087 回答
1

好的,新的 tinyMCE4X 有点变化。

    tinymce.init({
    charLimit : 10, // this is a default value which can get modified later
    setup: function(editor) {
        editor.on('change', function(e) {
            //define local variables
            var tinymax, tinylen, htmlcount;
            //setting our max character limit
            tinymax = this.settings.charLimit;
            //grabbing the length of the curent editors content
            tinylen = this.getContent().length;
            if (tinylen > tinymax) {
                alert('to big');
            }
        });
    }
    });
于 2013-07-02T10:13:18.183 回答
1

如果您在这里,也许您正在寻找简单的解决方案。这是我的解决方案。它并不完美,但非常简单

var max_length = 3;
    tinymce.init({
        selector: '#description',
        // some my settings for tiny mce
        toolbar: ' undo redo | bold italic | formatselect',
        setup : function(ed) {
           // important part
           ed.on("keypress", function(event){
                // get content of the tinymce and remove tags
                // tinymce will be adding tags while you type in it.
                // when tags are removed, you will heave real input length (the one that customer sees)
                var content =  tinymce.activeEditor.getContent().replace(/(<([^>]+)>)/ig,"");
                // now just compare that length to your prefered length.
                // if it is larger or same, return false, and that will disregard last input.
                if(content.length >= max_length){
                    return false;
                }
            });
        }

    });
于 2020-05-14T21:19:28.897 回答
0

最简单的方法:

contentContentLenght = tinyMCE.activeEditor.getContent({format : 'text'}).length; //takes lenght of current editor

if (contentContentLenght > 1499) {
                    e.preventDefault();
                    e.stopPropagation();
                    return false;
                } // 1500 is my limit in mine project.

防止粘贴:

editor.on('paste', function(e){
            contentContentLenght = tinyMCE.activeEditor.getContent({format : 'text'}).length;
            var data = e.clipboardData.getData('Text');
            if (data.length > (1500 - contentContentLenght)) {
                return false;
            } else {
                return true;
            }
        });
于 2017-01-12T14:26:07.057 回答
0

TinyMCE + AngularJS

这是使用ng-maxlengthAngularJS 指令限制前端最大字符数的方法。

参数ngMaxlength
类型:数字
详细信息maxlength:如果值长于最大长度,则设置验证错误键。

请注意,该指令不仅计算显示的文本字符,还计算<textarea>HTML 中的所有文本,如标签和脚本。

首先,包括AngularJSTinyMCE 4 分布式和TinyMCE 的 AngularUI 包装器

HTML:

<form name="form" action="#">
    <textarea ng-model="myMCEContent" ui-tinymce ng-maxlength="200" name="body"></textarea>
    <span ng-show="form.body.$error.maxlength" class="error">Reached limit!/span>
</form>

JavaScript:

angular.module('myApp', ['ui.tinymce'])
.config(['$sceProvider', function($sceProvider) {
    // Disable Strict Contextual Escaping
    $sceProvider.enabled(false);
}])
.constant('uiTinymceConfig', {/*...*/})
.controller('myCtrl', ['$scope', function($scope) {
    // ...
}]);

jsFiddle

!注意力 !

在使用此解决方案之前阅读手册以充分了解在 AngularJS 中禁用 SCE 的后果:$sce service

于 2016-01-18T11:59:31.930 回答
-1

Thariama 的答案很棒,刚刚实现了它,这正是我想要的,只是做了一些修改:

    max_chars : "10",
    setup : function(ed) {
        ed.onKeyDown.add(function(ed, evt) {
            if ( $(ed.getBody()).text().length+1 > ed.getParam('max_chars')){
                evt.preventDefault();
                evt.stopPropagation();
                return false;
            }
        });
    } 

谢谢塔里亚马。

于 2013-01-23T16:38:18.833 回答