氣泡彈框的實現


本人是一個前端的新手,記錄一下自己的成長過程,文章寫得內容都很low,希望能各位大牛看到后能指點一下文章和代碼的問題。

 

在做一個練手的項目,遇到一個很常用的場景:把鼠標放在頭像框上彈出一個氣泡,顯示更多內容。記錄一下實現這個功能的過程:

首先要解決的就是氣泡框的效果,這個很容易實現,設置一個帶邊框的容器,然后在容器下面加一個三角,此時三角是實心的,通過after在覆蓋一個與容器同顏色的小三角即可

    .pop{
      width:200px;
      height:100px;
      border:2px solid grey;
      border-radius: 2px;
      box-shadow: 2px 2px 2px grey;
      position:absolute;
      background-color:white;
    }
    .triangle-bottom{
      width:0;
      height:0;
      border-top:20px solid grey;
      border-left:10px dashed transparent;
      border-right:10px dashed transparent;
      position:absolute;
      left:90px;
      top:100px;
    } 
   <div class='pop' id='pop'>
      <div id='triangle' class='triangle-bottom'></div>
    </div>

效果如圖

接下來的問題就是把它放在合適的位置,這里有兩個思路,一個是一個頭像配一個pop,一個是只用一個pop,動態的去添加內容和修改位置。第一種實現起來很簡單,但是觀察了一下百度貼吧的代碼,應該用的是第二種方案(請教一下高人兩種方案的優缺點)。下面探索一下第二種方案的實現。

可以給需要展示氣泡的dom設置onmouseover和onmouseout事件,默認氣泡的display為none,onmouseover事件將它設置為block,並獲取對象目標在頁面的偏移量,並分別賦給氣泡的top和left,onmouseout事件負責將氣泡隱藏。

    <div onmouseover="show()" onmouseout="hiden()" class='base'>
        鼠標放我上面出氣泡
    </div>


  <script type="text/javascript">
      function show(event){
        event=event||window.event;
          let pop=document.getElementById('pop');
        let x=0,y=0;
        let target = event.currentTarget;

      do{
        x+=target.offsetTop;
        y+=target.offsetLeft;
        target=target.offsetParent;
      }while(target!==document.body)

        pop.style.display='block';
        pop.style.top=x-100+'px';
        pop.style.left=y-25+'px';

      }

    function hiden(){
      let pop=document.getElementById('pop');
      pop.style.display='none';
    }
  </script>

提一下獲取頁面偏移量的方法,absolute的參考坐標系為position為非block的父元素,此處相對於是body,所以獲取的是相對於body的偏移量。當頁面結構發生變化時上面的代碼就可能出現問題。我想到的解決方案是將position改為fixed,但是此時就要考慮滾動條的問題。

提到了滾動條就帶來了另一個問題,我們默認采用了箭頭向下的氣泡,如果頭像框過於靠近上邊界,就會導致氣泡移除頁面,此時需要一個箭頭向上的氣泡。如何判斷是否會移除頁面,可以通過頭像的上偏移量和滾動條的滾動距離進行比較。重寫上面兩個函數

      function show(event){
        event=event||window.event;
          let pop=document.getElementById('pop');
        let x=0,y=0;
        let target = event.currentTarget;
        while(target.offsetParent!==null){
          x+=target.offsetTop;
          y+=target.offsetLeft;
          target=target.offsetParent;
        }

        pop.style.display='block';
        pop.style.left=y-25+'px';
        if(x-100-100<document.body.scrollTop){
          document.getElementById('triangle').setAttribute('class','triangle-top');
          pop.style.top=x+150-document.body.scrollTop+'px';
        }else{
          document.getElementById('triangle').setAttribute('class','triangle-bottom');
          pop.style.top=x-100-document.body.scrollTop+'px';
        }
      }

    function hiden(){
      let pop=document.getElementById('pop');
      pop.style.display='none';
    }

過程有點亂,下面是整個頁面的代碼

<!DOCTYPE html>
<html>
  <head>
    <title>test2</title>
    <style type="text/css">
    .base{
      width:150px;
      height:150px;
      border:2px solid black;
      margin-top:100px;
      margin-left:100px;
    }
    .pop{
      width:200px;
      height:100px;
      border:2px solid grey;
      border-radius: 2px;
      box-shadow: 2px 2px 2px grey;
      position:fixed;
      display:none;
      background-color:white;
    }
    .triangle-bottom{
      width:0;
      height:0;
      border-top:20px solid grey;
      border-left:10px dashed transparent;
      border-right:10px dashed transparent;
      position:absolute;
      left:90px;
      top:100px;
    }
    .triangle-bottom:after{
      content:'';
      width:0;
      height:0;
      border-top:18px solid white;
      border-left:8px dashed transparent;
      border-right:8px dashed transparent;
      position:absolute;
      left:-8px;
      top:-20px;
    }
    .triangle-top{
      width:0;
      height:0;
      border-bottom:20px solid grey;
      border-left:10px dashed transparent;
      border-right:10px dashed transparent;
      position:absolute;
      left:90px;
      bottom:100px;
    }
    .triangle-top:after{
      content:'';
      width:0;
      height:0;
      border-bottom:18px solid white;
      border-left:8px dashed transparent;
      border-right:8px dashed transparent;
      position:absolute;
      left:-8px;
      bottom:-20px;
    }
    </style>
  </head>
  <body>
    <div onmouseover="show()" onmouseout="hiden()" class='base'>
        鼠標放我上面出氣泡
    </div>
      <div onmouseover="show()" onmouseout="hiden()" class='base'>
      鼠標放我上面出氣泡
    </div>
      <div onmouseover="show()" onmouseout="hiden()" class='base'>
      鼠標放我上面出氣泡
    </div>
      <div onmouseover="show()" onmouseout="hiden()" class='base'>
      鼠標放我上面出氣泡
    </div>
      <div onmouseover="show()" onmouseout="hiden()" class='base'>
      鼠標放我上面出氣泡
    </div>
      <div onmouseover="show()" onmouseout="hiden()" class='base'>
      鼠標放我上面出氣泡
    </div>
      <div onmouseover="show()" onmouseout="hiden()" class='base'>
      鼠標放我上面出氣泡
    </div>
      <div onmouseover="show()" onmouseout="hiden()" class='base'>
      鼠標放我上面出氣泡
    </div>

    <div class='pop' id='pop'>
      <div id='triangle' class='triangle-bottom'></div>
    </div>
  </body>
  <script type="text/javascript">
      function show(event){
      event=event||window.event;
          let pop=document.getElementById('pop');
      let x=0,y=0;
      let target = event.currentTarget;
      while(target.offsetParent!==null){
        x+=target.offsetTop;
        y+=target.offsetLeft;
        target=target.offsetParent;
      }

      pop.style.display='block';
      pop.style.left=y-25+'px';
      if(x-100-100<document.body.scrollTop){
        document.getElementById('triangle').setAttribute('class','triangle-top');
        pop.style.top=x+150-document.body.scrollTop+'px';
      }else{
        document.getElementById('triangle').setAttribute('class','triangle-bottom');
        pop.style.top=x-100-document.body.scrollTop+'px';
      }
      }

    function hiden(){
      let pop=document.getElementById('pop');
      pop.style.display='none';
    }
  </script>
</html>

至此,氣泡功能的樣式就算實現了,至於內容的填充就很簡單了。雖然實現了功能,但是這個方案好不好,代碼細節存在什么問題,希望各位大牛能指教一下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM