整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          vue3 根據點擊位置,實現一個用戶頭像彈框定位

          vue3 根據點擊位置,實現一個用戶頭像彈框定位

          Vue3 根據點擊位置,實現一個用戶頭像彈框定位

          **開篇:**

          在Web開發中,響應式UI設計一直是提升用戶體驗的關鍵所在。Vue3以其優秀的響應式機制和簡潔的API深受開發者喜愛。本文將詳細介紹如何利用Vue3的功能特性,結合DOM事件處理和CSS定位,實現一個可以根據點擊位置動態顯示用戶頭像彈框的功能。為了確保文章具有實踐指導意義,我們將按照實際操作流程,逐步解析并提供核心代碼示例。

          ---

          ### **一、搭建Vue3項目與基礎布局**

          **標題:** 初始化項目與頁面結構設定

          **內容:**

          首先,使用Vue CLI創建一個新的Vue3項目,并在主頁面上設置基礎布局,包括一個用于觸發頭像彈框顯示的用戶頭像區域和一個隱藏的彈框組件。

          ```html

          <template>

          <div id="app">

          <!-- 用戶列表或其他包含頭像的區域 -->

          <div @click="showAvatarPopup($event)">

          <img :src="user.avatarUrl" alt="User Avatar" class="avatar" />

          </div>

          <!-- 頭像彈框組件,初始狀態為隱藏 -->

          <AvatarPopup v-if="isPopupVisible" :position="popupPosition" :user="user" @close="hideAvatarPopup" />

          </div>

          </template>

          <script>

          import AvatarPopup from '@/components/AvatarPopup.vue';

          export default {

          components: {

          AvatarPopup,

          },

          data() {

          return {

          isPopupVisible: false,

          user: { // 示例用戶數據

          avatarUrl: 'path/to/avatar.jpg',

          // 其他用戶信息...

          },

          popupPosition: { x: 0, y: 0 }, // 彈框初始位置

          };

          },

          methods: {

          showAvatarPopup(event) {

          this.popupPosition={ x: event.clientX, y: event.clientY }; // 獲取點擊位置

          this.isPopupVisible=true; // 顯示彈框

          },

          hideAvatarPopup() {

          this.isPopupVisible=false; // 隱藏彈框

          },

          },

          };

          </script>

          ```

          ### **二、創建并樣式化頭像彈框組件**

          **標題:** 設計并實現自定義的`AvatarPopup`組件

          **內容:**

          在`AvatarPopup.vue`組件中,我們需要接收傳遞過來的位置坐標,并使用CSS絕對定位來使彈框跟隨鼠標點擊位置展示。

          ```html

          <!-- AvatarPopup.vue -->

          <template>

          <div class="avatar-popup" :style="{ top: position.y + 'px', left: position.x + 'px' }">

          <img :src="user.avatarUrl" alt="Popup Avatar" class="popup-avatar" />

          <!-- 其他用戶信息展示... -->

          <button @click="emitClose">關閉</button>

          </div>

          </template>

          <script>

          export default {

          props: {

          position: Object,

          user: Object,

          },

          emits: ['close'],

          methods: {

          emitClose() {

          this.$emit('close');

          },

          },

          };

          </script>

          <style scoped>

          .avatar-popup {

          position: absolute;

          width: fit-content;

          background-color: #fff;

          border-radius: 4px;

          box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);

          padding: 1rem;

          z-index: 1000; /* 確保彈框位于頂層 */

          }

          .popup-avatar {

          width: 100px;

          height: 100px;

          object-fit: cover;

          }

          </style>

          ```

          ### **三、優化彈框顯示邏輯**

          **標題:** 考慮邊界情況,確保彈框始終在可視區域內

          **內容:**

          為了防止彈框超出瀏覽器窗口范圍,我們需要對計算出的彈框位置進行適當的調整:

          ```javascript

          // 在App.vue中的methods內

          showAvatarPopup(event) {

          const viewportWidth=document.documentElement.clientWidth;

          const viewportHeight=document.documentElement.clientHeight;

          const popupWidth=document.querySelector('.avatar-popup').offsetWidth;

          const popupHeight=document.querySelector('.avatar-popup').offsetHeight;

          const x=Math.min(Math.max(event.clientX, popupWidth / 2), viewportWidth - popupWidth / 2);

          const y=Math.min(Math.max(event.clientY, popupHeight / 2), viewportHeight - popupHeight / 2);

          this.popupPosition={ x, y };

          this.isPopupVisible=true;

          }

          ```

          ### **四、添加過渡動畫效果**

          **標題:** 使用Vue Transition實現彈框顯示/隱藏動畫

          **內容:**

          為了讓彈框的出現和消失更加流暢自然,我們可以使用Vue的Transition組件包裹AvatarPopup,為其添加CSS過渡動畫。

          ```html

          <!-- App.vue -->

          <transition name="fade" appear>

          <AvatarPopup v-if="isPopupVisible" :position="popupPosition" :user="user" @close="hideAvatarPopup" />

          </transition>

          <style>

          .fade-enter-active,

          .fade-leave-active {

          transition: opacity .3s ease;

          }

          .fade-enter-from,

          .fade-leave-to {

          opacity: 0;

          }

          </style>

          ```

          ---

          **總結:**

          通過以上步驟,我們成功地在Vue3項目中實現了根據點擊位置動態定位用戶頭像彈框的功能。這一功能在社交網絡、評論區以及其他需要展現用戶詳細信息的場景中非常實用,既提升了用戶體驗,也展現了Vue3強大而靈活的應用能力。隨著進一步實踐,你可以嘗試增加更多高級功能,如自動調整彈框方向以適應屏幕邊界,或是集成拖拽移動等功能,從而使得彈框組件更為完善和人性化。

          ue3 根據點擊位置,實現一個用戶頭像彈框定位

          需求背景

          最近在做直播后臺,涉及到對用戶的一些操作,比如關注/取關/禁言/踢出直播間。多個地方都要用,需要封裝一個彈框組件

          效果圖


          實現過程分析

          1. 根據點擊元素,獲取元素的位置
          2. 動態設置元素top,left位置

          top 和 left 如何獲取

          根據 點擊事件event參數,來獲取位置,根據需要來實際計算位置

          • 元素距離左邊的距離 + 元素本身的寬度

          獲取元素top/left,其實直接用getBoundingClientRect 里的bottom / right 即可


          代碼實現

          export const getCurrentDialogXY=(event: Event)=> {
            const target=event.target as HTMLElement
            const { bottom, right }=target.getBoundingClientRect()
            return { bottom, right }
          }

          調用

          
          ```js
          const avatarHandler=(event: Event)=> {
            const { right, bottom }=getCurrentDialogXY(event)
            currentX.value=right
            currentY.value=bottom
          }

          傳入子組件,在子組件內接收到left/top 重新定位即可

              <user-info-dialog
                  :left="currentX"
                  :top="currentY"
              />
          <div ref="userInfoRef" class="dialog-wrap" :style="{ top: top + 'px', left: left + 'px' }"></div>

          細節處理

          1. 通過設置,你會發現彈框始終定位在元素右下角,可以根據自身需求,設置元素位置

          通過監聽彈框的ref(彈框有顯示隱藏邏輯,所以監聽彈框的ref即可,然后動態設置位置),

          watchEffect(()=> {
            const userInfoRefValue=userInfoRef.value
            if (userInfoRefValue) {
              const offsetHeight=userInfoRefValue.offsetHeight // 獲取彈框的高度
              const offsetWidth=userInfoRefValue.offsetWidth // 獲取元素的寬度
          
              // 不管彈框顯示是左側還是右側,根據需求 都需要 減去 彈框的高度 - 用戶頭像高度的一半 進行定位
                propTop.value=props.top - offsetHeight - userAvatarWidth.value / 2
                
              // 如果是彈框顯示在左側,需要減去彈框的寬度 - 頭像的寬度
              if (props.roleEnumType===1) {
                propLeft.value=props.left - offsetWidth - userAvatarWidth.value
              }
            }
          })
          1. 彈框打開之后,要點擊所有位置,都可以關閉
          • 那我們就需要實現一個朦層(透明色),點擊朦層,觸發關閉即可


          你會發現,其實我們的整個元素,是直接在根節點上,根常規里的,每個彈框,必須要綁定在循環里,才能做一一對應的關系,怎么不太一樣呢? 這里是用到的

          vue3中的Teleport:將其插槽內容渲染到 DOM 中的另一個位置 這對于我們層級比較多,做全局定位,脫離當前元素,非常好用!!!

          目中經常會出現點擊跳轉錨點的方法,比如給一個a標簽一個href=“#錨點”,然后要跳的錨點給個id=“錨點”,這樣就實現簡單的跳轉,但是這樣在url地址欄后面都會出現一個諸如www.csdn.net#錨點,然后你點擊給一次后退都是退回上一個選擇的錨點url,這里總結一些跳轉錨點的方法。

          第一種方法,也是最簡單的方法是錨點用<a>標簽,在href屬性中寫入DIV的id。如下:

          <!DOCTYPE html>

          <html>

          <head>

          <style>

          div {

          height: 800px;

          width: 400px;

          border: 2px solid black;

          }

          h2 {

          position: fixed;

          margin:50px 500px;

          }

          </style>

          </head>

          <body>

          <h2>

          <a href="#div1">to div1</a>

          <a href="#div2">to div2</a>

          <a href="#div3">to div3</a>

          </h2>

          <div id="div1">div1</div>

          <div id="div2">div2</div>

          <div id="div3">div3</div>

          </body>

          </html>

          這種方法的缺點是點擊錨點之后,瀏覽器的URL會發生變化,如果刷新可能會出現問題。

          第二種方法是在js事件中通過window.location.hash="divId"跳轉,但地址也會發生變化,感覺跟第一種方法沒區別,甚至更麻煩。

          第三種方法是用animate屬性,當點擊錨點后,頁面滾動到相應的DIV。接著上面的代碼,具體添加如下代碼:

          <script type="text/javascript" src="http://code.jquery.com/jquery-1.8.0.min.js"></script>

          <script type="text/javascript">

          $(document).ready(function() {

          $("#div1Link").click(function() {

          $("html, body").animate({

          scrollTop: $("#div1").offset().top }, {duration: 500,easing: "swing"});

          return false;

          });

          $("#div2Link").click(function() {

          $("html, body").animate({

          scrollTop: $("#div2").offset().top }, {duration: 500,easing: "swing"});

          return false;

          });

          $("#div3Link").click(function() {

          $("html, body").animate({

          scrollTop: $("#div3").offset().top }, {duration: 500,easing: "swing"});

          return false;

          });

          });

          </script>

          注意:運行上面的腳本的之前,先將為錨點增加相應的id,同時去掉href屬性。

          $("html, body")可以替換為響應的div,如果不起作用,試著給該div增加overflow:scroll屬性。

          另外,腳本可以進一步優化,自己來試試

          這樣做的好處是:URL地址不會變,同時點擊錨點時會自動響應scroll事件,不需要重新綁定。

          缺點是:如果頁面復雜的話,偏移值可能會發生變化需要算法輔助。

          第四種方法是用js的srollIntoView方法,直接用:

          document.getElementById("divId").scrollIntoView();

          比如:

          document.querySelector("#roll1").onclick=function(){

          document.querySelector("#roll1_top").scrollIntoView(true);

          }

          這里就是點擊id是#roll1的元素可以滾動到id是#roll1_top的地方,這里的#roll1和#roll1_top最好是一一對應的,

          這種方法的好處,是URL不會變,同時能夠響應相應的scroll事件,不需要算法什么的。代碼如下:

          <html>

          <head>

          <title>HTML5_ScrollInToView方法</title>

          <meta charset="utf-8">

          <script type="text/javascript">

          window.onload=function(){

          /*

          如果滾動頁面也是DOM沒有解決的一個問題。為了解決這個問題,瀏覽器實現了一下方法,

          以方便開發人員如何更好的控制頁面的滾動。在各種專有方法中,HTML5選擇了scrollIntoView()

          作為標準方法。

          scrollIntoView()可以在所有的HTML元素上調用,通過滾動瀏覽器窗口或某個容器元素,

          調用元素就可以出現在視窗中。如果給該方法傳入true作為參數,或者不傳入任何參數,那么

          窗口滾動之后會讓調動元素頂部和視窗頂部盡可能齊平。如果傳入false作為參數,調用元素

          會盡可能全部出現在視口中(可能的話,調用元素的底部會與視口的頂部齊平。)不過頂部

          不一定齊平,例如:

          //讓元素可見

          document.forms[0].scrollIntoView();

          當頁面發生變化時,一般會用這個方法來吸引用戶注意力。實際上,為某個元素設置焦點也

          會導致瀏覽器滾動顯示獲得焦點的元素。

          支持該方法的瀏覽器有 IE、Firefox、Safari和Opera。

          */

          document.querySelector("#roll1").onclick=function(){

          document.querySelector("#roll_top").scrollIntoView(false);

          }

          document.querySelector("#roll2").onclick=function(){

          document.querySelector("#roll_top").scrollIntoView(true);

          }

          }

          </script>

          <style type="text/css">

          #myDiv{

          height:900px;

          background-color:gray;

          }

          #roll_top{

          height:900px;

          background-color:green;

          color:#FFF;

          font-size:50px;

          position:relative;

          }

          #bottom{

          position:absolute;

          display:block;

          left;0;bottom:0;

          }

          </style>

          </head>

          <body>

          <button id="roll1">scrollIntoView(false)</button>

          <button id="roll2">scrollIntoView(true)</button>

          <div id="myDiv"></div>

          <div id="roll_top">

          scrollIntoView(ture)元素上邊框與視窗頂部齊平

          <span id="bottom">scrollIntoView(false)元素下邊框與視窗底部齊平</span>

          </div>

          </body>

          </html>

          個人建議使用第四種方法。


          主站蜘蛛池模板: 日本精品无码一区二区三区久久久 | 国产亚洲一区二区三区在线观看 | 国产另类ts人妖一区二区三区| 久久精品一区二区三区资源网| 国产suv精品一区二区6| 日韩好片一区二区在线看| 日本一区二区三区在线网| 成人免费一区二区三区在线观看| 亚洲一区二区三区四区视频| 中文字幕无码一区二区免费| 亚洲美女高清一区二区三区| 欧洲精品一区二区三区在线观看| 精品一区二区久久久久久久网精| 中文无码一区二区不卡αv | 久久久国产一区二区三区| 一区视频在线播放| 日韩电影在线观看第一区| 日韩视频免费一区二区三区| 秋霞日韩一区二区三区在线观看| 国产品无码一区二区三区在线| 亚洲日韩国产一区二区三区在线| 国产乱码精品一区二区三区中| 精品一区二区三区无码免费视频 | 中文字幕一区视频一线| 久久精品国产亚洲一区二区三区| 亚洲AⅤ视频一区二区三区| 无码精品人妻一区| 丰满人妻一区二区三区视频| 一区二区三区在线观看视频| 精品女同一区二区三区免费播放| 国产91一区二区在线播放不卡| 中文乱码精品一区二区三区| 亚洲国产成人一区二区精品区| 久久久国产精品一区二区18禁| 亚洲一区二区三区无码国产| 狠狠做深爱婷婷久久综合一区| 美女福利视频一区二区| 国产在线视频一区| 中文字幕一区二区精品区| 夜夜精品视频一区二区| 一区二区福利视频|