日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

Vue3 實現(xiàn)雙盒子定位Overlay的示例

瀏覽:118日期:2022-10-17 09:57:20

在 Vue 3 中,使用 <Teleport> 可以很優(yōu)雅的把某個組件渲染到根節(jié)點之外的節(jié)點,同時使其渲染的內(nèi)容不喪失響應(yīng)式和對應(yīng)的生命周期函數(shù)調(diào)用。那么基于此,用 <Teleport> 實現(xiàn)相對于某一元素的 Overlay 。 實際上,這篇文章跟 Vue3 的關(guān)系不大,只是通過 Vue3 講解一類 Overlay 的設(shè)計方法。

原理

要實現(xiàn)相對于某一元素的 Overlay 需要依靠兩個元素,Origin 和 Panel,Origin 表示相對于的元素,而 Panel 表示 Overlay 本身,實現(xiàn)方法主要有兩種。

文本流定位法,基于 position 的 absolute 和 relative 特性,將 Panel 形成相對于 Origin 的位置來定位的方式。Overlay 基于 Origin 做固定偏移的雙盒子定位法,也就是本文需要講解的方法。實現(xiàn) 首先,通過<Teleport>,能夠建立頂層 Overlay,也就是在根節(jié)點創(chuàng)建一個新的節(jié)點。

