气泡弹框的实现

本人是一个前端的新手,记录一下自己的成长过程,文章写得内容都很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>

至此,气泡功能的样式就算实现了,至于内容的填充就很简单了。虽然实现了功能,但是这个方案好不好,代码细节存在什么问题,希望各位大牛能指教一下。

转载于:https://www.cnblogs.com/lichliu/p/6372055.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值