diff --git a/demo/js/widget/numbereditor/demo.number_editor.js b/demo/js/widget/numbereditor/demo.number_editor.js index 9a57706bd..bbd7181dd 100644 --- a/demo/js/widget/numbereditor/demo.number_editor.js +++ b/demo/js/widget/numbereditor/demo.number_editor.js @@ -14,7 +14,8 @@ Demo.FileManager = BI.inherit(BI.Widget, { }, height: 24, width: 150, - errorText: "hahah" + errorText: "hahah", + watermark: "每个人都是自己健康的第一责任人", }); editor1.on(BI.NumberEditor.EVENT_CHANGE, function () { if (BI.parseFloat(this.getValue()) < 1) { diff --git a/src/base/combination/combo.js b/src/base/combination/combo.js index f73fec11d..003571b29 100644 --- a/src/base/combination/combo.js +++ b/src/base/combination/combo.js @@ -196,28 +196,22 @@ this.popupView.visible(); var combo = (o.belowMouse && BI.isNotNull(e)) ? { element: { - 0: e.target, + 0: BI.extend({}, e.target, { + getBoundingClientRect: function () { + return { + left: e.pageX, + top: e.pageY, + width: 0, + height: 0, + }; + } + }), offset: function () { return { left: e.pageX, top: e.pageY, }; }, - bounds: function () { - // offset为其相对于父定位元素的偏移 - return { - x: e.offsetX, - y: e.offsetY, - width: 0, - height: 24, - }; - }, - outerWidth: function () { - return 0; - }, - outerHeight: function () { - return 24; - }, }, } : this.combo; var positionRelativeElement = BI.DOM.getPositionRelativeContainingBlock(BI.isNull(o.container) ? this.element[0] : BI.Widget._renderEngine.createElement(BI.isFunction(o.container) ? o.container() : o.container)[0]); diff --git a/src/core/controller/controller.layer.js b/src/core/controller/controller.layer.js index 6887603f7..abc2d7f0e 100644 --- a/src/core/controller/controller.layer.js +++ b/src/core/controller/controller.layer.js @@ -63,41 +63,54 @@ BI.LayerController = BI.inherit(BI.Controller, { var layout = BI.createWidget({ type: "bi.absolute", invisible: true, - items: [{ - el: widget, - left: 0, - right: 0, - top: 0, - bottom: 0 - }] + items: [ + { + el: widget, + left: 0, + right: 0, + top: 0, + bottom: 0 + } + ] }, context); BI.createWidget({ type: "bi.absolute", element: op.container || this.options.render, - items: [{ - el: layout, - left: offset.left || 0, - right: offset.right || 0, - top: offset.top || 0, - bottom: offset.bottom || 0 - }] + items: [ + { + el: layout, + left: offset.left || 0, + right: offset.right || 0, + top: offset.top || 0, + bottom: offset.bottom || 0 + } + ] }); if (w) { layout.element.addClass("bi-popup-view"); - layout.element.css({ - left: w.offset().left + (offset.left || 0), - top: w.offset().top + (offset.top || 0), - width: offset.width || (w.outerWidth() - (offset.left || 0) - (offset.right || 0)) || "", - height: offset.height || (w.outerHeight() - (offset.top || 0) - (offset.bottom || 0)) || "" - }); - layout.element.on("__resize__", function () { - w.is(":visible") && - layout.element.css({ + + function getComputedPosition() { + + var css = { left: w.offset().left + (offset.left || 0), top: w.offset().top + (offset.top || 0), width: offset.width || (w.outerWidth() - (offset.left || 0) - (offset.right || 0)) || "", height: offset.height || (w.outerHeight() - (offset.top || 0) - (offset.bottom || 0)) || "" - }); + }; + + const { top, left, scaleY, scaleX } = BI.DOM.getPositionRelativeContainingBlockRect(layout.element[0]); + + css.top = (css.top - top) / scaleY; + css.left = (css.left - left) / scaleX; + + return css; + } + + + layout.element.css(getComputedPosition()); + layout.element.on("__resize__", function () { + w.is(":visible") && + layout.element.css(getComputedPosition()); }); } this.add(name, widget, layout); diff --git a/src/core/platform/web/dom.js b/src/core/platform/web/dom.js index 203683297..9b1026683 100644 --- a/src/core/platform/web/dom.js +++ b/src/core/platform/web/dom.js @@ -249,12 +249,14 @@ }, _getLeftAlignPosition: function (combo, popup, extraWidth, container) { - var viewBounds = popup.element.bounds(), - windowBounds = BI.Widget._renderEngine.createElement("body").bounds(); - var left = combo.element.offset().left - (container ? container.getBoundingClientRect().left : 0) + extraWidth; + var comboRect = combo.element[0].getBoundingClientRect(), + popupRect = popup.element.bounds(), + viewportRect = document.documentElement.getBoundingClientRect(), + containerRect = container ? container.getBoundingClientRect() : { left: 0 }; + var left = comboRect.left - containerRect.left + extraWidth; - if (left + viewBounds.width > windowBounds.width) { - left = windowBounds.width - viewBounds.width; + if (left + popupRect.width - containerRect.left > viewportRect.width) { + left = viewportRect.width - popupRect.width - containerRect.left; } return left; }, @@ -285,17 +287,19 @@ }; }, - _getRightAlignPosition: function (combo, popup, extraWidth) { - var comboBounds = combo.element.bounds(), viewBounds = popup.element.bounds(); - return combo.element.offset().left + comboBounds.width - viewBounds.width - extraWidth; + _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) { - var left = this._getRightAlignPosition(combo, popup, extraWidth); + 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); + left = this._getLeftAlignPosition(combo, popup, extraWidth, container); dir = "right"; } if (left < 0) { @@ -317,14 +321,13 @@ }, getTopAlignPosition: function (combo, popup, extraHeight, needAdaptHeight, container) { - var comboOffset = combo.element.offset(); 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 = comboOffset.top - containerBounds.top + extraHeight; + top = comboBounds.top - containerBounds.top + extraHeight; } else if (needAdaptHeight) { top = comboBounds.top - containerBounds.top + extraHeight; adaptHeight = viewportBounds.height - comboBounds.top; @@ -375,20 +378,19 @@ }, getBottomAlignPosition: function (combo, popup, extraHeight, needAdaptHeight, container) { - var comboOffset = combo.element.offset(); 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 = comboOffset.top + comboBounds.height - containerBounds.top - popupBounds.height; + 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 = comboOffset.top - containerBounds.top + extraHeight; + top = comboBounds.top - containerBounds.top + extraHeight; dir = "bottom"; } else { top = 0; @@ -410,7 +412,6 @@ }, getBottomAdaptPosition: function (combo, popup, extraHeight, needAdaptHeight) { - var comboOffset = combo.element.offset(); var comboBounds = combo.element.bounds(), popupBounds = popup.element.bounds(), windowBounds = BI.Widget._renderEngine.createElement("body").bounds(); if (BI.DOM.isBottomSpaceEnough(combo, popup, extraHeight)) { @@ -418,8 +419,8 @@ } if (needAdaptHeight) { return { - top: comboOffset.top + comboBounds.height + extraHeight, - adaptHeight: windowBounds.height - comboOffset.top - comboBounds.height - extraHeight + top: comboBounds.top + comboBounds.height + extraHeight, + adaptHeight: windowBounds.height - comboBounds.top - comboBounds.height - extraHeight }; } if (popupBounds.height + extraHeight > windowBounds.height) { @@ -732,5 +733,19 @@ 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 + }; + }, }); })(); diff --git a/src/widget/numbereditor/number.editor.js b/src/widget/numbereditor/number.editor.js index 383560bf8..2624c5dc4 100644 --- a/src/widget/numbereditor/number.editor.js +++ b/src/widget/numbereditor/number.editor.js @@ -18,7 +18,8 @@ BI.NumberEditor = BI.inherit(BI.Widget, { errorText: "", step: 1, min: BI.MIN, - max: BI.MAX + max: BI.MAX, + watermark: "", }); }, @@ -30,6 +31,7 @@ BI.NumberEditor = BI.inherit(BI.Widget, { height: BI.toPix(o.height, 2), simple: o.simple, allowBlank: o.allowBlank, + watermark: o.watermark, value: o.valueFormatter(o.value), validationChecker: function (v) { // 不设置validationChecker就自动检测 @@ -89,23 +91,27 @@ BI.NumberEditor = BI.inherit(BI.Widget, { type: "bi.htape", height: BI.toPix(o.height, 2), element: this, - items: [this.editor, { - el: { - type: "bi.grid", - columns: 1, - rows: 2, - items: [{ - column: 0, - row: 0, - el: this.topBtn - }, { - column: 0, - row: 1, - el: this.bottomBtn - }] - }, - width: 23 - }] + items: [ + this.editor, { + el: { + type: "bi.grid", + columns: 1, + rows: 2, + items: [ + { + column: 0, + row: 0, + el: this.topBtn + }, { + column: 0, + row: 1, + el: this.bottomBtn + } + ] + }, + width: 23 + } + ] }); }, @@ -117,13 +123,13 @@ BI.NumberEditor = BI.inherit(BI.Widget, { return this.editor.isEditing(); }, - _checkValueInRange: function(v) { + _checkValueInRange: function (v) { var o = this.options; return !!(BI.isNumeric(v) && BI.parseFloat(v) >= o.min && BI.parseFloat(v) <= o.max); }, - _checkAdjustDisabled: function(v) { - if(this.options.validationChecker === BI.emptyFn) { + _checkAdjustDisabled: function (v) { + if (this.options.validationChecker === BI.emptyFn) { this.bottomBtn.setEnable(BI.parseFloat(v) > this.options.min); this.topBtn.setEnable(BI.parseFloat(v) < this.options.max); }