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

中间件编程

开发平台:

JavaScript

  1. /*!
  2.  * Ext JS Library 3.0.0
  3.  * Copyright(c) 2006-2009 Ext JS, LLC
  4.  * licensing@extjs.com
  5.  * http://www.extjs.com/license
  6.  */
  7. /**
  8.  * @class Ext.Layer
  9.  * @extends Ext.Element
  10.  * An extended {@link Ext.Element} object that supports a shadow and shim, constrain to viewport and
  11.  * automatic maintaining of shadow/shim positions.
  12.  * @cfg {Boolean} shim False to disable the iframe shim in browsers which need one (defaults to true)
  13.  * @cfg {String/Boolean} shadow True to automatically create an {@link Ext.Shadow}, or a string indicating the
  14.  * shadow's display {@link Ext.Shadow#mode}. False to disable the shadow. (defaults to false)
  15.  * @cfg {Object} dh DomHelper object config to create element with (defaults to {tag: 'div', cls: 'x-layer'}).
  16.  * @cfg {Boolean} constrain False to disable constrain to viewport (defaults to true)
  17.  * @cfg {String} cls CSS class to add to the element
  18.  * @cfg {Number} zindex Starting z-index (defaults to 11000)
  19.  * @cfg {Number} shadowOffset Number of pixels to offset the shadow (defaults to 4)
  20.  * @cfg {Boolean} useDisplay
  21.  * Defaults to use css offsets to hide the Layer. Specify <tt>true</tt>
  22.  * to use css style <tt>'display:none;'</tt> to hide the Layer.
  23.  * @constructor
  24.  * @param {Object} config An object with config options.
  25.  * @param {String/HTMLElement} existingEl (optional) Uses an existing DOM element. If the element is not found it creates it.
  26.  */
  27. (function(){
  28. Ext.Layer = function(config, existingEl){
  29.     config = config || {};
  30.     var dh = Ext.DomHelper;
  31.     var cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;
  32.     if(existingEl){
  33.         this.dom = Ext.getDom(existingEl);
  34.     }
  35.     if(!this.dom){
  36.         var o = config.dh || {tag: 'div', cls: 'x-layer'};
  37.         this.dom = dh.append(pel, o);
  38.     }
  39.     if(config.cls){
  40.         this.addClass(config.cls);
  41.     }
  42.     this.constrain = config.constrain !== false;
  43.     this.setVisibilityMode(Ext.Element.VISIBILITY);
  44.     if(config.id){
  45.         this.id = this.dom.id = config.id;
  46.     }else{
  47.         this.id = Ext.id(this.dom);
  48.     }
  49.     this.zindex = config.zindex || this.getZIndex();
  50.     this.position('absolute', this.zindex);
  51.     if(config.shadow){
  52.         this.shadowOffset = config.shadowOffset || 4;
  53.         this.shadow = new Ext.Shadow({
  54.             offset : this.shadowOffset,
  55.             mode : config.shadow
  56.         });
  57.     }else{
  58.         this.shadowOffset = 0;
  59.     }
  60.     this.useShim = config.shim !== false && Ext.useShims;
  61.     this.useDisplay = config.useDisplay;
  62.     this.hide();
  63. };
  64. var supr = Ext.Element.prototype;
  65. // shims are shared among layer to keep from having 100 iframes
  66. var shims = [];
  67. Ext.extend(Ext.Layer, Ext.Element, {
  68.     getZIndex : function(){
  69.         return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000;
  70.     },
  71.     getShim : function(){
  72.         if(!this.useShim){
  73.             return null;
  74.         }
  75.         if(this.shim){
  76.             return this.shim;
  77.         }
  78.         var shim = shims.shift();
  79.         if(!shim){
  80.             shim = this.createShim();
  81.             shim.enableDisplayMode('block');
  82.             shim.dom.style.display = 'none';
  83.             shim.dom.style.visibility = 'visible';
  84.         }
  85.         var pn = this.dom.parentNode;
  86.         if(shim.dom.parentNode != pn){
  87.             pn.insertBefore(shim.dom, this.dom);
  88.         }
  89.         shim.setStyle('z-index', this.getZIndex()-2);
  90.         this.shim = shim;
  91.         return shim;
  92.     },
  93.     hideShim : function(){
  94.         if(this.shim){
  95.             this.shim.setDisplayed(false);
  96.             shims.push(this.shim);
  97.             delete this.shim;
  98.         }
  99.     },
  100.     disableShadow : function(){
  101.         if(this.shadow){
  102.             this.shadowDisabled = true;
  103.             this.shadow.hide();
  104.             this.lastShadowOffset = this.shadowOffset;
  105.             this.shadowOffset = 0;
  106.         }
  107.     },
  108.     enableShadow : function(show){
  109.         if(this.shadow){
  110.             this.shadowDisabled = false;
  111.             this.shadowOffset = this.lastShadowOffset;
  112.             delete this.lastShadowOffset;
  113.             if(show){
  114.                 this.sync(true);
  115.             }
  116.         }
  117.     },
  118.     // private
  119.     // this code can execute repeatedly in milliseconds (i.e. during a drag) so
  120.     // code size was sacrificed for effeciency (e.g. no getBox/setBox, no XY calls)
  121.     sync : function(doShow){
  122.         var sw = this.shadow;
  123.         if(!this.updating && this.isVisible() && (sw || this.useShim)){
  124.             var sh = this.getShim();
  125.             var w = this.getWidth(),
  126.                 h = this.getHeight();
  127.             var l = this.getLeft(true),
  128.                 t = this.getTop(true);
  129.             if(sw && !this.shadowDisabled){
  130.                 if(doShow && !sw.isVisible()){
  131.                     sw.show(this);
  132.                 }else{
  133.                     sw.realign(l, t, w, h);
  134.                 }
  135.                 if(sh){
  136.                     if(doShow){
  137.                        sh.show();
  138.                     }
  139.                     // fit the shim behind the shadow, so it is shimmed too
  140.                     var a = sw.adjusts, s = sh.dom.style;
  141.                     s.left = (Math.min(l, l+a.l))+'px';
  142.                     s.top = (Math.min(t, t+a.t))+'px';
  143.                     s.width = (w+a.w)+'px';
  144.                     s.height = (h+a.h)+'px';
  145.                 }
  146.             }else if(sh){
  147.                 if(doShow){
  148.                    sh.show();
  149.                 }
  150.                 sh.setSize(w, h);
  151.                 sh.setLeftTop(l, t);
  152.             }
  153.         }
  154.     },
  155.     // private
  156.     destroy : function(){
  157.         this.hideShim();
  158.         if(this.shadow){
  159.             this.shadow.hide();
  160.         }
  161.         this.removeAllListeners();
  162.         Ext.removeNode(this.dom);
  163.         Ext.Element.uncache(this.id);
  164.     },
  165.     remove : function(){
  166.         this.destroy();
  167.     },
  168.     // private
  169.     beginUpdate : function(){
  170.         this.updating = true;
  171.     },
  172.     // private
  173.     endUpdate : function(){
  174.         this.updating = false;
  175.         this.sync(true);
  176.     },
  177.     // private
  178.     hideUnders : function(negOffset){
  179.         if(this.shadow){
  180.             this.shadow.hide();
  181.         }
  182.         this.hideShim();
  183.     },
  184.     // private
  185.     constrainXY : function(){
  186.         if(this.constrain){
  187.             var vw = Ext.lib.Dom.getViewWidth(),
  188.                 vh = Ext.lib.Dom.getViewHeight();
  189.             var s = Ext.getDoc().getScroll();
  190.             var xy = this.getXY();
  191.             var x = xy[0], y = xy[1];
  192.             var so = this.shadowOffset;
  193.             var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so;
  194.             // only move it if it needs it
  195.             var moved = false;
  196.             // first validate right/bottom
  197.             if((x + w) > vw+s.left){
  198.                 x = vw - w - so;
  199.                 moved = true;
  200.             }
  201.             if((y + h) > vh+s.top){
  202.                 y = vh - h - so;
  203.                 moved = true;
  204.             }
  205.             // then make sure top/left isn't negative
  206.             if(x < s.left){
  207.                 x = s.left;
  208.                 moved = true;
  209.             }
  210.             if(y < s.top){
  211.                 y = s.top;
  212.                 moved = true;
  213.             }
  214.             if(moved){
  215.                 if(this.avoidY){
  216.                     var ay = this.avoidY;
  217.                     if(y <= ay && (y+h) >= ay){
  218.                         y = ay-h-5;
  219.                     }
  220.                 }
  221.                 xy = [x, y];
  222.                 this.storeXY(xy);
  223.                 supr.setXY.call(this, xy);
  224.                 this.sync();
  225.             }
  226.         }
  227.         return this;
  228.     },
  229.     isVisible : function(){
  230.         return this.visible;
  231.     },
  232.     // private
  233.     showAction : function(){
  234.         this.visible = true; // track visibility to prevent getStyle calls
  235.         if(this.useDisplay === true){
  236.             this.setDisplayed('');
  237.         }else if(this.lastXY){
  238.             supr.setXY.call(this, this.lastXY);
  239.         }else if(this.lastLT){
  240.             supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
  241.         }
  242.     },
  243.     // private
  244.     hideAction : function(){
  245.         this.visible = false;
  246.         if(this.useDisplay === true){
  247.             this.setDisplayed(false);
  248.         }else{
  249.             this.setLeftTop(-10000,-10000);
  250.         }
  251.     },
  252.     // overridden Element method
  253.     setVisible : function(v, a, d, c, e){
  254.         if(v){
  255.             this.showAction();
  256.         }
  257.         if(a && v){
  258.             var cb = function(){
  259.                 this.sync(true);
  260.                 if(c){
  261.                     c();
  262.                 }
  263.             }.createDelegate(this);
  264.             supr.setVisible.call(this, true, true, d, cb, e);
  265.         }else{
  266.             if(!v){
  267.                 this.hideUnders(true);
  268.             }
  269.             var cb = c;
  270.             if(a){
  271.                 cb = function(){
  272.                     this.hideAction();
  273.                     if(c){
  274.                         c();
  275.                     }
  276.                 }.createDelegate(this);
  277.             }
  278.             supr.setVisible.call(this, v, a, d, cb, e);
  279.             if(v){
  280.                 this.sync(true);
  281.             }else if(!a){
  282.                 this.hideAction();
  283.             }
  284.         }
  285.         return this;
  286.     },
  287.     storeXY : function(xy){
  288.         delete this.lastLT;
  289.         this.lastXY = xy;
  290.     },
  291.     storeLeftTop : function(left, top){
  292.         delete this.lastXY;
  293.         this.lastLT = [left, top];
  294.     },
  295.     // private
  296.     beforeFx : function(){
  297.         this.beforeAction();
  298.         return Ext.Layer.superclass.beforeFx.apply(this, arguments);
  299.     },
  300.     // private
  301.     afterFx : function(){
  302.         Ext.Layer.superclass.afterFx.apply(this, arguments);
  303.         this.sync(this.isVisible());
  304.     },
  305.     // private
  306.     beforeAction : function(){
  307.         if(!this.updating && this.shadow){
  308.             this.shadow.hide();
  309.         }
  310.     },
  311.     // overridden Element method
  312.     setLeft : function(left){
  313.         this.storeLeftTop(left, this.getTop(true));
  314.         supr.setLeft.apply(this, arguments);
  315.         this.sync();
  316.         return this;
  317.     },
  318.     setTop : function(top){
  319.         this.storeLeftTop(this.getLeft(true), top);
  320.         supr.setTop.apply(this, arguments);
  321.         this.sync();
  322.         return this;
  323.     },
  324.     setLeftTop : function(left, top){
  325.         this.storeLeftTop(left, top);
  326.         supr.setLeftTop.apply(this, arguments);
  327.         this.sync();
  328.         return this;
  329.     },
  330.     setXY : function(xy, a, d, c, e){
  331.         this.fixDisplay();
  332.         this.beforeAction();
  333.         this.storeXY(xy);
  334.         var cb = this.createCB(c);
  335.         supr.setXY.call(this, xy, a, d, cb, e);
  336.         if(!a){
  337.             cb();
  338.         }
  339.         return this;
  340.     },
  341.     // private
  342.     createCB : function(c){
  343.         var el = this;
  344.         return function(){
  345.             el.constrainXY();
  346.             el.sync(true);
  347.             if(c){
  348.                 c();
  349.             }
  350.         };
  351.     },
  352.     // overridden Element method
  353.     setX : function(x, a, d, c, e){
  354.         this.setXY([x, this.getY()], a, d, c, e);
  355.         return this;
  356.     },
  357.     // overridden Element method
  358.     setY : function(y, a, d, c, e){
  359.         this.setXY([this.getX(), y], a, d, c, e);
  360.         return this;
  361.     },
  362.     // overridden Element method
  363.     setSize : function(w, h, a, d, c, e){
  364.         this.beforeAction();
  365.         var cb = this.createCB(c);
  366.         supr.setSize.call(this, w, h, a, d, cb, e);
  367.         if(!a){
  368.             cb();
  369.         }
  370.         return this;
  371.     },
  372.     // overridden Element method
  373.     setWidth : function(w, a, d, c, e){
  374.         this.beforeAction();
  375.         var cb = this.createCB(c);
  376.         supr.setWidth.call(this, w, a, d, cb, e);
  377.         if(!a){
  378.             cb();
  379.         }
  380.         return this;
  381.     },
  382.     // overridden Element method
  383.     setHeight : function(h, a, d, c, e){
  384.         this.beforeAction();
  385.         var cb = this.createCB(c);
  386.         supr.setHeight.call(this, h, a, d, cb, e);
  387.         if(!a){
  388.             cb();
  389.         }
  390.         return this;
  391.     },
  392.     // overridden Element method
  393.     setBounds : function(x, y, w, h, a, d, c, e){
  394.         this.beforeAction();
  395.         var cb = this.createCB(c);
  396.         if(!a){
  397.             this.storeXY([x, y]);
  398.             supr.setXY.call(this, [x, y]);
  399.             supr.setSize.call(this, w, h, a, d, cb, e);
  400.             cb();
  401.         }else{
  402.             supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
  403.         }
  404.         return this;
  405.     },
  406.     /**
  407.      * Sets the z-index of this layer and adjusts any shadow and shim z-indexes. The layer z-index is automatically
  408.      * incremented by two more than the value passed in so that it always shows above any shadow or shim (the shadow
  409.      * element, if any, will be assigned z-index + 1, and the shim element, if any, will be assigned the unmodified z-index).
  410.      * @param {Number} zindex The new z-index to set
  411.      * @return {this} The Layer
  412.      */
  413.     setZIndex : function(zindex){
  414.         this.zindex = zindex;
  415.         this.setStyle('z-index', zindex + 2);
  416.         if(this.shadow){
  417.             this.shadow.setZIndex(zindex + 1);
  418.         }
  419.         if(this.shim){
  420.             this.shim.setStyle('z-index', zindex);
  421.         }
  422.         return this;
  423.     }
  424. });
  425. })();