IE下使用onpropertychange,非IE下使用input,不能输入的控制是直接截取[0,maxlen]区间内的值即可。
/**
* 对一个页面如果有多次调用,可以使用:
* targetId:传入的需要控制长度内容的对象ID
* fontId:字体变化的对象Id
* maxLen:最大超过字数
* 调用方法:
* new FontChange("content","fontLen",50);
* @author:xuzengqiang
* @since :2015-4-9 17:36:14
* IE9支持oninput事件,但是不支持退格删除,它还是支持onpropertychange事件,所以IE还是采用onpropertychange事件
**/
var Class={
create:function(){
return function(){
this.initialize.apply(this,arguments);
}
}
};
//将参数obj绑定到fun函数中
function bind(obj,fun){
return function(){
return fun.apply(obj,arguments);
}
}
String.prototype.empty=function(){
var reg = /^\s\s*$/;
return reg.test(this);
}
// 让非IE浏览器支持currentStyle
if(! document.all){
HTMLElement.prototype.__defineGetter__("currentStyle", function () {
return this.ownerDocument.defaultView.getComputedStyle(this, null);
});
}
var FontChange = Class.create();
FontChange.prototype = {
initialize:function(targetId,fontId,maxSize){
var _this = this;
this.target = document.getElementById(targetId);
this.font = document.getElementById(fontId);
this.fontColor = this.font.currentStyle.color;
// 用于判定是否是由于target的长度本身超出而字体长度发生改变触发的onpropertychange,默认否,只是针对IE8做出的调整
if(!this.$$guid) {
this.$$guid = false;
}
this.maxSize = maxSize;
var content = this.target.value;
//由于刚开始textarea中默认会有空字符串,影响初始值,但是考虑一开始textarea中可能有提示语,所以不能清空
if(content.empty()) {
this.target.value=""; //必须先清空一次,否则会影响初始值
} else if(content.length > 0 && content.length <= this.maxSize){
this.font.innerHTML = this.maxSize - content.length;
} else {
this.font.inerrHTML = 0;
this.target.value = content.substr(0,this.maxSize);
}
//必须绑定,否则changeSize中获取不到对应的this.target的值
this._changeSize = bind(this,this.changeSize);
// IE9新增了addEventListener方法,所以可能是IE
if(this.target.addEventListener) {
// IE9的oninput和onpropertychange不支持退格删除,即删除内容不会触发该事件,可以绑定selectionchange事件(对退格删除有效)
// IE9的oninput事件对退格无效,但是添加有效,同时绑定
if(this.isIE()) {
this.target.addEventListener("focus",function(){
_this.target.addEventListener("input",_this._changeSize,false);
document.addEventListener("selectionchange", _this._changeSize, false);
},false);
this.target.addEventListener("blur",function(){
_this.target.removeEventListener("input",_this._changeSize,false);
document.removeEventListener("selectionchange", _this._changeSize, false);
},false);
} else {
this.target.addEventListener("input",this._changeSize,false);
}
}
// 如果是IE<9
else if(this.target.attachEvent) {
this.target.attachEvent("onfocus",function(){
_this.target.attachEvent("onpropertychange",_this._changeSize);
});
// 当失去焦点的时候移除propertychange事件
this.target.attachEvent("onblur",function(){
_this.target.detachEvent("onpropertychange",_this._changeSize);
});
}
},
// 注意:onpropertychange事件是当dom元素上的任意property属性发生改变的时候都会触发
// property:是指获取dom元素被获取后,dom本身的属性,如this.target.id,this.target.value,this.target.style等
// 当其中任意属性发生改变,都会触发onpropertychange事件,所以一定要防止出现死循环而造成的内存溢出
changeSize:function(e){
var content = this.target.value,
len = content.length,
// IE:e,FireFox:window.event
event = window.event || e;
// 如果支持onpropertychange,那么IE<9,则需要通过event.propertName判定是否是触发的value属性
if(event.propertyName){
if(event.propertyName.toLowerCase() != "value") {
return false;
} else {
// 如果是由于本身超出长度导致value发生改变触发的onpropertychange事件,则直接退出,不处理,只针对IE8以下的浏览器,因为input事件不会去触发
if(this.$$guid) {
// 重置,避免下次不触发
this.$$guid = false;
return false;
}
}
}
if(len<=this.maxSize) {
this.font.innerHTML=this.maxSize-len;
this.font.style.color = this.fontColor;
this.$$guid = false;
} else {
// value属性发生改变,会再次触发onpropertychange事件,需要处理,设置$$guid=true
this.$$guid = true;
this.target.value=content.substring(0,this.maxSize);
this.font.style.color = "#FF0000";
}
},
// 一般通过window.navigator.userAgent判定,但是IE11没有MSIE标识
// IE10:Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
// IE11:Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv 11.0) like Gecko
isIE:function(){
return ("ActiveXObject" in window);
}
};
使用案例:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>FontChange</title>
<script type="text/javascript" src="FontChange.js"></script>
<style type="text/css">
*{margin:0;padding:0;font-family:微软雅黑;font-size:13px}
.content-box{margin-top:30px;margin-left:100px}
</style>
</head>
<body>
<div class="content-box">
<textarea id="content" rows="8" cols="60"></textarea>
<br/>
还可以输入<span id="fontLen">500</span>字
</div>
</body>
<script type="text/javascript">
new FontChange("content","fontLen",500);
</script>
</html>