Jak narzucić maxlength na textArea w HTML za pomocą JavaScript

116

Chciałbym mieć jakąś funkcjonalność, o której piszę

<textarea maxlength="50"></textarea>
<textarea maxlength="150"></textarea>
<textarea maxlength="250"></textarea>

automatycznie narzuci maxlength na textArea. Jeśli to możliwe, nie dostarczaj rozwiązania w jQuery.

Uwaga: można to zrobić, jeśli zrobię coś takiego:

<textarea onkeypress="return imposeMaxLength(event, this, 110);" rows="4" cols="50">

function imposeMaxLength(Event, Object, MaxLen)
{
    return (Object.value.length <= MaxLen)||(Event.keyCode == 8 ||Event.keyCode==46||(Event.keyCode>=35&&Event.keyCode<=40))
}

Skopiowano z Jaki jest najlepszy sposób emulacji atrybutu wejściowego HTML „maxlength” w obszarze tekstowym HTML?

Ale chodzi o to, że nie chcę pisać onKeyPress i onKeyUp za każdym razem, gdy deklaruję textArea.

Rakesh Juyal
źródło
4
wartość maksymalna dla obszarów tekstowych jest w html5. W tej chwili działa w przeglądarce Chrome, ale nie Firefox.
Dave,

Odpowiedzi:

