[前端小项目] 扩展卡片 Expanding Cards(50projects50days)

  • [前端小项目] 扩展卡片 Expanding Cards(50projects50days)已关闭评论
  • 144 次浏览
  • A+
所属分类:Web前端

?前言

  • 这个小项目源于github项目:✨50 projects 50 days, 这个项目包含了50个小型前端项目,适合学习了Html+Css+JavaScript但是还没有学习框架的前端新手作为练习。
  • 这里是原项目的代码实现?扩展卡片 Expanding Cards

?分析

[前端小项目] 扩展卡片 Expanding Cards(50projects50days)

?布局

  • 卡片横向排列,可以使用flex布局.
  • 文字位于卡片左下角,可以将卡片设置为相对定位position:relative;,文字设置为绝对定位position:absolute;,然后设置leftbottom属性.

?文字样式

  • 大卡片有文字,小卡片没有文字,一开始的想法是给小卡片的文字设置display:none;,大卡片的文字设置display:block;。后来发现不可行,因为点击小卡片后,一开始卡片还没完全变大,但是如果此时将文字的display:none;更换为display:block;则会出现文字被较小的宽度挤成好几行,尽管设置成溢出时不换行、显示省略号的样式,文字也是突然出现的,较为突兀。
  • 显示文字与否可以用调整透明度实现,不显示则opacity:0;,显示则opacity:1;,并且可以使用transition:opacity ease;,这样的话,过渡就会比较自然。

?点击事件

  • 这里我使用了事件委托,而不是每一个卡片都绑定点击事件,这样可以提高效率。事件委托是给这些卡片的父元素绑定点击事件,通过事件冒泡原理,当点击卡片时,父元素会检测到点击事件,然后可以通过event对象的target属性找到是哪一个卡片被点击了。这样的话就可以只绑定一个点击事件,而不是有多少卡片就要绑定多少点击事件,从而提高了效率。
  • 点击事件触发后:
    1. 所有卡片变成小卡片,即宽度设置为统一的较小的值。
    2. 被点击的卡片变成大卡片,即宽度设置为较大的值。
    3. 修改被点击的卡片内部文字的opacity,使其显现。

?代码

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <meta http-equiv="X-UA-Compatible" content="IE=edge">     <meta name="viewport" content="width=device-width, initial-scale=1.0">     <title>expanding-cards</title>     <style>         *{             margin: 0;             padding: 0;             box-sizing: border-box;         }         body{             min-height: 100vh;         }         .container{             min-height: 100vh;             width: 100%;             /* 使用flex布局 */             display: flex;             align-items: center;             justify-content: center;             padding: 0 60px;         }         .item{             width: 10%;             /* 小卡片统一的宽度 */             height: 80vh;             margin: 0 1rem;             position: relative;     /* 卡片设置相对定位 */             border-radius: 2rem;             background-repeat: no-repeat;             background-size: cover;             cursor: pointer;             transition: all ease-in-out 0.5s;         }          /* 卡片的背景图片源自原项目 */         .item:nth-of-type(1){             background-image: url('https://images.unsplash.com/photo-1558979158-65a1eaa08691?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80');         }         .item:nth-of-type(2){             background-image: url('https://images.unsplash.com/photo-1572276596237-5db2c3e16c5d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80');         }         .item:nth-of-type(3){             background-image: url('https://images.unsplash.com/photo-1507525428034-b723cf961d3e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1353&q=80');         }         .item:nth-of-type(4){             background-image: url('https://images.unsplash.com/photo-1551009175-8a68da93d5f9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1351&q=80');         }         .item:nth-of-type(5){             background-image: url('https://images.unsplash.com/photo-1549880338-65ddcdfd017b?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80');         }          /* 大卡片的宽度 */         .focus{             margin: 0 1rem;             width: 50%;         }         .item p{             /* 小卡片内部文字是不可见的 */             opacity: 0;         }         .focus p{             /* 大卡片内部文字可见 */             opacity: 1;             transition: all ease-in-out 0.5s;             color: #fff;             font-size: 32px;             font-weight: bold;             /* 文字使用绝对定位,并设置bottom和left,将文字置于卡片左下角 */             position: absolute;             bottom: 40px;             left: 40px;         }     </style> </head> <body>     <div class="container">         <div class="item focus"><p>Explore the world</p></div>         <div class="item"><p>Wild Forest</p></div>         <div class="item"><p>Sunny Beach</p></div>         <div class="item"><p>City on Winter</p></div>         <div class="item"><p>Mountains - Clouds</p></div>     </div> </body> <script>     window.onload = function(){         // 获取DOM元素         const container  = document.getElementsByClassName('container')[0];         const item = document.getElementsByClassName('item');          //绑定点击事件(事件委托)         container.onclick = function(e){             e = window.event || e;      //兼容firefox             const target = e.target;    //从target属性获取到被点击的元素             //首先将所有卡片设置为小卡片             for(let i=0;i<item.length;i++){                 item[i].classList.remove('focus');             }             //被点击的卡片额外设置成大卡片             target.classList.add("focus");         }     } </script> </html> 

参考文章