@@ -266,6 +266,7 @@ interface PanelPlacementOptions {
266266 defaultLeft ?: number
267267 placement ?: '' | 'top' | 'bottom' | null
268268 defaultPlacement ?: '' | 'top' | 'bottom' | null
269+ appendTo ?: string | HTMLElement | ( ( params : any ) => string | HTMLElement )
269270 teleportTo ?: boolean
270271 marginSize ?: number
271272 isMinWidth ?: boolean
@@ -275,7 +276,8 @@ interface PanelPlacementOptions {
275276 * 通用定位计算
276277 */
277278export function updatePanelPlacement ( targetElem : HTMLElement | null | undefined , panelElem : HTMLElement | null | undefined , options : PanelPlacementOptions ) {
278- const { defaultTop, defaultLeft, placement, defaultPlacement, teleportTo, marginSize, isMinWidth } = Object . assign ( {
279+ const { defaultTop, defaultLeft, placement, defaultPlacement, appendTo, teleportTo, marginSize, isMinWidth } = Object . assign ( {
280+ appendTo : '' ,
279281 teleportTo : false ,
280282 marginSize : 18 ,
281283 isMinWidth : true
@@ -289,7 +291,7 @@ export function updatePanelPlacement (targetElem: HTMLElement | null | undefined
289291 const stys : Record < string , string > = { }
290292 if ( panelElem && targetElem ) {
291293 const bodyEl = document . body
292- const parentWrapperEl = getPopupWrapperElement ( panelElem )
294+ const parentWrapperEl = getPopupWrapperElement ( teleportTo ? getPopupAppendElement ( appendTo ) : panelElem )
293295 if ( parentWrapperEl ) {
294296 const targetWidth = targetElem . offsetWidth
295297 const targetHeight = targetElem . offsetHeight
@@ -302,16 +304,18 @@ export function updatePanelPlacement (targetElem: HTMLElement | null | undefined
302304 const visibleHeight = bodyEl . clientHeight
303305 const visibleWidth = bodyEl . clientWidth
304306
305- const offsetLeft = parentWrapperRect . left
306- const offsetTop = parentWrapperRect . top
307+ const parentWrapperScrollLeft = parentWrapperEl . scrollLeft
308+ const parentWrapperScrollTop = parentWrapperEl . scrollTop
309+ const parentWrapperOffsetLeft = parentWrapperRect . left
310+ const parentWrapperOffsetTop = parentWrapperRect . top
307311 const targetLeft = targetRect . left
308312 const targetTop = targetRect . top
309313
310314 minWidth = targetElem . offsetWidth
311315
312316 if ( teleportTo ) {
313- left = defaultLeft || ( targetLeft - ( panelWidth - targetWidth ) / 2 )
314- top = defaultTop || ( targetTop + targetHeight )
317+ left = ( defaultLeft || ( targetLeft - ( panelWidth - targetWidth ) / 2 ) ) - parentWrapperScrollLeft
318+ top = ( defaultTop || ( targetTop + targetHeight ) ) - parentWrapperScrollTop
315319 if ( placement === 'top' ) {
316320 panelPlacement = 'top'
317321 top = targetTop - panelHeight
@@ -354,8 +358,8 @@ export function updatePanelPlacement (targetElem: HTMLElement | null | undefined
354358 }
355359
356360 // 偏移
357- top -= offsetTop
358- left -= offsetLeft
361+ top -= parentWrapperOffsetTop
362+ left -= parentWrapperOffsetLeft
359363 } else {
360364 if ( placement === 'top' ) {
361365 panelPlacement = 'top'
0 commit comments