36-讨论
10.8.3 讨论
上述代码足够通用,考虑了指定页面任何数量的“Character remaining”消息和 <textarea> 元素。如果你打算构建一个内容管理或者数据输入系统,这可能很实用。
为了在用户试图用鼠标将数据复制和粘贴到 <textarea> 时提供保护,需要绑定 input 和 paste 事件。不能使用 mouseup 事件,因为在选择浏览器上下文菜单的一项时不会触发它。 input 事件是HTML5(工作草案)的一部分,已经被Firefox、Opera和Safari所实现。它在用户输入时触发,不管输入设备为何(鼠标还是键盘)。Safari在本书编写期间还有一个缺陷,无法在 <textarea> 元素上触发输入事件。Safari和Internet Explorer都能理解 <textarea> 元素上的 paste 事件,理解用于捕捉击键的 keyup 事件。
附加 keyup 、 input 和 paste 是多余的,但是在本例中是有利的。 update 函数很简单,因而没有任何性能问题,它只在必要的时候操纵DOM,所以第一个 update 之后的调用都是多余的,什么也不会做。
对多余事件的替代方案之一是在 <textarea> 元素拥有焦点时使用 setInterval 。在指定时间间隔之后调用同一个 update 函数,如果与 keyup 事件配对,你就能够在按键的时候立刻更新,而且任意的更新时间间隔(如300毫秒)就是信息粘贴到 <textarea> 元素的时间。如果 update 函数较为复杂或者代价较高,这可能是更好的替代方案。
当将事件绑定到表单元素时,有时候使用超时对函数调用稍作延迟很重要。在前一个例子中,Internet Explorer在剪贴板中的文本实际在添加到 <textarea> 元素中之前触发 paste 事件。因此,剩余字符数的计算在用户单击或者按下另一个键之前都是不正确的。通过使用 setTimeout(update, 0) ,把更新函数放在调用栈的最后,在浏览器添加文本之后才触发:
$input.bind('input keyup paste', function(){setTimeout(update,0)} );
当禁用JavaScript时会发生什么情况?你应该在CSS中默认隐藏“Characters remaining”消息。然后使用JavaScript为双亲元素添加一个类名,覆盖前一条CSS规则。还有,在服务器端再次检查消息的长度也很重要:
<style type="text/css" title="text/css">
.remaining { display:none; }
.jsEnabled .remaining { display:block; }
</style>
...
//当HTML DOM就绪时
$(document).ready(function(){
$('form').addClass('jsEnabled');
});