本人是一個前端的新手,記錄一下自己的成長過程,文章寫得內容都很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>
至此,氣泡功能的樣式就算實現了,至於內容的填充就很簡單了。雖然實現了功能,但是這個方案好不好,代碼細節存在什么問題,希望各位大牛能指教一下。