色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術文章
文章詳情頁

Vue3 實現雙盒子定位Overlay的示例

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

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

原理

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

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

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 來獲取具體元素。然后再在 生命周期中 進行計算。

計算兩個盒子的相對位置

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

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的坐標為到原點的偏移 const panelRect = panel.getBoundingClientRect(); const panelX = originX - panelRect.width / 2; const panelY = originY; // 設置 panel 數據,觸發節點變更 panelStyle.value.left = `${panelX}px`; panelStyle.value.top = `${panelY}px`; };});

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

監聽盒子的變化

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

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

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

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

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

然后,需要在dom銷毀前取消監聽。

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

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

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

至此,已經完成基本的雙盒子定位法的 Overlay 的設計。

小結

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

以上就是Vue3 實現雙盒子定位Overlay的示例的詳細內容,更多關于vue3 實現Overlay的資料請關注好吧啦網其它相關文章!

標簽: Vue
相關文章:
主站蜘蛛池模板: 99ri在线视频 | 亚洲综合色视频在线观看 | 国产美女又黄又爽又色视频免费 | 2022麻豆福利午夜久久 | 成人自拍小视频 | 手机看片国产免费 | 久久九九有精品国产56 | 怡红院免费的全部视频国产a | 亚洲qingse中文久久网 | 久久久国产99久久国产一 | 久草在线免费播放 | 91大神在线精品视频一区 | 99久久精品久久久久久婷婷 | 99热精品在线免费观看 | 99久久精品久久久久久清纯 | 亚洲国产欧美在线人成 | 日韩 欧美 自拍 | 午夜影院福利社 | 欧美三级三级三级爽爽爽 | 国产一级做a爱免费观看 | 久久精品国内偷自一区 | 看久久 | 亚洲视频中文 | 永久黄网站色视频免费网站 | 欧美中日韩在线 | 欧美日韩亚洲综合久久久 | 99国内精品 | 亚洲人妖女同在线播放 | 久久免费国产精品一区二区 | 中文字幕在线视频在线看 | 国产精品一区久久精品 | 亚洲高清免费 | 久久99国产精一区二区三区 | 成年人免费在线观看网站 | 日韩一区视频在线 | 国产伦久视频免费观看 视频 | 男女性男女刺激大片免费观看 | 亚洲伦| 国产一区二三区 | 国产乱子伦真实china | 亚洲国产成人va在线观看网址 |