日期:2014-05-16 浏览次数:20477 次
????? Ext提供了一个很有用的工具类Ext.util.TextMetrics,利用该类可以很方便的为一段文字提供一个精确象素级的测量,以便可以得到某段文字的高度和宽度。该类的实现采用了单例模式,即当调用该类时,该类内部属性shared已实例,下次调用时不需再实例化。先看函数的定义
?
Ext.util.TextMetrics = function(){
var shared;
return {
measure : function(el, text, fixedWidth){
if(!shared){
shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
}
shared.bind(el);
shared.setFixedWidth(fixedWidth || 'auto');
return shared.getSize(text);
},
createInstance : function(el, fixedWidth){
return Ext.util.TextMetrics.Instance(el, fixedWidth);
}
};
}();
?
????? 该函数是自执行函数,执行完后该类提供了两个方法measure和createInstance,分别用来测量元素el的大小和创建实例。
????? 方法measure中三个参数为el测试的DOM对象,text要测量的文字,fixedWidth设置该值可以根据该值压缩文字的多行显示,从而根据行数的不同返回文本的高度,不设置时会默认根据文本显示的行数返回内容的高度。该方法首先实例化要测量的对象,然后绑定el,绑定的过程会设置其与字体相关的css样式,最后返回一段文字的大小。
上面方法中调用的函数实际上在Ext.util.TextMetrics.Instance中定义,函数主体如下
?
Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
...
var instance = {
...
};
instance.bind(bindTo);
return instance;
};
?
????? 该函数实际上返回闭包变量instance,Ext.util.TextMetrics.Instance中封装了要实现的函数,首先看Instance中的变量
?
var ml = new Ext.Element(document.createElement('div'));
document.body.appendChild(ml.dom);
ml.position('absolute');
ml.setLeftTop(-1000, -1000);
ml.hide();
if(fixedWidth){
ml.setWidth(fixedWidth);
}
??? 该类定义了辅助div,隐藏显示,用来存放要测试的文字,下面看闭包变量instance中的函数
?
/**
* 返回一个指定文字的尺寸。该文字内置元素的样式和宽度属性
* <p><b>Only available on the instance returned from {@link #createInstance}, <u>not</u> on the singleton.</b></p>
* Returns the size of the specified text based on the internal element's style and width properties
* @param {String} text 要测量的文字 The text to measure
* @return {Object} An object containing the text's size {width: (width), height: (height)}
*/
getSize : function(text){
ml.update(text);
var s = ml.getSize();
ml.update('');
return s;
},
?注意返回大小后把ml内容清空
?
/**
* 绑定某个样式的TextMetrics实例,使得被渲染之文字重新获得CSS样式。
* <p><b>Only available on the instance returned from {@link #createInstance}, <u>not</u> on the singleton.</b></p>
* Binds this TextMetrics instance to an element from which to copy existing CSS styles
* that can affect the size of the rendered text
* @param {String/HTMLElement} el The element, dom node or id
*/
bind : function(el){
ml.setStyle(
Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing')
);
},
?绑定时只设置与字体相关的属性
?
/**
* 对内置的测量元素设置一个固定的宽度。
* <p><b>Only available on the instance returned from {@link #createInstance}, <u>not</u> on the singleton.</b></p>
* Sets a fixed width on the internal measurement element. If the text will be multiline, you have
* to set a fixed width in order to accurately measure the text height.
* @param {Number} width The width to set on the element
*/
setFixedWidth : function(width){
ml.setWidth(width);
},
/**
* 返回指定文字的宽度
* <p><b>Only available on the instance returned from {@link #createInstance}, <u>not</u> on the singleton.</b></p>
* Returns the measured width of the specified text