setup(_, ctx) { const originRef = ref<HTMLElement>(); const panelRef = ref<HTMLElement>(); const panelStyle = ref<CSSProperties>({ position: ’absolute’ }); // ... return () => ( <> <div ref={originRef}>origin</div> <Teleport to='#cdk-overlay-anchor'> <div style={{ position: ’fixed’, top: 0, left: 0, right: 0, bottom: 0, height: ’100vh’, width: ’100vw’ pointerEvents: ’none’}}> <div ref={panelRef} style={panelStyle.value}> <div style={{height: ’100px’, width: ’100px’ border: ’1px solid black’}} /> </div> </div> </Teleport> </> );}

拿到這兩者的 dom ref 后,需要通過實時計算 Origin 的盒子的大小和位置,來獲得 Panel 的相對偏移。在 Vue 中,元素只有在 mounted 后才能獲取得到,所以可以通過 composition-api 的 onMouted 來獲取具體元素。然后再在 生命周期中 進(jìn)行計算。

計算兩個盒子的相對位置

如何計算 Origin 的大小和位置,以及獲取其變化后的監(jiān)聽。Origin 的大小和位置,通過 getBoundingClientRect 這一 API 來獲取,這一就可以開始計算 Overlay 的相對位置。假設(shè)我們要把 Overlay 放在 Origin 的正下方,計算函數(shù)應(yīng)該是這樣的。

const panelStyle = ref<CSSProperties>({ position: ’absolute’ });onMounted(() => { const origin = originRef.value; const panel = panelRef.value; if (!origin || !panel) { return ; } const calculate = () => { const rect = origin.getBoundingClientRect(); // 原點為 origin 元素的底邊中央正下方 const originX = rect.left + (rect.width / 2); const originY = rect.bottom; // panel的坐標(biāo)為到原點的偏移 const panelRect = panel.getBoundingClientRect(); const panelX = originX - panelRect.width / 2; const panelY = originY; // 設(shè)置 panel 數(shù)據(jù),觸發(fā)節(jié)點變更 panelStyle.value.left = `${panelX}px`; panelStyle.value.top = `${panelY}px`; };});

當(dāng)然,你還可以計算各個不同方向的 Panel 坐標(biāo)(比如,正左、正上、正下等),排列組合一下,一共有種27不同的情況(每個點依賴于兩個變量 X 和 Y;每個變量有三種不同的情況,左、中、右,或者,上、中、下)。

監(jiān)聽盒子的變化

在這里,我們將使用瀏覽器自帶的API 來對他們進(jìn)行監(jiān)聽。通過 MutationObserver 和 ResizeObserver,可以很輕松的監(jiān)聽 Origin 和 Panel 的大小和位置變化。

首先是監(jiān)聽 Origin 的大小和位置變化,這里采用的是 MutationObserver,因為導(dǎo)致位置變化的原因只能是 style,所以只需要監(jiān)聽 style 的變化即可。

const origin$ = new MutationObserver(calculate);origin$.observe(origin, { // 只需要拿到 attribute 的 style 的變化即可 attributeFilter: [’style’],});

Panel 只需要監(jiān)聽其大小的變化,大小變化有一個更加完美的API, ResizeObserver。

const panel$ = new ResizeObserver(calculate);panel$.observe(panel);

然后,需要在dom銷毀前取消監(jiān)聽。

// dom銷毀前取消監(jiān)聽onBeforeUnmount(() => { origin$.disconnect(); panel$.disconnect();});監(jiān)聽窗口事件

為了能夠正確的獲取變化,我們需要監(jiān)聽兩個事件:resize 和 scroll.

// 為了能夠在滾動事件捕獲前進(jìn)行計算,帶有滾動條的子元素也會因此觸發(fā)計算window.addEventListener(’scroll’, calculate, true);window.addEventListener(’resize’, calculate);最后,仍然要在銷毀前取消事件。// dom銷毀前取消監(jiān)聽onBeforeUnmount(() => { window.removeEventListener(’scroll’, calculate, true); window.removeEventListener(’resize’, calculate);});

至此,已經(jīng)完成基本的雙盒子定位法的 Overlay 的設(shè)計。

小結(jié)

通過雙盒子定位來構(gòu)建的 Overlay 能夠有效規(guī)避 CSS 帶來的問題 zindex 等一系列相關(guān)的問題,只用通過計算盒子之間的相對偏移,就能讓 Panel 附著于 Origin 上,這樣,實現(xiàn)類似下拉或者 Tooltip 等功能的時候,就會非常有用。同時,附上一個簡單例子,希望能帶來一些啟發(fā)。

以上就是Vue3 實現(xiàn)雙盒子定位Overlay的示例的詳細(xì)內(nèi)容,更多關(guān)于vue3 實現(xiàn)Overlay的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Vue
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
伊人网在线播放| 久久久久国产| 欧美一级网址| 亚洲二区视频| 久久中文字幕二区| 老司机精品视频在线播放| 一二三区精品| 蜜桃久久精品一区二区| 蜜桃视频第一区免费观看| 久久国产亚洲| 国产亚洲福利| 亚洲v天堂v手机在线| 亚洲欧洲美洲国产香蕉| 亚洲黄页一区| 国产欧美成人| 国产精品毛片视频| 在线精品亚洲欧美日韩国产| 成人日韩在线| av一区在线| 激情综合网站| 欧美伊人影院| 国产精品mm| 亚洲一级高清| 亚洲精品精选| 国产精品99精品一区二区三区∴ | 日韩网站中文字幕| 国产亚洲精品v| 欧美一级全黄| 日韩88av| 免费高清在线一区| 国产精品尤物| 婷婷激情一区| 亚洲国内精品| 青草综合视频| 99久久婷婷这里只有精品| 一区二区三区午夜视频| 精品国产一级| 亚洲精品成人一区| 电影91久久久| 亚洲自啪免费| 日韩精品一区二区三区免费观看| 久久最新视频| 中文字幕在线视频网站| 91精品国产自产观看在线| 婷婷成人在线| 激情国产在线| 欧美激情aⅴ一区二区三区 | 国产精品夜夜夜| 怡红院精品视频在线观看极品| 国产精品黄色| 日本aⅴ免费视频一区二区三区| 欧美肉体xxxx裸体137大胆| 亚洲aa在线| 亚洲精品伊人| 老鸭窝亚洲一区二区三区| 黑森林国产精品av| 久久精品免视看国产成人| 91精品国产自产精品男人的天堂| 日本韩国欧美超级黄在线观看| 欧美精品国产| 国产精品扒开腿做爽爽爽软件| 91九色精品| 久久精品国内一区二区三区水蜜桃| 精品亚洲成人| 国产精品日本一区二区不卡视频| 性一交一乱一区二区洋洋av| 国内精品99| 国产91久久精品一区二区| 私拍精品福利视频在线一区| 麻豆91精品视频| 日韩av在线中文字幕| 中文字幕一区久| 91精品一区二区三区综合| 久久精品人人| 超碰在线99| 欧美日韩国产免费观看视频| 激情久久婷婷| 久久国产66| 在线精品福利| 欧美日本久久| 国产高潮在线| 亚洲成人三区| 日韩精选在线| 精品伊人久久久| 国产精品久久久久久久免费观看| аⅴ资源天堂资源库在线| 亚洲精品一区二区妖精| 亚洲天堂免费| 成人国产精品一区二区免费麻豆| 久久99精品久久久野外观看| 日韩大片在线| 日本欧洲一区二区| 精品视频网站| 蜜臀91精品一区二区三区| 国产精品v日韩精品v欧美精品网站| 美女视频免费精品| 国产手机视频一区二区| 精品三级av在线导航| 欧美日韩视频| 精品99久久| 亚洲精品综合| 亚洲天堂av影院| 欧美日本三区| 五月天久久网站| 免费看日韩精品| 国产高潮在线| 国产欧美日韩在线观看视频| 欧美aa一级| 麻豆国产一区| 国产亚洲精品久久久久婷婷瑜伽| 久久久久久亚洲精品美女| 免费人成精品欧美精品| 少妇精品导航| 色爱综合网欧美| 国产乱码精品一区二区三区四区| 成人久久久久| 正在播放日韩精品| 国产精品调教| 国产精品亚洲欧美日韩一区在线 | 日韩大片在线播放| 久久久精品区| 日本强好片久久久久久aaa| 国产伊人精品| 中文一区一区三区高中清不卡免费| 日韩动漫一区| 亚洲精品一级| 免费国产亚洲视频| 免费精品视频最新在线| 免费在线视频一区| 在线亚洲激情| 免费久久久久久久久| 日本久久成人网| 高清一区二区| 国产不卡人人| 日韩欧美综合| 99久久婷婷| 香蕉久久久久久久av网站| 九一国产精品| 在线观看亚洲精品福利片| 久久亚洲不卡| 日韩福利视频导航| 欧美国产另类| 亚洲午夜精品久久久久久app| 91精品二区| 亚洲影视一区二区三区| 日韩精品一区二区三区免费视频| 欧美精品国产白浆久久久久| 日本天堂一区| 国产aⅴ精品一区二区三区久久| 国产91在线播放精品| 欧美肉体xxxx裸体137大胆| 久久福利精品| 国产精品一区二区美女视频免费看 | 婷婷中文字幕一区| 国产精品一区二区三区av麻| 国产成人精品亚洲日本在线观看| 日韩和欧美一区二区三区| 欧美成人亚洲| 日本亚州欧洲精品不卡| 激情欧美国产欧美| 中文字幕人成乱码在线观看 | 亚洲精品一区二区在线看| 国产精品成人自拍| 亚洲一区中文| 九色porny丨国产首页在线| 免费观看亚洲天堂| 亚洲尤物av| 久久一区国产| 国产欧美在线| 欧美成人精品午夜一区二区| 久久精品福利| 国产不卡精品在线| 久久青青视频| 亚洲午夜精品久久久久久app| 久久精品国产亚洲夜色av网站| 国产成人精品亚洲线观看| 国产一区二区三区久久| 精品一区二区三区在线观看视频 | 日韩av影院| 国产精久久久| 欧美影院视频| 久久一区欧美| 欧美黄色精品| 国产精品网在线观看| 日本欧美大码aⅴ在线播放| 国产精品一区二区三区四区在线观看| 久久福利在线| 久久久久久美女精品| 久久精品免费一区二区三区| 日韩午夜电影| 日韩一区精品视频| 丝瓜av网站精品一区二区| 国产高清一区| 久久香蕉精品| 日韩av二区在线播放| 日韩av中文在线观看| 国产视频一区二| 国产videos久久| 国产综合精品| 亚洲乱码久久|