日期:2014-05-16 浏览次数:20418 次
????? 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