lichliu

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

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

分类:

技术点:

相关文章:

  • 2021-11-09
  • 2022-01-29
  • 2022-12-23
  • 2022-12-23
  • 2022-02-16
  • 2021-07-03
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-11-27
  • 2021-08-25
  • 2021-12-06
  • 2022-01-04
  • 2022-12-23
  • 2022-01-06
  • 2021-06-24
相关资源
相似解决方案