it-swarm.com.de

Begrenzung der Anzahl von Zeichen in einem ContentEditable-Div

Ich verwende inhaltsfähige Div-Elemente in meiner Webanwendung und versuche, eine Lösung zu finden, um die Anzahl der Zeichen zu begrenzen, die in diesem Bereich zulässig sind. Sobald das Limit erreicht ist, versucht der Versuch, Zeichen einzugeben, nichts. Das habe ich bisher:

var content_id = 'editable_div';

//binding keyup/down events on the contenteditable div
$('#'+content_id).keyup(function(){ check_charcount(content_id, max); });
$('#'+content_id).keydown(function(){ check_charcount(content_id, max); });

function check_charcount(content_id, max)
{   
    if($('#'+content_id).text().length > max)
    {
        $('#'+content_id).text($('#'+content_id).text().substring(0, max));
    }
}

Diese DOES beschränken die Anzahl der Zeichen auf die durch 'max' angegebene Anzahl. Sobald der Text des Bereichs mit der Funktion jquery.text () festgelegt wurde, setzt sich der Cursor an den Anfang des Bereichs. Wenn der Benutzer also weiter tippt, werden die neu eingegebenen Zeichen am Anfang des Textes eingefügt und das letzte Zeichen des Textes wird entfernt. Ich brauche also nur einen Weg, um den Cursor am Ende des inhaltbaren Bereichs zu halten. 

32
Bill Dami

Wie wäre es, wenn Sie das event-Objekt an Ihre Funktion übergeben und e.preventDefault() aufrufen, wenn das Maximum erreicht ist?

var content_id = 'editable_div';  

max = 10;

//binding keyup/down events on the contenteditable div
$('#'+content_id).keyup(function(e){ check_charcount(content_id, max, e); });
$('#'+content_id).keydown(function(e){ check_charcount(content_id, max, e); });

function check_charcount(content_id, max, e)
{   
    if(e.which != 8 && $('#'+content_id).text().length > max)
    {
       // $('#'+content_id).text($('#'+content_id).text().substring(0, max));
       e.preventDefault();
    }
}

Möglicherweise müssen Sie jedoch ein wenig mehr tun, damit der Benutzer beispielsweise "Löschen" ausführen kann.


BEARBEITEN:

Unterstützung für die Löschtaste hinzugefügt.


EDIT 2:

Außerdem könnten Sie wahrscheinlich den keyup-Handler loswerden. keydown sollte ausreichen.

42
user113716

Ein einfacher Weg, um dies zu erreichen:

<div onkeypress="return (this.innerText.length <= 256)" contenteditable="true">
19
Bala Velayutham

Erstens ist dies für den Benutzer irritierend: Ich würde stattdessen etwas Ähnliches wie das Kommentarfeld von StackOverflow vorschlagen, in dem Sie so viel oder so wenig eingeben können, wie Sie möchten, und eine Meldung mit der Anzahl der eingegebenen Zeichen wird angezeigt und ob es zu viele oder zu wenige ist und nicht zulässt, dass Sie einen Kommentar einreichen, dessen Länge nicht gültig ist.

Zweitens: Wenn Sie wirklich die Länge des Textes begrenzen müssen, ist das Ersetzen des gesamten Inhalts von <div> bei jedem Tastendruck, wenn der Inhalt zu lang ist, unnötig teuer und führt dazu, dass der Editor auf langsameren Computern nicht reagiert. Ich schlage vor, das Ereignis keypress zu behandeln und einfach zu verhindern, dass das Zeichen mit preventDefault() für das Ereignis eingefügt wird (oder im IE, indem die Variable returnValue des Ereignisses auf true gesetzt wird, vorausgesetzt, Sie verwenden attachEvent). Dies hindert den Benutzer nicht daran, Text einzufügen. Daher müssen Sie das paste -Ereignis behandeln (das in Opera oder Firefox <3 nicht vorhanden ist. Daher benötigen Sie eine abfragebasierte Lösung für diese). . Da Sie im Voraus nicht auf den eingefügten Inhalt zugreifen können, wissen Sie nicht, ob Sie durch das Einfügen das Zeichenlimit überschreiten. Daher müssen Sie einen Timer einstellen, um die Länge in Kürze erneut überprüfen zu können nach der Paste Unter diesen Umständen scheint mir die erste Option vorzuziehen.

16
Tim Down

Die folgende Lösung berücksichtigt auch die Steuertasten (die nicht druckbaren Zeichen entsprechen).

//Maximum number of characters
var max = 200;

$('#editable_div').keydown(function(e) {
    var keycode = e.keyCode;

    //List of keycodes of printable characters from:
    //http://stackoverflow.com/questions/12467240/determine-if-javascript-e-keycode-is-a-printable-non-control-character
    var printable = 
        (keycode > 47 && keycode < 58)   || // number keys
        keycode == 32 || keycode == 13   || // spacebar & return key(s) (if you want to allow carriage returns)
        (keycode > 64 && keycode < 91)   || // letter keys
        (keycode > 95 && keycode < 112)  || // numpad keys
        (keycode > 185 && keycode < 193) || // ;=,-./` (in order)
        (keycode > 218 && keycode < 223);   // [\]' (in order)

    if (printable) {
        //Based on the Bala Velayutham's answer
        return $(this).text().length <= max; 
    }
});
4
Vito Gentile

Auf diese Weise habe ich es durch jQuery-Bindung so gemacht, dass es für mich einfach ist, indem ich einem inhaltsfähigen Element einfach eine Eigenschaft data-input-length hinzufügt .. _.