113
window.onload = function() { 
  var txts = document.getElementsByTagName('TEXTAREA'); 

  for(var i = 0, l = txts.length; i < l; i++) {
    if(/^[0-9]+$/.test(txts[i].getAttribute("maxlength"))) { 
      var func = function() { 
        var len = parseInt(this.getAttribute("maxlength"), 10); 

        if(this.value.length > len) { 
          alert('Maximum length exceeded: ' + len); 
          this.value = this.value.substr(0, len); 
          return false; 
        } 
      }

      txts[i].onkeyup = func;
      txts[i].onblur = func;
    } 
  };

}
Josh Stodola
źródło
3
Josh, wygląda na to, że zadziała, ale proszę wyjaśnij, co to zrobi --- if (/ ^ [0-9] + $ /. Test (txts [i] .getAttribute ("maxlength"))) {- -
Rakesh Juyal
2
Myślę, że pamiętam, o co chodzi: FF lub IE (myślę, że to FF) zwraca inny ciąg, gdy JavaScript sprawdza atrybut „wartość”, niż to, co wysyła z powrotem do serwera po wysłaniu formularza! Ma to coś wspólnego z tym, jak twarde podziały wierszy powodują / nie powodują wstawienia znaku powrotu karetki. Łatwo to rozgryźć, używając kodu debugowania po stronie klienta i serwera.
Pointy
7
Zmieniłem kolejność ostrzeżenia i obcięcie wartości - w pierwotnej kolejności włączanie klawisza zaalarmowało, powodując utratę koncentracji, a onblur zaczął strzelać, ponieważ pole nie zostało jeszcze obcięte.
GalacticCowboy
1
@JoshStodola - onblurnie obsłuży wklejania, dopóki użytkownik nie wyjdzie z obszaru tekstu. onkeyupnie obsłuży wklejania, jeśli odbywa się to za pośrednictwem menu kontekstowego lub menu przeglądarki. To podejście działa, jeśli nie musisz sprawdzać w celu wklejenia. Zobacz tę odpowiedź, aby zapoznać się z podejściem opartym na zegarze stackoverflow.com/a/10390626/1026459
Travis J
3
@JoshStodola - Rzeczywiście nie możesz. Byłbym naprawdę zirytowany jako użytkownik, gdybym wkleił cały fragment czegoś w obszarze tekstowym, kliknąłem Prześlij i zobaczyłem tylko niewielką część tego, która przechodzi bez odpowiedzi.
Travis J
80

Wiem, że chcesz uniknąć jQuery, ale ponieważ rozwiązanie wymaga JavaScript, to rozwiązanie (przy użyciu jQuery 1.4) jest najbardziej zrozumiałe i niezawodne.

Zainspirowany, ale lepszy od odpowiedzi Dany Woodman:

Zmiany w tej odpowiedzi to: Uproszczone i bardziej ogólne, przy użyciu jQuery.live, a także bez ustawiania wartości, jeśli długość jest OK (prowadzi do działających klawiszy strzałek w IE i zauważalnego przyspieszenia w IE):

// Get all textareas that have a "maxlength" property. Now, and when later adding HTML using jQuery-scripting:
$('textarea[maxlength]').live('keyup blur', function() {
    // Store the maxlength and value of the field.
    var maxlength = $(this).attr('maxlength');
    var val = $(this).val();

    // Trim the field if it has content over the maxlength.
    if (val.length > maxlength) {
        $(this).val(val.slice(0, maxlength));
    }
});

EDYCJA: Zaktualizowana wersja dla jQuery 1.7+ , używając onzamiastlive

// Get all textareas that have a "maxlength" property. Now, and when later adding HTML using jQuery-scripting:
$('textarea[maxlength]').on('keyup blur', function() {
    // Store the maxlength and value of the field.
    var maxlength = $(this).attr('maxlength');
    var val = $(this).val();

    // Trim the field if it has content over the maxlength.
    if (val.length > maxlength) {
        $(this).val(val.slice(0, maxlength));
    }
});
Eirik W
źródło
1
Fajny Eirik, jak na żywo (zapomniałem o tym!).
Dana Woodman
5
Znalazłem błędy w live (), a jQuery od tego czasu jest przestarzałe. Zamiast tego użyj on (). Jeśli obchodzi Cię dlaczego: britishdeveloper.co.uk/2012/04/…
BritishDeveloper
6
Ale jeśli edytowali w środku, zabije to ostatnią postać, a nie nową postać, prawda?
Joe Mabel
6
Tak używane w () i działa jak klejnot. Dzięki. oto zmodyfikowane i nieco poprawione
B-Money
6
Problem z krojeniem polega na tym, że jeśli wprowadzisz znaki do środka, są one wstawiane, a ciąg jest odcinany od końca. Jeśli cały tekst nie jest widoczny od razu, może to być mylące. Również użycie funkcji val (..) do zmiany wartości wydaje się przenosić kursor na koniec ciągu. (jeśli chcesz je przetestować za pomocą nowoczesnej przeglądarki w skrzypcach, musisz usunąć atrybut maxlength - w przeciwnym razie przeglądarka wymusi ograniczenie).
Juha Palomäki
33

Zaktualizuj Użyj rozwiązania Eirik, używając .live()zamiast tego, ponieważ jest nieco bardziej niezawodne.


Chociaż chciałeś rozwiązania, które nie używa jQuery, pomyślałem, że dodam je dla każdego, kto znajdzie tę stronę za pośrednictwem Google i szuka rozwiązania w stylu jQuery:

$(function() {        
    // Get all textareas that have a "maxlength" property.
    $('textarea[maxlength]').each(function() {

        // Store the jQuery object to be more efficient...
        var $textarea = $(this);

        // Store the maxlength and value of the field.
        var maxlength = $textarea.attr('maxlength');
        var val = $textarea.val();

        // Trim the field if it has content over the maxlength.
        $textarea.val(val.slice(0, maxlength));

        // Bind the trimming behavior to the "keyup" event.
        $textarea.bind('keyup', function() {
            $textarea.val($textarea.val().slice(0, maxlength));
        });

    });
});

Mam nadzieję, że jest to przydatne dla pracowników Google ...

Dana Woodman
źródło
1
Funkcja powiązana z kluczem powinna wyglądać następująco: $ (this) .val ($ (this) .val (). Slice (0, maxlength));
Brian Vallelunga
@brian Tak, masz rację. Dzięki za wykrycie mojego błędu, naprawiono!
Dana Woodman
$ (this) .val (function (i, val) {return val.slice (0, maxlength)});
Dima Bildin
ten fragment jest nadal pomocny, ponieważ nowe wiersze są liczone jako 1 znak w przeglądarce i 2 na serwerze ...
bebbo
32

HTML5 dodaje maxlengthatrybut do textareaelementu, na przykład:

<!DOCTYPE html>
<html>
    <body>
        <form action="processForm.php" action="post">
            <label for="story">Tell me your story:</label><br>
            <textarea id="story" maxlength="100"></textarea>
            <input type="submit" value="Submit">
        </form>
    </body>
</html>

Jest to obecnie obsługiwane w Chrome 13, FF 5 i Safari 5. Nic dziwnego, że nie jest obsługiwane w IE 9. (testowane na Win 7)

james.garriss
źródło
5

To rozwiązanie pozwala uniknąć problemu w IE, gdzie ostatni znak jest usuwany, gdy dodawany jest znak w środku tekstu. Działa również dobrze z innymi przeglądarkami.

$("textarea[maxlength]").keydown( function(e) {
    var key = e.which;  // backspace = 8, delete = 46, arrows = 37,38,39,40

    if ( ( key >= 37 && key <= 40 ) || key == 8 || key == 46 ) return;

    return $(this).val().length < $(this).attr( "maxlength" );
});

Moja walidacja formularza zajmuje się następnie wszelkimi problemami, w których użytkownik mógł wkleić (tylko wydaje się, że jest to problem w IE) tekst przekraczający maksymalną długość obszaru tekstu.

Chris R.
źródło
4

To jest trochę zmodyfikowany kod, którego właśnie używałem w mojej witrynie. Ulepszono wyświetlanie użytkownikowi liczby pozostałych znaków.

(Jeszcze raz przepraszam dla OP, który nie zażądał jQuery. Ale poważnie, kto nie używa obecnie jQuery?)

$(function() {
    // Get all textareas that have a "maxlength" property.
    $("textarea[maxlength]").each(function() {

        // Store the jQuery object to be more efficient...
        var $textarea = $(this);

        // Store the maxlength and value of the field
        var maxlength = $textarea.attr("maxlength");

        // Add a DIV to display remaining characters to user
        $textarea.after($("<div>").addClass("charsRemaining"));

        // Bind the trimming behavior to the "keyup" & "blur" events (to handle mouse-based paste)
        $textarea.on("keyup blur", function(event) {
            // Fix OS-specific line-returns to do an accurate count
            var val = $textarea.val().replace(/\r\n|\r|\n/g, "\r\n").slice(0, maxlength);
            $textarea.val(val);
            // Display updated count to user
            $textarea.next(".charsRemaining").html(maxlength - val.length + " characters remaining");
        }).trigger("blur");

    });
});

NIE został przetestowany z międzynarodowymi znakami wielobajtowymi, więc nie jestem pewien, jak to dokładnie działa.

Simon East
źródło
2

Dodaj również następujące zdarzenie, aby poradzić sobie z wklejaniem do obszaru tekstu:

...

txts[i].onkeyup = function() {
  ...
}

txts[i].paste = function() {
  var len = parseInt(this.getAttribute("maxlength"), 10);

  if (this.value.length + window.clipboardData.getData("Text").length > len) {
    alert('Maximum length exceeded: ' + len);
    this.value = this.value.substr(0, len);
    return false;
  }
}

...
stusherwin
źródło
Czy ktoś mógłby dodać to do treści odpowiedzi, jeśli uważa, że ​​wszystko jest w porządku? Nie masz jeszcze wystarczającej liczby punktów, aby to zrobić.
stusherwin
Funkcja wklejania nie jest znormalizowana. Uważam, że działa tylko w IE.
Josh Stodola
Zaktualizowałem odpowiedź, aby poradzić sobie z sytuacją wklejania. Dziękuję Ci!
Josh Stodola
2

Atrybut maxlength jest obsługiwany w przeglądarkach Internet Explorer 10, Firefox, Chrome i Safari.

Uwaga: atrybut maxlength <textarea>tagu nie jest obsługiwany w przeglądarce Internet Explorer 9 i wcześniejszych wersjach ani w przeglądarce Opera.

z HTML maxlength Attribute w3schools.com

W przypadku IE8 lub wcześniejszych wersji musisz użyć następującego

//only call this function in IE
function maxLengthLimit($textarea){
    var maxlength = parseInt($textarea.attr("maxlength"));
    //in IE7,maxlength attribute can't be got,I don't know why...
    if($.browser.version=="7.0"){
        maxlength = parseInt($textarea.attr("length"));
    }
    $textarea.bind("keyup blur",function(){
        if(this.value.length>maxlength){
            this.value=this.value.substr(0,maxlength);
        }
    });
}

PS

Atrybut maxlength <input>tagu jest obsługiwany we wszystkich głównych przeglądarkach.

z HTML maxlength Attribute w3schools.com

Eason
źródło
1

Lepsze rozwiązanie w porównaniu do przycinania wartości obszaru tekstowego.

$('textarea[maxlength]').live('keypress', function(e) {
    var maxlength = $(this).attr('maxlength');
    var val = $(this).val();

    if (val.length > maxlength) {
        return false;
    }
});
Bharat
źródło
1

Możesz użyć jQuery, aby było to łatwe i przejrzyste

JSFiddle DEMO

<textarea id="ta" max="10"></textarea>

<script>
$("#ta").keypress(function(e){

    var k = e.which==0 ? e.keyCode : e.which;
    //alert(k);
    if(k==8 || k==37 || k==39 || k==46) return true;

    var text      = $(this).val();
    var maxlength = $(this).attr("max");

    if(text.length >= maxlength) {
        return false;   
    }
    return true;
});
</script>

Jest testowane Firefox, Google ChromeaOpera

MaxEcho
źródło
Obawiam się, że kiedy handler jest wykonywany, textjest wypełniony "wartością" texarea, zanim zostanie zaktualizowany. Oznacza to, że twój test powinien być if( text.length +1 > maxlength) {return false;}. W przeciwnym razie można by umieścić tylko maxlength - 1znaki w środku:/
Stphane
Twoje skrzypce pozwalają użytkownikowi wprowadzić jeszcze jedną postać. IMO, twój test powinien być if(text.length+1 > maxlength)albo if(text.length >= maxlength)...
Stphane
Nie działa zgodnie z oczekiwaniami, kiedy kopiuję i wklejam zawartość
Ranjit Kumar
0

Mały problem z powyższym kodem polega na tym, że val () nie wyzwala zdarzenia change (), więc jeśli używasz backbone.js (lub innych frameworków do wiązania modelu), model nie zostanie zaktualizowany.

Publikuję rozwiązanie, które zadziałało świetnie.

$(function () {

    $(document).on('keyup', '.ie8 textarea[maxlength], .ie9 textarea[maxlength]', function (e) {
        var maxLength = $(this).attr('maxlength');
        if (e.keyCode > 47 && $(this).val().length >= maxLength) {
            $(this).val($(this).val().substring(0, maxLength)).trigger('change');
        }
        return true;
    });

});
Alexander Beletsky
źródło
0

Niedawno zaimplementowałem maxlengthzachowanie textareai napotkałem problem opisany w tym pytaniu: Chrome nieprawidłowo liczy znaki w obszarze tekstowym z atrybutem maxlength .

Tak więc wszystkie wymienione tutaj implementacje będą działać trochę błędnie. Aby rozwiązać ten problem, dodam .replace(/(\r\n|\n|\r)/g, "11")wcześniej .length. I pamiętaj o tym podczas cięcia sznurka.

Skończyło się na czymś takim:

var maxlength = el.attr("maxlength");
var val = el.val();
var length = val.length;
var realLength = val.replace(/(\r\n|\n|\r)/g, "11").length;
if (realLength > maxlength) {
    el.val(val.slice(0, maxlength - (realLength - length)));
}

Nie jestem pewien, czy to całkowicie rozwiązuje problem, ale na razie działa.

Roman Pominov
źródło
0

Wypróbuj to jQuery, które działa w IE9, FF, Chrome i zapewnia odliczanie dla użytkowników:

$("#comments").bind("keyup keydown", function() {
    var max = 500;
    var value = $(this).val();
    var left = max - value.length;
    if(left < 0) {
        $(this).val( value.slice(0, left) );
        left = 0;
    }
    $("#charcount").text(left);
}); 

<textarea id="comments" onkeyup="ismaxlength(this,500)"></textarea>
<span class="max-char-limit"><span id="charcount">500</span> characters left</span>
Leslie King
źródło
0

Spróbuj użyć tego przykładu kodu:

$("#TextAreaID1").bind('input propertychange', function () {
    var maxLength = 4000;
    if ($(this).val().length > maxLength) {
        $(this).val($(this).val().substring(0, maxLength));
    }
});
naveen
źródło
-1

To jest dużo łatwiejsze:

<textarea onKeyPress="return ( this.value.length < 1000 );"></textarea>

erdomester
źródło
2
Zauważ, że to rozwiązanie nie jest w pełni replikowane, maxlengthponieważ możesz wkleić ciągi, które są dłuższe niż żądana długość.
Chris Bier,