这一节,我们来制作弹出框,这个组件在非常多的网页中都有用到,其实大多数用到的还是css动画。其实用JS也可以做,但是请记住能CSS写的尽量别用JS写,专业的东西交给专业的做,因为用JS写非常的消耗性能,写的不好就炸了,常见的基本都可以通过css完成。

首先准备HTML

(慎重)这个HTML DOM结构 不好做css动画。正确的在后面。

  1. <div class="testContent" style="height:3000px;">
  2. <button id="login">show mask</button>
  3. </div>
  4. <div id="mask">
  5. <div class="box">
  6. <span class="close">x</span>
  7. <h1>Hello Mask!</h1>
  8. </div>
  9. </div>

准备CSS

  1. #mask{
  2. position: fixed;
  3. left: 0;
  4. right: 0;
  5. top: 0;
  6. bottom: 0;
  7. background: rgba(0,0,0,.7);
  8. display: flex;
  9. justify-content: center;
  10. align-items: center;
  11. transition: all ease-in-out 1s;
  12. }
  13. #mask .box{
  14. width: 800px;
  15. height: 400px;
  16. background: #f9f9f9;
  17. border: 1px solid #f7f7f7;
  18. border-radius: 5px;
  19. position: relative;
  20. }
  21. #mask .close{
  22. position: absolute;
  23. right: 20px;
  24. top: 20px;
  25. display: block;
  26. width: 30px;
  27. height: 30px;
  28. line-height: 30px;
  29. text-align: center;
  30. cursor: pointer;
  31. border-radius: 50%;
  32. color: #ff7878;
  33. border: 1px solid;
  34. }
  35. #mask .box h1{
  36. text-align: center;
  37. line-height: 400px;
  38. margin: 0;
  39. color: rgb(185, 185, 185);
  40. font-size: 80px;
  41. }

这里我们终于用了flex居中,我只是为了让大家认识到居中有很多种方法,想认识更多,上google搜一下,非常多的人写了类似的文章。

假如按照目前的HTML结构和思路去完善,写是可以写出来,但是想加上动画就不行了,因为在同一个div里面,都是公用一个transition属性。

之所以留下这些错误,是让大家可以试着完善,真正体会下这些坑,我写的时候,也是感觉怀疑人生的。

这里我们换一个DOM结构,把 mask 分离开来。因为我们想在mask里面添加一个动画,还想在box里面添加一个动画,假如2个在一起就会发生重叠。而且transition是对display:none,变成display:block不起动画作用的。我们用opacity/visibility代替,之所以不随便用z-index是因为,这会造成一些bug。你可以尝试加上z-index试一试,你会发现当z-index为1的时候,按钮是白色的,其他地方是黑色的,这种体验就非常不好了。

  1. <div class="testContent" style="height:3000px;">
  2. <button id="login">show mask</button>
  3. </div>
  4. <div id="mask"></div>
  5. <div id="dialog">
  6. <div class="box">
  7. <span class="close">x</span>
  8. <h1>Hello Mask!</h1>
  9. </div>
  10. </div>

假如我们尝试把 transition: all .7s ; 加到 #dialog里面,会发现动画不起作用了。

  1. #mask, #dialog{
  2. position: fixed;
  3. left: 0;
  4. right: 0;
  5. top: 0;
  6. bottom: 0;
  7. visibility: hidden;
  8. }
  9. #mask{
  10. background: rgba(0,0,0,.7);
  11. opacity: 0;
  12. transition: all .7s ;
  13. }
  14. #dialog{
  15. justify-content: center;
  16. align-items: center;
  17. display: flex;
  18. }
  19. #dialog .box{
  20. width: 800px;
  21. height: 400px;
  22. background: #f9f9f9;
  23. border: 1px solid #f7f7f7;
  24. border-radius: 5px;
  25. transition: all .7s ;
  26. position: relative;
  27. top: -900px;
  28. }
  29. #mask.show{
  30. opacity: 1;
  31. visibility: visible;
  32. }
  33. #dialog.show{
  34. display: flex;
  35. visibility: visible;
  36. }
  37. #dialog.show .box{
  38. top: 0px;
  39. }
  40. #dialog .close{
  41. position: absolute;
  42. right: 20px;
  43. top: 20px;
  44. display: block;
  45. width: 30px;
  46. height: 30px;
  47. line-height: 30px;
  48. text-align: center;
  49. cursor: pointer;
  50. border-radius: 50%;
  51. color: #ff7878;
  52. border: 1px solid;
  53. }
  54. #dialog .close:hover{
  55. color:red;
  56. }
  57. #dialog .box h1{
  58. text-align: center;
  59. line-height: 400px;
  60. margin: 0;
  61. color: rgb(185, 185, 185);
  62. font-size: 80px;
  63. }

JS逻辑其实就是添加类名。

  1. const loginBtn = document.querySelector('#login');
  2. const mask = document.querySelector('#mask');
  3. const closeBtn = document.querySelector('#dialog .close');
  4. const dialog = document.querySelector('#dialog');
  5. function close(){
  6. dialog.classList.remove('show');
  7. mask.classList.remove('show')
  8. }
  9. function open(){
  10. dialog.classList.add('show');
  11. mask.classList.add('show')
  12. }
  13. loginBtn.addEventListener('click', open);
  14. closeBtn.onclick = close
  15. dialog.onclick = (e) => {
  16. if(e.target.id == 'dialog') close();
  17. }