$(document).ready(function(){
	// Excempt keys(arrows, del, backspace, home, end);
	var excempt = [37,38,39,40,46,8,36,35];
	// Loop through every editiable thing
	$("[contenteditable='true']").each(function(index,elem) {
	    var $elem = $(elem);
	    // Check for a property called data-input-length="value" (<div contenteditiable="true" data-input-length="100">)
	    var length = $elem.data('input-length');
	    // Validation of value
	    if(!isNaN(length)) {
	    	// Register keydown handler
	        $elem.on('keydown',function(evt){
	        	// If the key isn't excempt AND the text is longer than length stop the action.
	            if(excempt.indexOf(evt.which) === -1 && $elem.text().length > length) {
	               evt.preventDefault();
	               return false;
	            }
	        });
	    }
	});
});
div {
  background-color:#eee;
  border: 1px solid black;
  margin:5px;
  width:300px;
  height:100px;
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div contenteditable="true" data-input-length="100">
You can type a 100 characters here
</div>
<div contenteditable="true" data-input-length="150">
You can type a 150 characters here
</div>
<div contenteditable="true" data-input-length="10">
You can type a 10 characters here
</div>

4
Tschallacka

Dies ist der beste Weg, um diese am meisten verallgemeinernde Form zu machen und einfach großartig für mich zu arbeiten!

<div contenteditable="true" name="choice1" class="textfield" max="255"></div>
    $('.textfield').on("keypress paste", function (e) {
        if (this.innerHTML.length >= this.getAttribute("max")) {
            e.preventDefault();
            return false;
        }
    });
3
VizardCrawler
$("[contenteditable=true]").keydown(function(e) {
    var max = $(this).attr("maxlength");
    if (e.which != 8 && $(this).text().length > max) {
        e.preventDefault();
    }
});
1
Yuval Perelman

Eine allgemeinere Überarbeitung der Antwort von @ user113716, die nicht für mehrere inhaltsbearbeitbare Felder geeignet ist (sie zählt die Gesamtzahl der Zeichen für alle Elemente, die der angegebenen ID entsprechen. Daher können Sie nur die Maximalzeichen total auf der Seite eingeben) .

Diese Lösung ermöglicht es Ihnen, eine allgemeine Klasse zu verwenden, und begrenzt die Anzahl der Zeichen in jedem inhaltsfähigen Feld unabhängig.

die html:

<div contenteditable="true" name="choice1" class="textfield"></div>

Und das JavaScript:

MAX_TEXTINPUT = 10;
TEXTFIELD_CLASS = "textfield"

$(document).ready(function() {

    //binding keyup/down events on the contenteditable div
    $('.'+TEXTFIELD_CLASS).keydown(function(e){ check_charcount(TEXTFIELD_CLASS, MAX_TEXTINPUT, e); });

})

function check_charcount(inputclass, max, e) {   
    var focused = $(document.activeElement)

    if(focused.hasClass(inputclass) && e.which != 8 && $(focused).text().length >= max)
    {
        e.preventDefault();
    }
}
0
Wes Modes

Eine andere Version der Antwort von @ user113716. Unterstützt "Einfügen" -Ereignis und einige Text-Hotkeys wie STRG + A.

$('#'+content_id).on('keydown paste', function (e) { maxLimitForContenteditableDiv(e, 140) });

function maxLimitForContenteditableDiv(e, limit) {
    var allowedKeys = false;

    if (e.type === 'keydown') {
        allowedKeys = (
            e.which === 8 ||  /* BACKSPACE */
            e.which === 35 || /* END */
            e.which === 36 || /* HOME */
            e.which === 37 || /* LEFT */
            e.which === 38 || /* UP */
            e.which === 39 || /* RIGHT*/
            e.which === 40 || /* DOWN */
            e.which === 46 || /* DEL*/
            e.ctrlKey === true && e.which === 65 || /* CTRL + A */
            e.ctrlKey === true && e.which === 88 || /* CTRL + X */
            e.ctrlKey === true && e.which === 67 || /* CTRL + C */
            e.ctrlKey === true && e.which === 86 || /* CTRL + V */
            e.ctrlKey === true && e.which === 90    /* CTRL + Z */
        )
    }

    if (e.type === 'paste') {
        setTimeout(function () {
            $(e.target).text($(e.target).text().slice(0, limit));
        });
    }

    if (!allowedKeys && $(e.target).text().length >= limit) {
        e.preventDefault();
    }
0
vodnycheck
var onKeyPress = function () {
    var keyCode = window.event.keyCode,
        isNumeric = (keyCode > 47 && keyCode < 58),
        isNotEnterKey = !!(window.event.keyCode !== 13);

        (isNotEnterKey) || (this.blur());

        return (isNumeric && this.innerText.length < 3);
};
0
shawndumas

Wenn Sie möchten, dass es mit Klassen funktioniert. Mit anderen Worten, Element könnte Klassennamen gemeinsam nutzen und hat trotzdem eine eigene eindeutige Anzahl: 

var content_id = '.myclass';  

max = 1;
//binding keyup/down events on the contenteditable div
$(content_id).keyup(function(e){ check_charcount(this, max, e); });
$(content_id).keydown(function(e){ check_charcount(this, max, e); });

function check_charcount(elem, max, e){   
    if(e.which != 8 && $(elem).text().length >= max){       
        e.preventDefault();
    }
}
0
Al Serize