You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
757 lines
34 KiB
757 lines
34 KiB
/** |
|
* 对DOM操作的通用函数 |
|
* @type {{}} |
|
*/ |
|
!(function () { |
|
BI.DOM = BI.DOM || {}; |
|
|
|
BI.extend(BI.DOM, { |
|
ready: function (fn) { |
|
BI.Widget._renderEngine.createElement(document).ready(fn); |
|
} |
|
}); |
|
|
|
BI.extend(BI.DOM, { |
|
|
|
patchProps: function (fromElement, toElement) { |
|
var elemData = BI.jQuery._data(fromElement[0]); |
|
var events = elemData.events; |
|
BI.each(events, function (eventKey, event) { |
|
BI.each(event, function (i, handler) { |
|
toElement.on(eventKey + (handler.namespace ? ("." + handler.namespace) : ""), handler); |
|
}); |
|
}); |
|
var fromChildren = fromElement.children(), toChildren = toElement.children(); |
|
if (fromChildren.length !== toChildren.length) { |
|
throw new Error("不匹配"); |
|
} |
|
BI.each(fromChildren, function (i, child) { |
|
BI.DOM.patchProps(BI.jQuery(child), BI.jQuery(toChildren[i])); |
|
}); |
|
BI.each(fromElement.data("__widgets"), function (i, widget) { |
|
widget.element = toElement; |
|
}); |
|
}, |
|
/** |
|
* 把dom数组或元素悬挂起来,使其不对html产生影响 |
|
* @param dom |
|
*/ |
|
hang: function (doms) { |
|
if (BI.isEmpty(doms)) { |
|
return; |
|
} |
|
var frag = BI.Widget._renderEngine.createFragment(); |
|
BI.each(doms, function (i, dom) { |
|
dom instanceof BI.Widget && (dom = dom.element); |
|
dom instanceof BI.$ && dom[0] && frag.appendChild(dom[0]); |
|
}); |
|
return frag; |
|
}, |
|
|
|
isExist: function (obj) { |
|
return BI.Widget._renderEngine.createElement("body").find(obj.element).length > 0; |
|
}, |
|
|
|
// 预加载图片 |
|
preloadImages: function (srcArray, onload) { |
|
var count = 0, images = []; |
|
|
|
function complete() { |
|
count++; |
|
if (count >= srcArray.length) { |
|
onload(); |
|
} |
|
} |
|
|
|
BI.each(srcArray, function (i, src) { |
|
images[i] = new Image(); |
|
images[i].src = src; |
|
images[i].onload = function () { |
|
complete(); |
|
}; |
|
images[i].onerror = function () { |
|
complete(); |
|
}; |
|
}); |
|
}, |
|
|
|
getTextSizeWidth: function (text, fontSize) { |
|
var span = BI.Widget._renderEngine.createElement("<span></span>").addClass("text-width-span").appendTo("body"); |
|
|
|
if (fontSize == null) { |
|
fontSize = 12; |
|
} |
|
fontSize = fontSize + "px"; |
|
|
|
span.css("font-size", fontSize).text(text); |
|
|
|
var width = span.width(); |
|
span.remove(); |
|
|
|
return width; |
|
}, |
|
|
|
getTextSizeHeight: function (text, fontSize) { |
|
var span = BI.Widget._renderEngine.createElement("<span></span>").addClass("text-width-span").appendTo("body"); |
|
|
|
if (fontSize == null) { |
|
fontSize = 12; |
|
} |
|
fontSize = fontSize + "px"; |
|
|
|
span.css("font-size", fontSize).text(text); |
|
|
|
var height = span.height(); |
|
span.remove(); |
|
|
|
return height; |
|
}, |
|
|
|
// 获取滚动条的宽度,页面display: none时候获取到的为0 |
|
getScrollWidth: function () { |
|
if (BI.isNull(this._scrollWidth) || this._scrollWidth === 0) { |
|
var ul = BI.Widget._renderEngine.createElement("<div>").width(50).height(50).css({ |
|
position: "absolute", |
|
top: "-9999px", |
|
overflow: "scroll" |
|
}).appendTo("body"); |
|
this._scrollWidth = ul[0].offsetWidth - ul[0].clientWidth; |
|
ul.destroy(); |
|
} |
|
return this._scrollWidth; |
|
}, |
|
|
|
getImage: function (param, fillStyle, backgroundColor) { |
|
var canvas = document.createElement("canvas"); |
|
var ratio = 2; |
|
BI.Widget._renderEngine.createElement("body").append(canvas); |
|
|
|
var ctx = canvas.getContext("2d"); |
|
ctx.font = "12px Helvetica Neue,Arial,PingFang SC,Hiragino Sans GB,Microsoft YaHei,微软雅黑,Heiti,黑体,sans-serif"; |
|
var w = ctx.measureText(param).width + 4; |
|
canvas.width = w * ratio; |
|
canvas.height = 16 * ratio; |
|
ctx.font = 12 * ratio + "px Helvetica Neue,Arial,PingFang SC,Hiragino Sans GB,Microsoft YaHei,微软雅黑,Heiti,黑体,sans-serif"; |
|
ctx.fillStyle = fillStyle || "#3685f2"; |
|
ctx.textBaseline = "middle"; |
|
// ctx.fillStyle = "#EAF2FD"; |
|
ctx.fillText(param, 2 * ratio, 9 * ratio); |
|
BI.Widget._renderEngine.createElement(canvas).destroy(); |
|
var backColor = backgroundColor || "rgba(54, 133, 242, 0.1)"; |
|
// IE可以放大缩小所以要固定最大最小宽高 |
|
return { |
|
width: w, |
|
height: 16, |
|
src: canvas.toDataURL("image/png"), |
|
style: "background-color: " + backColor + ";vertical-align: middle; margin: 0 1px; width:" + w + "px;height: 16px; max-width:" + w + "px;max-height: 16px; min-width:" + w + "px;min-height: 16px", |
|
param: param |
|
}; |
|
} |
|
}); |
|
|
|
BI.extend(BI.DOM, { |
|
|
|
getLeftPosition: function (combo, popup, extraWidth, container) { |
|
var el = combo.element; |
|
var popupEl = popup.element; |
|
var elRect = el[0].getBoundingClientRect(); |
|
var popupElRect = popupEl[0].getBoundingClientRect(); |
|
var containerRect = container ? container.getBoundingClientRect() : { left: 0 }; |
|
|
|
return { |
|
left: elRect.left - containerRect.left - popupElRect.width - (extraWidth || 0) |
|
}; |
|
}, |
|
|
|
getInnerLeftPosition: function (combo, popup, extraWidth) { |
|
return { |
|
left: combo.element.offset().left + (extraWidth || 0) |
|
}; |
|
}, |
|
|
|
getRightPosition: function (combo, popup, extraWidth, container) { |
|
var el = combo.element; |
|
var elRect = el[0].getBoundingClientRect(); |
|
var containerRect = container ? container.getBoundingClientRect() : { left: 0 }; |
|
|
|
return { |
|
left: elRect.left + elRect.width - containerRect.left + (extraWidth || 0) |
|
}; |
|
}, |
|
|
|
getInnerRightPosition: function (combo, popup, extraWidth) { |
|
var el = combo.element, viewBounds = popup.element.bounds(); |
|
return { |
|
left: el.offset().left + el.outerWidth() - viewBounds.width - (extraWidth || 0) |
|
}; |
|
}, |
|
|
|
getTopPosition: function (combo, popup, extraHeight, container) { |
|
var el = combo.element; |
|
var popupEl = popup.element; |
|
var elRect = el[0].getBoundingClientRect(); |
|
var popupElRect = popupEl[0].getBoundingClientRect(); |
|
var containerRect = container ? container.getBoundingClientRect() : { top: 0 }; |
|
|
|
return { |
|
top: elRect.top - containerRect.top - popupElRect.height - (extraHeight || 0) |
|
}; |
|
}, |
|
|
|
getBottomPosition: function (combo, popup, extraHeight, container) { |
|
var el = combo.element; |
|
var elRect = el[0].getBoundingClientRect(); |
|
var containerRect = container ? container.getBoundingClientRect() : { top: 0 }; |
|
|
|
return { |
|
top: elRect.top - containerRect.top + elRect.height + (extraHeight || 0) |
|
}; |
|
}, |
|
|
|
isLeftSpaceEnough: function (combo, popup, extraWidth) { |
|
return BI.DOM.getLeftPosition(combo, popup, extraWidth).left >= 0; |
|
}, |
|
|
|
isInnerLeftSpaceEnough: function (combo, popup, extraWidth) { |
|
var viewBounds = popup.element.bounds(), |
|
windowBounds = BI.Widget._renderEngine.createElement("body").bounds(); |
|
return BI.DOM.getInnerLeftPosition(combo, popup, extraWidth).left + viewBounds.width <= windowBounds.width; |
|
}, |
|
|
|
isRightSpaceEnough: function (combo, popup, extraWidth) { |
|
var viewBounds = popup.element[0].getBoundingClientRect(), |
|
viewportBounds = document.documentElement.getBoundingClientRect(); |
|
return BI.DOM.getRightPosition(combo, popup, extraWidth).left + viewBounds.width <= viewportBounds.width; |
|
}, |
|
|
|
isInnerRightSpaceEnough: function (combo, popup, extraWidth) { |
|
return BI.DOM.getInnerRightPosition(combo, popup, extraWidth).left >= 0; |
|
}, |
|
|
|
isTopSpaceEnough: function (combo, popup, extraHeight) { |
|
return BI.DOM.getTopPosition(combo, popup, extraHeight).top >= 0; |
|
}, |
|
|
|
isBottomSpaceEnough: function (combo, popup, extraHeight) { |
|
var viewBounds = popup.element[0].getBoundingClientRect(), |
|
viewportBounds = document.documentElement.getBoundingClientRect(); |
|
return BI.DOM.getBottomPosition(combo, popup, extraHeight).top + viewBounds.height <= viewportBounds.height; |
|
}, |
|
|
|
isRightSpaceLarger: function (combo) { |
|
var comboBounds = combo.element[0].getBoundingClientRect(), |
|
viewportBounds = document.documentElement.getBoundingClientRect(); |
|
return viewportBounds.width - comboBounds.right >= comboBounds.left; |
|
}, |
|
|
|
isBottomSpaceLarger: function (combo) { |
|
var comboBounds = combo.element[0].getBoundingClientRect(), |
|
viewportBounds = document.documentElement.getBoundingClientRect(); |
|
return viewportBounds.height - comboBounds.bottom >= comboBounds.top; |
|
}, |
|
|
|
_getLeftAlignPosition: function (combo, popup, extraWidth, container) { |
|
var comboRect = combo.element[0].getBoundingClientRect(), |
|
popupRect = popup.element[0].getBoundingClientRect(), |
|
viewportRect = document.documentElement.getBoundingClientRect(), |
|
containerRect = container ? container.getBoundingClientRect() : { left: 0 }; |
|
var left = comboRect.left - containerRect.left + extraWidth; |
|
|
|
if (comboRect.left + popupRect.width > viewportRect.width) { |
|
left = viewportRect.width - popupRect.width - containerRect.left; |
|
} |
|
return left; |
|
}, |
|
|
|
getLeftAlignPosition: function (combo, popup, extraWidth, container) { |
|
var left = this._getLeftAlignPosition(combo, popup, extraWidth, container); |
|
var dir = ""; |
|
// 如果放不下,优先使用RightAlign, 如果RightAlign也放不下, 再使用left=0 |
|
var containerRect = container ? container.getBoundingClientRect() : { left: 0 }; |
|
if (left + containerRect.left < 0) { |
|
left = this._getRightAlignPosition(combo, popup, extraWidth); |
|
dir = "left"; |
|
} |
|
if (left + containerRect.left < 0) { |
|
left = 0 - containerRect.left; |
|
} |
|
return { |
|
left: left, |
|
dir: dir || "right" |
|
}; |
|
}, |
|
|
|
getLeftAdaptPosition: function (combo, popup, extraWidth, container) { |
|
if (BI.DOM.isLeftSpaceEnough(combo, popup, extraWidth, container)) { |
|
return BI.DOM.getLeftPosition(combo, popup, extraWidth, container); |
|
} |
|
return { |
|
left: 0 |
|
}; |
|
}, |
|
|
|
_getRightAlignPosition: function (combo, popup, extraWidth, container) { |
|
var comboBounds = combo.element[0].getBoundingClientRect(), |
|
viewBounds = popup.element[0].getBoundingClientRect(), |
|
containerRect = container ? container.getBoundingClientRect() : { left: 0 }; |
|
return comboBounds.left + comboBounds.width - viewBounds.width - extraWidth - containerRect.left; |
|
}, |
|
|
|
getRightAlignPosition: function (combo, popup, extraWidth, container) { |
|
var left = this._getRightAlignPosition(combo, popup, extraWidth, container); |
|
var dir = ""; |
|
// 如果放不下,优先使用LeftAlign, 如果LeftAlign也放不下, 再使用left=0 |
|
if (left < 0) { |
|
left = this._getLeftAlignPosition(combo, popup, extraWidth, container); |
|
dir = "right"; |
|
} |
|
if (left < 0) { |
|
left = 0; |
|
} |
|
return { |
|
left: left, |
|
dir: dir || "left" |
|
}; |
|
}, |
|
|
|
getRightAdaptPosition: function (combo, popup, extraWidth, container) { |
|
if (BI.DOM.isRightSpaceEnough(combo, popup, extraWidth, container)) { |
|
return BI.DOM.getRightPosition(combo, popup, extraWidth, container); |
|
} |
|
return { |
|
left: document.documentElement.getBoundingClientRect().width - popup.element[0].getBoundingClientRect().width - container.getBoundingClientRect().left |
|
}; |
|
}, |
|
|
|
getTopAlignPosition: function (combo, popup, extraHeight, needAdaptHeight, container) { |
|
var comboBounds = combo.element[0].getBoundingClientRect(), |
|
popupBounds = popup.element[0].getBoundingClientRect(), |
|
viewportBounds = document.documentElement.getBoundingClientRect(), |
|
containerBounds = container ? container.getBoundingClientRect() : { top: 0 }; |
|
var top, adaptHeight, dir; |
|
if (BI.DOM.isBottomSpaceEnough(combo, popup, -1 * comboBounds.height + extraHeight)) { |
|
top = comboBounds.top - containerBounds.top + extraHeight; |
|
} else if (needAdaptHeight) { |
|
top = comboBounds.top - containerBounds.top + extraHeight; |
|
adaptHeight = viewportBounds.height - comboBounds.top; |
|
} else if (BI.DOM.isTopSpaceEnough(combo, popup, -1 * comboBounds.height + extraHeight)) { |
|
// 下方空间不足且不允许调整高度的情况下,优先使用上对齐 |
|
top = comboBounds.top + comboBounds.height - popupBounds.height - containerBounds.top - extraHeight; |
|
dir = "top"; |
|
} else { |
|
top = viewportBounds.height - popupBounds.height; |
|
if (top < extraHeight) { |
|
adaptHeight = viewportBounds.height - extraHeight; |
|
} |
|
} |
|
if (top < extraHeight) { |
|
top = extraHeight; |
|
} |
|
return adaptHeight ? { |
|
top: top, |
|
adaptHeight: adaptHeight, |
|
dir: dir || "bottom" |
|
} : { |
|
top: top, |
|
dir: dir || "bottom" |
|
}; |
|
}, |
|
|
|
getTopAdaptPosition: function (combo, popup, extraHeight, needAdaptHeight, positionRelativeElement) { |
|
var comboBounds = combo.element[0].getBoundingClientRect(), |
|
popupBounds = popup.element[0].getBoundingClientRect(), |
|
positionRelativeElementRect = positionRelativeElement.getBoundingClientRect(), |
|
viewportBounds = document.documentElement.getBoundingClientRect(); |
|
if (BI.DOM.isTopSpaceEnough(combo, popup, extraHeight)) { |
|
return BI.DOM.getTopPosition(combo, popup, extraHeight); |
|
} |
|
if (needAdaptHeight) { |
|
return { |
|
top: 0 - positionRelativeElementRect.top, |
|
adaptHeight: comboBounds.top - extraHeight |
|
}; |
|
} |
|
if (popupBounds.height + extraHeight > viewportBounds.height) { |
|
return { |
|
top: 0 - positionRelativeElementRect.top, |
|
adaptHeight: viewportBounds.height - extraHeight |
|
}; |
|
} |
|
return { |
|
top: 0 - positionRelativeElementRect.top |
|
}; |
|
}, |
|
|
|
getBottomAlignPosition: function (combo, popup, extraHeight, needAdaptHeight, container) { |
|
var comboBounds = combo.element[0].getBoundingClientRect(), |
|
popupBounds = popup.element[0].getBoundingClientRect(), |
|
windowBounds = BI.Widget._renderEngine.createElement("body").bounds(), |
|
containerBounds = container ? container.getBoundingClientRect() : { top: 0 }; |
|
var top, adaptHeight, dir; |
|
if (BI.DOM.isTopSpaceEnough(combo, popup, -1 * comboBounds.height + extraHeight)) { |
|
top = comboBounds.top + comboBounds.height - containerBounds.top - popupBounds.height; |
|
} else if (needAdaptHeight) { |
|
top = 0 - containerBounds.top; |
|
adaptHeight = comboBounds.top + comboBounds.height - extraHeight; |
|
} else if (BI.DOM.isBottomSpaceEnough(combo, popup, -1 * comboBounds.height + extraHeight)) { |
|
// 上方空间不足且不允许调整高度的情况下,优先使用下对齐 |
|
top = comboBounds.top - containerBounds.top + extraHeight; |
|
dir = "bottom"; |
|
} else { |
|
top = 0; |
|
if (popupBounds.height + extraHeight > windowBounds.height) { |
|
adaptHeight = windowBounds.height - extraHeight; |
|
} |
|
} |
|
if (top + containerBounds.top < 0) { |
|
top = 0; |
|
} |
|
return adaptHeight ? { |
|
top: top, |
|
adaptHeight: adaptHeight, |
|
dir: dir || "top" |
|
} : { |
|
top: top, |
|
dir: dir || "top" |
|
}; |
|
}, |
|
|
|
getBottomAdaptPosition: function (combo, popup, extraHeight, needAdaptHeight) { |
|
var comboBounds = combo.element[0].getBoundingClientRect(), |
|
popupBounds = popup.element[0].getBoundingClientRect(), |
|
windowBounds = BI.Widget._renderEngine.createElement("body").bounds(); |
|
if (BI.DOM.isBottomSpaceEnough(combo, popup, extraHeight)) { |
|
return BI.DOM.getBottomPosition(combo, popup, extraHeight); |
|
} |
|
if (needAdaptHeight) { |
|
return { |
|
top: comboBounds.top + comboBounds.height + extraHeight, |
|
adaptHeight: windowBounds.height - comboBounds.top - comboBounds.height - extraHeight |
|
}; |
|
} |
|
if (popupBounds.height + extraHeight > windowBounds.height) { |
|
return { |
|
top: extraHeight, |
|
adaptHeight: windowBounds.height - extraHeight |
|
}; |
|
} |
|
return { |
|
top: windowBounds.height - popupBounds.height - extraHeight |
|
}; |
|
}, |
|
|
|
getCenterAdaptPosition: function (combo, popup, positionRelativeElement) { |
|
var comboRect = combo.element[0].getBoundingClientRect(), |
|
popupRect = popup.element[0].getBoundingClientRect(), |
|
positionRelativeElementRect = positionRelativeElement.getBoundingClientRect(), |
|
viewportBounds = document.documentElement.getBoundingClientRect(); |
|
var left; |
|
if (comboRect.left + comboRect.width / 2 + popupRect.width / 2 > viewportBounds.width) { |
|
left = viewportBounds.width - comboRect.width - positionRelativeElementRect.left; |
|
} else { |
|
left = comboRect.left + (comboRect.width - popupRect.width) / 2 - positionRelativeElementRect.left; |
|
} |
|
if (left + positionRelativeElementRect.left < 0) { |
|
left = 0; |
|
} |
|
return { |
|
left: left |
|
}; |
|
}, |
|
|
|
getMiddleAdaptPosition: function (combo, popup, positionRelativeElement) { |
|
var comboRect = combo.element[0].getBoundingClientRect(), |
|
popupRect = popup.element[0].getBoundingClientRect(), |
|
positionRelativeElementRect = positionRelativeElement.getBoundingClientRect(), |
|
viewportBounds = document.documentElement.getBoundingClientRect(); |
|
|
|
var top; |
|
if (comboRect.top + comboRect.height / 2 + popupRect.height / 2 > viewportBounds.height) { |
|
top = viewportBounds.height - popupRect.height - positionRelativeElementRect.top; |
|
} else { |
|
top = comboRect.top + (comboRect.height - popupRect.height) / 2 - positionRelativeElementRect.top; |
|
} |
|
if (top + positionRelativeElementRect.top < 0) { |
|
top = 0; |
|
} |
|
return { |
|
top: top |
|
}; |
|
}, |
|
|
|
getComboPositionByDirections: function (combo, popup, extraWidth, extraHeight, needAdaptHeight, directions, container) { |
|
extraWidth || (extraWidth = 0); |
|
extraHeight || (extraHeight = 0); |
|
var i, direct; |
|
var leftRight = [], topBottom = [], innerLeftRight = []; |
|
var isNeedAdaptHeight = false, tbFirst = false, lrFirst = false; |
|
var left, top, pos, firstDir = directions[0]; |
|
for (i = 0; i < directions.length; i++) { |
|
direct = directions[i]; |
|
switch (direct) { |
|
case "left": |
|
leftRight.push(direct); |
|
break; |
|
case "right": |
|
leftRight.push(direct); |
|
break; |
|
case "top": |
|
topBottom.push(direct); |
|
break; |
|
case "bottom": |
|
topBottom.push(direct); |
|
break; |
|
case "innerLeft": |
|
innerLeftRight.push(direct); |
|
break; |
|
case "innerRight": |
|
innerLeftRight.push(direct); |
|
break; |
|
} |
|
} |
|
for (i = 0; i < directions.length; i++) { |
|
direct = directions[i]; |
|
switch (direct) { |
|
case "left": |
|
if (!isNeedAdaptHeight) { |
|
var tW = tbFirst ? extraHeight : extraWidth, tH = tbFirst ? 0 : extraHeight; |
|
if (BI.DOM.isLeftSpaceEnough(combo, popup, tW)) { |
|
left = BI.DOM.getLeftPosition(combo, popup, tW, container).left; |
|
if (topBottom[0] === "bottom") { |
|
pos = BI.DOM.getTopAlignPosition(combo, popup, tH, needAdaptHeight, container); |
|
} else { |
|
pos = BI.DOM.getBottomAlignPosition(combo, popup, tH, needAdaptHeight, container); |
|
} |
|
pos.dir = "left," + pos.dir; |
|
if (tbFirst) { |
|
pos.change = "left"; |
|
} |
|
pos.left = left; |
|
return pos; |
|
} |
|
} |
|
lrFirst = true; |
|
break; |
|
case "right": |
|
if (!isNeedAdaptHeight) { |
|
var tW = tbFirst ? extraHeight : extraWidth, tH = tbFirst ? extraWidth : extraHeight; |
|
if (BI.DOM.isRightSpaceEnough(combo, popup, tW)) { |
|
left = BI.DOM.getRightPosition(combo, popup, tW, container).left; |
|
if (topBottom[0] === "bottom") { |
|
pos = BI.DOM.getTopAlignPosition(combo, popup, tH, needAdaptHeight, container); |
|
} else { |
|
pos = BI.DOM.getBottomAlignPosition(combo, popup, tH, needAdaptHeight, container); |
|
} |
|
pos.dir = "right," + pos.dir; |
|
if (tbFirst) { |
|
pos.change = "right"; |
|
} |
|
pos.left = left; |
|
return pos; |
|
} |
|
} |
|
lrFirst = true; |
|
break; |
|
case "top": |
|
var tW = lrFirst ? extraHeight : extraWidth, tH = lrFirst ? extraWidth : extraHeight; |
|
if (BI.DOM.isTopSpaceEnough(combo, popup, tH)) { |
|
top = BI.DOM.getTopPosition(combo, popup, tH, container).top; |
|
if (leftRight[0] === "right") { |
|
pos = BI.DOM.getLeftAlignPosition(combo, popup, tW, container); |
|
} else { |
|
pos = BI.DOM.getRightAlignPosition(combo, popup, tW, container); |
|
} |
|
pos.dir = "top," + pos.dir; |
|
if (lrFirst) { |
|
pos.change = "top"; |
|
} |
|
pos.top = top; |
|
return pos; |
|
} |
|
if (needAdaptHeight) { |
|
isNeedAdaptHeight = true; |
|
} |
|
tbFirst = true; |
|
break; |
|
case "bottom": |
|
var tW = lrFirst ? extraHeight : extraWidth, tH = lrFirst ? extraWidth : extraHeight; |
|
if (BI.DOM.isBottomSpaceEnough(combo, popup, tH)) { |
|
top = BI.DOM.getBottomPosition(combo, popup, tH, container).top; |
|
if (leftRight[0] === "right") { |
|
pos = BI.DOM.getLeftAlignPosition(combo, popup, tW, container); |
|
} else { |
|
pos = BI.DOM.getRightAlignPosition(combo, popup, tW, container); |
|
} |
|
pos.dir = "bottom," + pos.dir; |
|
if (lrFirst) { |
|
pos.change = "bottom"; |
|
} |
|
pos.top = top; |
|
return pos; |
|
} |
|
if (needAdaptHeight) { |
|
isNeedAdaptHeight = true; |
|
} |
|
tbFirst = true; |
|
break; |
|
case "innerLeft": |
|
if (!isNeedAdaptHeight) { |
|
var tW = tbFirst ? extraHeight : extraWidth, tH = tbFirst ? 0 : extraHeight; |
|
if (BI.DOM.isInnerLeftSpaceEnough(combo, popup, tW)) { |
|
left = BI.DOM.getInnerLeftPosition(combo, popup, tW).left; |
|
if (topBottom[0] === "bottom") { |
|
pos = BI.DOM.getTopAlignPosition(combo, popup, tH, needAdaptHeight); |
|
} else { |
|
pos = BI.DOM.getBottomAlignPosition(combo, popup, tH, needAdaptHeight); |
|
} |
|
pos.dir = "innerLeft," + pos.dir; |
|
if (tbFirst) { |
|
pos.change = "innerLeft"; |
|
} |
|
pos.left = left; |
|
return pos; |
|
} |
|
} |
|
lrFirst = true; |
|
break; |
|
case "innerRight": |
|
if (!isNeedAdaptHeight) { |
|
var tW = tbFirst ? extraHeight : extraWidth, tH = tbFirst ? extraWidth : extraHeight; |
|
if (BI.DOM.isInnerRightSpaceEnough(combo, popup, tW)) { |
|
left = BI.DOM.getInnerRightPosition(combo, popup, tW).left; |
|
if (topBottom[0] === "bottom") { |
|
pos = BI.DOM.getTopAlignPosition(combo, popup, tH, needAdaptHeight); |
|
} else { |
|
pos = BI.DOM.getBottomAlignPosition(combo, popup, tH, needAdaptHeight); |
|
} |
|
pos.dir = "innerLeft," + pos.dir; |
|
if (tbFirst) { |
|
pos.change = "innerRight"; |
|
} |
|
pos.left = left; |
|
return pos; |
|
} |
|
} |
|
break; |
|
|
|
} |
|
} |
|
|
|
// 此处为四个方向放不下时挑空间最大的方向去放置, 也就是说我设置了弹出方向为"bottom,left", |
|
// 最后发现实际弹出方向可能是"top,left",那么此时外界获取popup的方向应该是"top,left" |
|
switch (directions[0]) { |
|
case "left": |
|
case "right": |
|
if (BI.DOM.isRightSpaceLarger(combo)) { |
|
left = BI.DOM.getRightAdaptPosition(combo, popup, extraWidth, container).left; |
|
firstDir = "right"; |
|
} else { |
|
left = BI.DOM.getLeftAdaptPosition(combo, popup, extraWidth, container).left; |
|
firstDir = "left"; |
|
} |
|
if (topBottom[0] === "bottom") { |
|
pos = BI.DOM.getTopAlignPosition(combo, popup, extraHeight, needAdaptHeight); |
|
pos.left = left; |
|
pos.dir = firstDir + "," + pos.dir; |
|
return pos; |
|
} |
|
pos = BI.DOM.getBottomAlignPosition(combo, popup, extraHeight, needAdaptHeight); |
|
pos.left = left; |
|
pos.dir = firstDir + "," + pos.dir; |
|
return pos; |
|
default : |
|
if (BI.DOM.isBottomSpaceLarger(combo)) { |
|
top = BI.DOM.getBottomAdaptPosition(combo, popup, extraHeight, needAdaptHeight, container).top; |
|
firstDir = "bottom"; |
|
} else { |
|
top = BI.DOM.getTopAdaptPosition(combo, popup, extraHeight, needAdaptHeight, container).top; |
|
firstDir = "top"; |
|
} |
|
if (leftRight[0] === "right") { |
|
pos = BI.DOM.getLeftAlignPosition(combo, popup, extraWidth, container); |
|
pos.top = top; |
|
pos.dir = firstDir + "," + pos.dir; |
|
return pos; |
|
} |
|
pos = BI.DOM.getRightAlignPosition(combo, popup, extraWidth, container); |
|
pos.top = top; |
|
pos.dir = firstDir + "," + pos.dir; |
|
return pos; |
|
} |
|
}, |
|
|
|
|
|
getComboPosition: function (combo, popup, extraWidth, extraHeight, needAdaptHeight, directions, offsetStyle, positionRelativeElement) { |
|
extraWidth || (extraWidth = 0); |
|
extraHeight || (extraHeight = 0); |
|
var viewportBounds = document.documentElement.getBoundingClientRect(); |
|
var maxHeight = Math.min(popup.attr("maxHeight") || viewportBounds.height, viewportBounds.height); |
|
popup.resetHeight && popup.resetHeight(maxHeight); |
|
var position = BI.DOM.getComboPositionByDirections(combo, popup, extraWidth, extraHeight, needAdaptHeight, directions || ["bottom", "top", "right", "left"], positionRelativeElement); |
|
switch (offsetStyle) { |
|
case "center": |
|
if (position.change) { |
|
var p = BI.DOM.getMiddleAdaptPosition(combo, popup, positionRelativeElement); |
|
position.top = p.top; |
|
} else { |
|
var p = BI.DOM.getCenterAdaptPosition(combo, popup, positionRelativeElement); |
|
position.left = p.left; |
|
} |
|
break; |
|
case "middle": |
|
if (position.change) { |
|
var p = BI.DOM.getCenterAdaptPosition(combo, popup, positionRelativeElement); |
|
position.left = p.left; |
|
} else { |
|
var p = BI.DOM.getMiddleAdaptPosition(combo, popup, positionRelativeElement); |
|
position.top = p.top; |
|
} |
|
break; |
|
} |
|
if (needAdaptHeight === true) { |
|
popup.resetHeight && popup.resetHeight(Math.min(viewportBounds.height - position.top + (positionRelativeElement ? positionRelativeElement.getBoundingClientRect().top : 0), maxHeight)); |
|
} |
|
return position; |
|
}, |
|
|
|
/** |
|
* 获取position:fixed相对定位的元素 |
|
*/ |
|
getPositionRelativeContainingBlock: function (element) { |
|
if (['html', 'body', '#document'].indexOf((element.nodeName || '').toLowerCase()) >= 0) { |
|
// $FlowFixMe[incompatible-return]: assume body is always available |
|
return element.ownerDocument.body; |
|
} |
|
|
|
function isExcept(node) { |
|
var _computedStyle = getComputedStyle(node); |
|
var transform = _computedStyle.transform; |
|
var perspective = _computedStyle.perspective; |
|
var filter = _computedStyle.filter; |
|
var willChange = _computedStyle["will-change"]; |
|
|
|
return [transform, perspective, filter].some(value => value !== 'none') || (willChange === "transform"); |
|
} |
|
|
|
if (isExcept(element)) { |
|
return element; |
|
} |
|
|
|
return BI.DOM.getPositionRelativeContainingBlock(element.parentNode); |
|
}, |
|
|
|
/** |
|
* 获取position:fixed相对定位的元素的clientRect |
|
*/ |
|
getPositionRelativeContainingBlockRect: function (element) { |
|
var positionRelativeElement = BI.DOM.getPositionRelativeContainingBlock(element); |
|
var rect = positionRelativeElement.getBoundingClientRect(); |
|
|
|
return { |
|
...rect.toJSON(), |
|
scaleX: rect.width / positionRelativeElement.offsetWidth, |
|
scaleY: rect.height / positionRelativeElement.offsetHeight |
|
}; |
|
}, |
|
}); |
|
})();
|
|
|