【发布时间】:2011-02-18 21:44:06
【问题描述】:
如何使用 javascript 检测 textarea 上的更改事件?
我正在尝试检测您键入时剩余的可用字符数。
我尝试使用 onchange 事件,但似乎只有在焦点消失时才会启动。
【问题讨论】:
标签: javascript
如何使用 javascript 检测 textarea 上的更改事件?
我正在尝试检测您键入时剩余的可用字符数。
我尝试使用 onchange 事件,但似乎只有在焦点消失时才会启动。
【问题讨论】:
标签: javascript
最好的方法是跨浏览器:结合使用input 和onpropertychange 事件,如下所示:
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
});
}
input 事件处理IE9+, FF, Chrome, Opera and Safari,onpropertychange 处理IE8(它也适用于 IE6 和 7,但存在一些错误)。
使用input 和onpropertychange 的优点是它们不会不必要地触发(例如按下Ctrl 或Shift 键时);所以如果您希望在 textarea 内容发生变化时运行相对昂贵的操作,这是可行的方法。
现在 IE 一如既往地支持这一点:当字符从 textarea 中删除时,input 和 onpropertychange 在 IE 中都不会触发。因此,如果您需要处理 IE 中的字符删除,请使用 keypress(而不是使用 keyup / keydown,因为即使用户按下并按住某个键,它们也只会触发一次)。
来源:http://www.alistapart.com/articles/expanding-text-areas-made-elegant/
编辑: 似乎即使上述解决方案也不完美,正如 cmets 中正确指出的那样:textarea 上 addEventListener 属性的存在确实不暗示您正在使用健全的浏览器;同样,attachEvent 属性的存在确实不暗示 IE。如果您希望您的代码真正密封,您应该考虑更改它。有关指针,请参阅 Tim Down's comment。
【讨论】:
addEventListener 并不意味着支持input 事件,反之亦然);特征检测会更好。有关此问题的讨论,请参阅 this blog post。
oninput 是我们应该这样做的,但您可能不应该使用 addEventListener 作为浏览器支持的测试。无论如何 +1。
keypress 事件来处理 IE9(可能还有更高版本)中的这种情况。
input event 处理程序也可以通过实现.oninput 对象属性来定义。
您需要为此使用onkeyup 和 onchange。 onchange 将阻止上下文菜单粘贴,并且 onkeyup 将在每次击键时触发。
有关代码示例,请参阅我在 How to impose maxlength on textArea 上的回答。
【讨论】:
onkeyup 是输入检测的可怕事件。使用oninput 和onpropertychange(用于IE 支持)。
onchange在上下文菜单剪切/粘贴发生时不被触发。
未在 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>
【讨论】:
我知道这不完全是您的问题,但我认为这可能有用。 对于某些应用程序,最好不要在每次按下键时触发更改功能。这可以通过以下方式实现:
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);
}
}();
这通过测试是否在某个延迟期内触发了更新的事件来起作用。祝你好运!
【讨论】:
我知道这个问题是特定于 JavaScript 的,但是,似乎没有一种好的、干净的方法来始终检测所有当前浏览器中的文本区域何时发生变化。我了解到 jquery 已经为我们处理好了。它甚至可以处理文本区域的上下文菜单更改。无论输入类型如何,都使用相同的语法。
$('div.lawyerList').on('change','textarea',function(){
// Change occurred so count chars...
});
或
$('textarea').on('change',function(){
// Change occurred so count chars...
});
【讨论】:
bind("input cut paste"...,它就像一个魅力——使用键盘或上下文菜单输入、剪切和粘贴;甚至拖放文本。
textarea 触发change 事件。
您可以收听文本区域更改的事件并根据需要进行更改。这是一个例子。
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>
【讨论】:
如果与 HTML5 输入验证/模式属性配对,Keyup 就足够了。因此,创建一个模式(正则表达式)来验证输入并根据 .checkValidity() 状态采取行动。像下面这样的东西可以工作。在您的情况下,您需要一个正则表达式来匹配长度。我的解决方案正在使用/可在线演示here。
<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;
}
});
【讨论】:
我在没有 jquery 的情况下用于 IE 11 并且仅用于单个 textarea 的代码:
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);
}
和html:
<TEXTAREA onpropertychange='limit_char(5)' ...
【讨论】:
试试这个。这很简单,因为它是 2016 年,我相信它可以在大多数浏览器上运行。
<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;
}
【讨论】:
你能做的最好的事情是设置一个函数在给定的时间内被调用,这个函数来检查你的文本区域的内容。
self.setInterval('checkTextAreaValue()', 50);
【讨论】: