Position.pin = function (target, base) { target = normalize(target); base = normalize(base); // 设定目标元素的 position 为绝对定位 // 若元素的初始 position 不为 absolute,会影响元素的 display、宽高等属性 if(lib.getStyle(target.element,'position') !== 'fixed' || isIE6) { lib.setStyle(target.element,{ position:'absolute' }); isPosFixed = false; } else { isPosFixed = true; } // 将位置属性归一化为数值 // 注:必须放在上面这句 `css('position', 'absolute')` 之后, // 否则获取的宽高有可能不对 posConverter(target); posConverter(base); var parentOffset = getParentOffset(target); var baseOffset = base.offset(); var top = baseOffset.top + base.y - target.y - parentOffset.top; var left = baseOffset.left + base.x - target.x - parentOffset.left; lib.setStyle(target.element,{ left:left+'px', top:top+'px' }); };
_initSideNav: function () { var me = this; //获取sideNav的宽高 var wh = lib.getSize(this.element); this.navHeight = wh.height + 'px'; this.navWidth = wh.width + 'px'; //为了控制动画效果,添加一层wrap容器 var wrap = document.createElement('div'); lib.addClass(wrap, 'ui-nav-cnt-wrap'); this.navNodeWrap = wrap; lib.wrap(wrap, this.element.childNodes); lib.setStyle(wrap, { 'position': 'absolute', 'left': '0', 'right': '0', 'top': '0', 'bottom': '0', 'margin': 'auto', 'display': 'none', 'height': this.navHeight, 'width': this.navWidth }); lib.setStyle(this.element, { 'display':'block', 'overflow': 'visible', 'width': this.navWidth, 'height': this.navHeight }); if (this.get('map').enable) { this.navNodes = []; this.panelNodes = []; u.each(this.get('map').rule, function (value, key) { var domKey = lib.query(key), domValue = lib.query(value); if (domKey && domValue) { me.navNodes.push(domKey); me.panelNodes.push(domValue); } }) } //获取两个节点 this.whenElement = lib.query(this.get('when').node); this.topElement = lib.query(this.get('top').node); },
/** * 获取最近的祖先定位元素的offset * @param pinObj */ function getParentOffset(pinObj) { var parent = pinObj.element.offsetParent; if(parent === document.documentElement) { parent = document.body; } if(isIE6) { lib.setStyle(parent,{ zoom:1 }); } var offset; // 当 offsetParent 为 body, // 而且 body 的 position 是 static 时 // 元素并不按照 body 来定位,而是按 document 定位 // http://jsfiddle.net/afc163/hN9Tc/2/ // 因此这里的偏移值直接设为 0 0 if (parent === document.body && lib.getStyle(parent,'position') === 'static') { offset = { top:0, left: 0 }; } else { offset = lib.getPosition(parent); } // 根据基准元素 offsetParent 的 border 宽度,来修正 offsetParent 的基准位置 offset.top += numberize(lib.getStyle(parent,'border-top-width')); offset.left += numberize(lib.getStyle(parent,'border-left-width')); return offset; }
_setPosition:function(align) { if(!lib.isInDocument(this.element)){ return; } align || (align = this.get('align')); if(!align) { return; } //如果起先是隐藏的 var isHidden = lib.getStyle(this.element, 'display') === 'none'; if(isHidden) { //放入文档流中,但不可见 lib.setStyle(this.element,{ visibility:'hidden', display:'block' }); } //进行定位计算 Position.pin({ element: this.element, x:align.selfXY[0], y:align.selfXY[1] },{ element:align.baseElement, x:align.baseXY[0], y:align.baseXY[1] }); //重新可见 if(isHidden) { lib.setStyle(this.element, { visibility: 'visible' }); } //触发resize事件 this.fire('resize'); return this; },
this.after('render',function() { lib.setStyle(this.element,{ width:this.get('width'), height:this.get('height'), zIndex:this.get('zIndex') }); //首先将元素hide var position = lib.getStyle(this.element, 'position'); if(position === 'static' || position === 'relative') { lib.setStyle(this.element,{ position:'absolute', left:'-9999px', top:'-9999px' }); } });