Element.style.js
上传用户:shuoshiled
上传日期:2018-01-28
资源大小:10124k
文件大小:17k
源码类别:

中间件编程

开发平台:

JavaScript

  1. /*!  * Ext JS Library 3.0.0  * Copyright(c) 2006-2009 Ext JS, LLC  * licensing@extjs.com  * http://www.extjs.com/license  */ /**
  2.  * @class Ext.Element
  3.  */
  4. Ext.Element.addMethods(function(){  
  5.     // local style camelizing for speed
  6.     var propCache = {},
  7.         camelRe = /(-[a-z])/gi,
  8.         classReCache = {},
  9.         view = document.defaultView,
  10.         propFloat = Ext.isIE ? 'styleFloat' : 'cssFloat',
  11.         opacityRe = /alpha(opacity=(.*))/i,
  12.         trimRe = /^s+|s+$/g,
  13.         EL = Ext.Element,   
  14.         PADDING = "padding",
  15.         MARGIN = "margin",
  16.         BORDER = "border",
  17.         LEFT = "-left",
  18.         RIGHT = "-right",
  19.         TOP = "-top",
  20.         BOTTOM = "-bottom",
  21.         WIDTH = "-width",    
  22.         MATH = Math,
  23.         HIDDEN = 'hidden',
  24.         ISCLIPPED = 'isClipped',
  25.         OVERFLOW = 'overflow',
  26.         OVERFLOWX = 'overflow-x',
  27.         OVERFLOWY = 'overflow-y',
  28.         ORIGINALCLIP = 'originalClip',
  29.         // special markup used throughout Ext when box wrapping elements    
  30.         borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},
  31.         paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},
  32.         margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM},
  33.         data = Ext.Element.data;
  34.         
  35.     
  36.     // private  
  37.     function camelFn(m, a) {
  38.         return a.charAt(1).toUpperCase();
  39.     }
  40.     
  41.     // private (needs to be called => addStyles.call(this, sides, styles))
  42.     function addStyles(sides, styles){
  43.         var val = 0;    
  44.         
  45.         Ext.each(sides.match(/w/g), function(s) {
  46.             if (s = parseInt(this.getStyle(styles[s]), 10)) {
  47.                 val += MATH.abs(s);      
  48.             }
  49.         },
  50.         this);
  51.         return val;
  52.     }
  53.     function chkCache(prop) {
  54.         return propCache[prop] || (propCache[prop] = prop == 'float' ? propFloat : prop.replace(camelRe, camelFn));
  55.     }
  56.             
  57.     return {    
  58.         // private  ==> used by Fx  
  59.         adjustWidth : function(width) {
  60.             var me = this;
  61.             var isNum = (typeof width == "number");
  62.             if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
  63.                width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
  64.             }
  65.             return (isNum && width < 0) ? 0 : width;
  66.         },
  67.         
  68.         // private   ==> used by Fx 
  69.         adjustHeight : function(height) {
  70.             var me = this;
  71.             var isNum = (typeof height == "number");
  72.             if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
  73.                height -= (me.getBorderWidth("tb") + me.getPadding("tb"));               
  74.             }
  75.             return (isNum && height < 0) ? 0 : height;
  76.         },
  77.     
  78.     
  79.         /**
  80.          * Adds one or more CSS classes to the element. Duplicate classes are automatically filtered out.
  81.          * @param {String/Array} className The CSS class to add, or an array of classes
  82.          * @return {Ext.Element} this
  83.          */
  84.         addClass : function(className){
  85.             var me = this;
  86.             Ext.each(className, function(v) {
  87.                 me.dom.className += (!me.hasClass(v) && v ? " " + v : "");  
  88.             });
  89.             return me;
  90.         },
  91.     
  92.         /**
  93.          * Adds one or more CSS classes to this element and removes the same class(es) from all siblings.
  94.          * @param {String/Array} className The CSS class to add, or an array of classes
  95.          * @return {Ext.Element} this
  96.          */
  97.         radioClass : function(className){
  98.             Ext.each(this.dom.parentNode.childNodes, function(v) {
  99.                 if(v.nodeType == 1) {
  100.                     Ext.fly(v, '_internal').removeClass(className);          
  101.                 }
  102.             });
  103.             return this.addClass(className);
  104.         },
  105.     
  106.         /**
  107.          * Removes one or more CSS classes from the element.
  108.          * @param {String/Array} className The CSS class to remove, or an array of classes
  109.          * @return {Ext.Element} this
  110.          */
  111.         removeClass : function(className){
  112.             var me = this;
  113.             if (me.dom.className) {
  114.                 Ext.each(className, function(v) {               
  115.                     me.dom.className = me.dom.className.replace(
  116.                         classReCache[v] = classReCache[v] || new RegExp('(?:^|\s+)' + v + '(?:\s+|$)', "g"), 
  117.                         " ");               
  118.                 });    
  119.             }
  120.             return me;
  121.         },
  122.     
  123.         /**
  124.          * Toggles the specified CSS class on this element (removes it if it already exists, otherwise adds it).
  125.          * @param {String} className The CSS class to toggle
  126.          * @return {Ext.Element} this
  127.          */
  128.         toggleClass : function(className){
  129.             return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
  130.         },
  131.     
  132.         /**
  133.          * Checks if the specified CSS class exists on this element's DOM node.
  134.          * @param {String} className The CSS class to check for
  135.          * @return {Boolean} True if the class exists, else false
  136.          */
  137.         hasClass : function(className){
  138.             return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
  139.         },
  140.     
  141.         /**
  142.          * Replaces a CSS class on the element with another.  If the old name does not exist, the new name will simply be added.
  143.          * @param {String} oldClassName The CSS class to replace
  144.          * @param {String} newClassName The replacement CSS class
  145.          * @return {Ext.Element} this
  146.          */
  147.         replaceClass : function(oldClassName, newClassName){
  148.             return this.removeClass(oldClassName).addClass(newClassName);
  149.         },
  150.         
  151.         isStyle : function(style, val) {
  152.             return this.getStyle(style) == val;  
  153.         },
  154.     
  155.         /**
  156.          * Normalizes currentStyle and computedStyle.
  157.          * @param {String} property The style property whose value is returned.
  158.          * @return {String} The current value of the style property for this element.
  159.          */
  160.         getStyle : function(){         
  161.             return view && view.getComputedStyle ?
  162.                 function(prop){
  163.                     var el = this.dom,
  164.                         v,                  
  165.                         cs;
  166.                     if(el == document) return null;
  167.                     prop = chkCache(prop);
  168.                     return (v = el.style[prop]) ? v : 
  169.                            (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
  170.                 } :
  171.                 function(prop){      
  172.                     var el = this.dom, 
  173.                         m, 
  174.                         cs;     
  175.                         
  176.                     if(el == document) return null;      
  177.                     if (prop == 'opacity') {
  178.                         if (el.style.filter.match) {                       
  179.                             if(m = el.style.filter.match(opacityRe)){
  180.                                 var fv = parseFloat(m[1]);
  181.                                 if(!isNaN(fv)){
  182.                                     return fv ? fv / 100 : 0;
  183.                                 }
  184.                             }
  185.                         }
  186.                         return 1;
  187.                     }
  188.                     prop = chkCache(prop);  
  189.                     return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
  190.                 };
  191.         }(),
  192.         
  193.         /**
  194.          * Return the CSS color for the specified CSS attribute. rgb, 3 digit (like #fff) and valid values
  195.          * are convert to standard 6 digit hex color.
  196.          * @param {String} attr The css attribute
  197.          * @param {String} defaultValue The default value to use when a valid color isn't found
  198.          * @param {String} prefix (optional) defaults to #. Use an empty string when working with
  199.          * color anims.
  200.          */
  201.         getColor : function(attr, defaultValue, prefix){
  202.             var v = this.getStyle(attr),
  203.                 color = prefix || '#',
  204.                 h;
  205.                 
  206.             if(!v || /transparent|inherit/.test(v)){
  207.                 return defaultValue;
  208.             }
  209.             if(/^r/.test(v)){
  210.                 Ext.each(v.slice(4, v.length -1).split(','), function(s){
  211.                     h = parseInt(s, 10);
  212.                     color += (h < 16 ? '0' : '') + h.toString(16); 
  213.                 });
  214.             }else{
  215.                 v = v.replace('#', '');
  216.                 color += v.length == 3 ? v.replace(/^(w)(w)(w)$/, '$1$1$2$2$3$3') : v;
  217.             }
  218.             return(color.length > 5 ? color.toLowerCase() : defaultValue);
  219.         },
  220.     
  221.         /**
  222.          * Wrapper for setting style properties, also takes single object parameter of multiple styles.
  223.          * @param {String/Object} property The style property to be set, or an object of multiple styles.
  224.          * @param {String} value (optional) The value to apply to the given property, or null if an object was passed.
  225.          * @return {Ext.Element} this
  226.          */
  227.         setStyle : function(prop, value){
  228.             var tmp, 
  229.                 style,
  230.                 camel;
  231.             if (!Ext.isObject(prop)) {
  232.                 tmp = {};
  233.                 tmp[prop] = value;          
  234.                 prop = tmp;
  235.             }
  236.             for (style in prop) {
  237.                 value = prop[style];            
  238.                 style == 'opacity' ? 
  239.                     this.setOpacity(value) : 
  240.                     this.dom.style[chkCache(style)] = value;
  241.             }
  242.             return this;
  243.         },
  244.         
  245.         /**
  246.          * Set the opacity of the element
  247.          * @param {Float} opacity The new opacity. 0 = transparent, .5 = 50% visibile, 1 = fully visible, etc
  248.          * @param {Boolean/Object} animate (optional) a standard Element animation config object or <tt>true</tt> for
  249.          * the default animation (<tt>{duration: .35, easing: 'easeIn'}</tt>)
  250.          * @return {Ext.Element} this
  251.          */
  252.          setOpacity : function(opacity, animate){
  253.             var me = this,
  254.                 s = me.dom.style;
  255.                 
  256.             if(!animate || !me.anim){            
  257.                 if(Ext.isIE){
  258.                     var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '', 
  259.                     val = s.filter.replace(opacityRe, '').replace(trimRe, '');
  260.                     s.zoom = 1;
  261.                     s.filter = val + (val.length > 0 ? ' ' : '') + opac;
  262.                 }else{
  263.                     s.opacity = opacity;
  264.                 }
  265.             }else{
  266.                 me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');
  267.             }
  268.             return me;
  269.         },
  270.         
  271.         /**
  272.          * Clears any opacity settings from this element. Required in some cases for IE.
  273.          * @return {Ext.Element} this
  274.          */
  275.         clearOpacity : function(){
  276.             var style = this.dom.style;
  277.             if(Ext.isIE){
  278.                 if(!Ext.isEmpty(style.filter)){
  279.                     style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');
  280.                 }
  281.             }else{
  282.                 style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';
  283.             }
  284.             return this;
  285.         },
  286.     
  287.         /**
  288.          * Returns the offset height of the element
  289.          * @param {Boolean} contentHeight (optional) true to get the height minus borders and padding
  290.          * @return {Number} The element's height
  291.          */
  292.         getHeight : function(contentHeight){
  293.             var me = this,
  294.                 dom = me.dom,
  295.                 h = MATH.max(dom.offsetHeight, dom.clientHeight) || 0;
  296.             h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");
  297.             return h < 0 ? 0 : h;
  298.         },
  299.     
  300.         /**
  301.          * Returns the offset width of the element
  302.          * @param {Boolean} contentWidth (optional) true to get the width minus borders and padding
  303.          * @return {Number} The element's width
  304.          */
  305.         getWidth : function(contentWidth){
  306.             var me = this,
  307.                 dom = me.dom,
  308.                 w = MATH.max(dom.offsetWidth, dom.clientWidth) || 0;
  309.             w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");
  310.             return w < 0 ? 0 : w;
  311.         },
  312.     
  313.         /**
  314.          * Set the width of this Element.
  315.          * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>
  316.          * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li>
  317.          * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.
  318.          * </ul></div>
  319.          * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
  320.          * @return {Ext.Element} this
  321.          */
  322.         setWidth : function(width, animate){
  323.             var me = this;
  324.             width = me.adjustWidth(width);
  325.             !animate || !me.anim ? 
  326.                 me.dom.style.width = me.addUnits(width) :
  327.                 me.anim({width : {to : width}}, me.preanim(arguments, 1));
  328.             return me;
  329.         },
  330.     
  331.         /**
  332.          * Set the height of this Element.
  333.          * <pre><code>
  334. // change the height to 200px and animate with default configuration
  335. Ext.fly('elementId').setHeight(200, true);
  336. // change the height to 150px and animate with a custom configuration
  337. Ext.fly('elId').setHeight(150, {
  338.     duration : .5, // animation will have a duration of .5 seconds
  339.     // will change the content to "finished"
  340.     callback: function(){ this.{@link #update}("finished"); } 
  341. });
  342.          * </code></pre>
  343.          * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>
  344.          * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels.)</li>
  345.          * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>
  346.          * </ul></div>
  347.          * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
  348.          * @return {Ext.Element} this
  349.          */
  350.          setHeight : function(height, animate){
  351.             var me = this;
  352.             height = me.adjustHeight(height);
  353.             !animate || !me.anim ? 
  354.                 me.dom.style.height = me.addUnits(height) :
  355.                 me.anim({height : {to : height}}, me.preanim(arguments, 1));
  356.             return me;
  357.         },
  358.         
  359.         /**
  360.          * Gets the width of the border(s) for the specified side(s)
  361.          * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,
  362.          * passing <tt>'lr'</tt> would get the border <b><u>l</u></b>eft width + the border <b><u>r</u></b>ight width.
  363.          * @return {Number} The width of the sides passed added together
  364.          */
  365.         getBorderWidth : function(side){
  366.             return addStyles.call(this, side, borders);
  367.         },
  368.     
  369.         /**
  370.          * Gets the width of the padding(s) for the specified side(s)
  371.          * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,
  372.          * passing <tt>'lr'</tt> would get the padding <b><u>l</u></b>eft + the padding <b><u>r</u></b>ight.
  373.          * @return {Number} The padding of the sides passed added together
  374.          */
  375.         getPadding : function(side){
  376.             return addStyles.call(this, side, paddings);
  377.         },
  378.     
  379.         /**
  380.          *  Store the current overflow setting and clip overflow on the element - use <tt>{@link #unclip}</tt> to remove
  381.          * @return {Ext.Element} this
  382.          */
  383.         clip : function(){
  384.             var me = this,
  385.                 dom = me.dom;
  386.                 
  387.             if(!data(dom, ISCLIPPED)){
  388.                 data(dom, ISCLIPPED, true);
  389.                 data(dom, ORIGINALCLIP, {
  390.                     o: me.getStyle(OVERFLOW),
  391.                     x: me.getStyle(OVERFLOWX),
  392.                     y: me.getStyle(OVERFLOWY)
  393.                 });
  394.                 me.setStyle(OVERFLOW, HIDDEN);
  395.                 me.setStyle(OVERFLOWX, HIDDEN);
  396.                 me.setStyle(OVERFLOWY, HIDDEN);
  397.             }
  398.             return me;
  399.         },
  400.     
  401.         /**
  402.          *  Return clipping (overflow) to original clipping before <tt>{@link #clip}</tt> was called
  403.          * @return {Ext.Element} this
  404.          */
  405.         unclip : function(){
  406.             var me = this,
  407.                 dom = me.dom;
  408.                 
  409.             if(data(dom, ISCLIPPED)){
  410.                 data(dom, ISCLIPPED, false);
  411.                 var o = data(dom, ORIGINALCLIP);
  412.                 if(o.o){
  413.                     me.setStyle(OVERFLOW, o.o);
  414.                 }
  415.                 if(o.x){
  416.                     me.setStyle(OVERFLOWX, o.x);
  417.                 }
  418.                 if(o.y){
  419.                     me.setStyle(OVERFLOWY, o.y);
  420.                 }
  421.             }
  422.             return me;
  423.         },
  424.         
  425.         addStyles : addStyles,
  426.         margins : margins
  427.     }
  428. }()         
  429. );