Jak wykryć zdarzenie zmiany w obszarze tekstowym za pomocą javascript?
Próbuję wykryć, ile znaków pozostało dostępnych podczas pisania.
Próbowałem użyć zdarzenia onchange, ale wydaje się, że działa tylko wtedy, gdy nie ma ostrości.
Odpowiedzi:
Będziesz musiał użyć onkeyup i onchange do tego. Zmiana zapobiegnie wklejaniu menu kontekstowego, a onkeyup będzie uruchamiany przy każdym naciśnięciu klawisza.
Zobacz moją odpowiedź na temat Jak nałożyć maxlength na textArea dla przykładu kodu.
onkeyupto straszne zdarzenie dla wykrycia wejścia. Użyj oninputi onpropertychange(do obsługi IE).
onchange jest wywoływany, gdy występuje wycinanie / wklejanie z menu kontekstowego.
Jest rok 2012, nadeszła era post-PC, a my wciąż musimy zmagać się z czymś tak podstawowym jak to. To powinno być bardzo proste .
Dopóki to marzenie się nie spełni, oto najlepszy sposób na zrobienie tego, cross-browser: użyj kombinacji zdarzeń inputionpropertychange , na przykład:
var area = container.querySelector('textarea');
if (area.addEventListener) {
area.addEventListener('input', function() {
// event handling code for sane browsers
}, false);
} else if (area.attachEvent) {
area.attachEvent('onpropertychange', function() {
// IE-specific event handling code
});
}
inputWydarzenie zajmuje IE9 +, FF, Chrome, Opera i Safari , a onpropertychangedba o IE8 (działa również z IE6 i 7, ale istnieją pewne błędy).
Zaletą używania inputi onpropertychangejest to, że nie uruchamiają się niepotrzebnie (jak podczas naciskania klawiszy Ctrllub Shift); więc jeśli chcesz uruchomić stosunkowo kosztowną operację, gdy zmienia się zawartość obszaru tekstowego, to jest droga do zrobienia .
Teraz IE, jak zawsze, wykonuje połowiczną robotę, wspierając to: ani inputnie onpropertychangeuruchamia się w IE, gdy znaki są usuwane z obszaru tekstu. Jeśli więc chcesz zająć się usuwaniem znaków w IE, użyj keypress(w przeciwieństwie do używania keyup/ keydown, ponieważ uruchamiają się one tylko raz, nawet jeśli użytkownik naciśnie i przytrzyma klawisz).
Źródło: http://www.alistapart.com/articles/expanding-text-areas-made-elegant/
EDYCJA: Wydaje się, że nawet powyższe rozwiązanie nie jest idealne, jak słusznie wskazano w komentarzach: obecność addEventListenerwłaściwości w obszarze tekstowym nie oznacza, że pracujesz z rozsądną przeglądarką; podobnie obecność attachEventdobra nie implikuje IE. Jeśli chcesz, aby Twój kod był naprawdę szczelny, powinieneś rozważyć zmianę tego. Zobacz komentarz Tim Down dla wskazówek.
oninputjak powinniśmy to zrobić, ale prawdopodobnie nie powinieneś używać go addEventListenerjako testu obsługi przeglądarki. +1 w każdym przypadku.
keypresszdarzenia do obsługi tego przypadku w IE9 (i być może także późniejszych wersjach).
Nie testowano w przeglądarce Firefox.
var isIE = /*@cc_on!@*/false; // Note: This line breaks closure compiler...
function SuperDuperFunction() {
// DoSomething
}
function SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally() {
if(isIE) // For Chrome, oninput works as expected
SuperDuperFunction();
}
<textarea id="taSource"
class="taSplitted"
rows="4"
cols="50"
oninput="SuperDuperFunction();"
onpropertychange="SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally();"
onmousemove="SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally();"
onkeyup="SuperDuperFunctionBecauseMicrosoftMakesIEsuckIntentionally();">
Test
</textarea>
Wiem, że to nie jest dokładnie twoje pytanie, ale pomyślałem, że może się przydać. W przypadku niektórych aplikacji dobrze jest mieć funkcję zmiany uruchamianą nie za każdym razem, gdy naciśnięty zostanie klawisz. Można to osiągnąć za pomocą czegoś takiego:
var text = document.createElement('textarea');
text.rows = 10;
text.cols = 40;
document.body.appendChild(text);
text.onkeyup = function(){
var callcount = 0;
var action = function(){
alert('changed');
}
var delayAction = function(action, time){
var expectcallcount = callcount;
var delay = function(){
if(callcount == expectcallcount){
action();
}
}
setTimeout(delay, time);
}
return function(eventtrigger){
++callcount;
delayAction(action, 1200);
}
}();
Działa to poprzez sprawdzenie, czy w pewnym okresie opóźnienia wystąpiło nowsze zdarzenie. Powodzenia!
Wiem, że to pytanie było specyficzne dla JavaScript, jednak wydaje się, że nie ma dobrego, przejrzystego sposobu na ZAWSZE wykrycie, kiedy obszar tekstowy zmienia się we wszystkich obecnych przeglądarkach. Dowiedziałem się, że jquery zajął się tym za nas. Obsługuje nawet zmiany menu kontekstowego w obszarach tekstowych. Ta sama składnia jest używana niezależnie od typu wejścia.
$('div.lawyerList').on('change','textarea',function(){
// Change occurred so count chars...
});
lub
$('textarea').on('change',function(){
// Change occurred so count chars...
});
bind("input cut paste"...i działa jak urok - pisanie, wycinanie i wklejanie za pomocą klawiatury lub menu kontekstowego; nawet przeciągnij / upuść tekstu.
changezdarzenia dla textarea.
Możesz słuchać zdarzenia przy zmianie obszaru tekstowego i wprowadzać zmiany, jak chcesz. Oto jeden przykład.
const textArea = document.getElementById('my_text_area');
textArea.addEventListener('input', () => {
var textLn = textArea.value.length;
if(textLn >= 100) {
textArea.style.fontSize = '10pt';
}
})
<html>
<textarea id='my_text_area' rows="4" cols="50" style="font-size:40pt">
This text will change font after 100.
</textarea>
</html>
Kluczowanie powinno wystarczyć, jeśli jest sparowane z atrybutem walidacji / wzorca wejścia HTML5. Dlatego utwórz wzorzec (wyrażenie regularne), aby sprawdzić poprawność danych wejściowych i działaj na podstawie statusu .checkValidity (). Coś jak poniżej może działać. W twoim przypadku chciałbyś, aby wyrażenie regularne odpowiadało długości. Moje rozwiązanie jest używane / demonstracyjne online tutaj .
<input type="text" pattern="[a-zA-Z]+" id="my-input">
var myInput = document.getElementById = "my-input";
myInput.addEventListener("keyup", function(){
if(!this.checkValidity() || !this.value){
submitButton.disabled = true;
} else {
submitButton.disabled = false;
}
});
Kod, którego użyłem dla IE 11 bez jQuery i tylko dla pojedynczego obszaru tekstowego:
JavaScript:
// Impede que o comentário tenha mais de num_max caracteres
var internalChange= 0; // important, prevent reenter
function limit_char(max)
{
if (internalChange == 1)
{
internalChange= 0;
return;
}
internalChange= 1;
// <form> and <textarea> are the ID's of your form and textarea objects
<form>.<textarea>.value= <form>.<textarea>.value.substring(0,max);
}
i html:
<TEXTAREA onpropertychange='limit_char(5)' ...
Spróbuj tego. To proste, a ponieważ jest rok 2016, jestem pewien, że będzie działać na większości przeglądarek.
<textarea id="text" cols="50" rows="5" onkeyup="check()" maxlength="15"></textarea>
<div><span id="spn"></span> characters left</div>
function check(){
var string = document.getElementById("url").value
var left = 15 - string.length;
document.getElementById("spn").innerHTML = left;
}
Najlepszą rzeczą, jaką możesz zrobić, jest ustawienie funkcji, która ma być wywoływana w określonym czasie i ta funkcja, aby sprawdzić zawartość obszaru tekstowego.
self.setInterval('checkTextAreaValue()', 50);