jjzjj

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

feixianxing 2023-03-28 原文

?前言

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

?分析


?布局

  • 卡片横向排列,可以使用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>

参考文章

有关[前端小项目] 扩展卡片 Expanding Cards(50projects50days)的更多相关文章

  1. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  2. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  3. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  4. Ruby 从大范围中获取第 n 个项目 - 2

    假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit

  5. ruby - 如何在 Ruby 字符串中插入项目符号字符? - 2

    我正在尝试创建一个带有项目符号字符的Ruby1.9.3字符串。str="•"+"helloworld"但是,当我输入它时,我收到有关非ASCII字符的语法错误。我该怎么做? 最佳答案 你可以把Unicode字符放在那里。str="\u2022"+"helloworld" 关于ruby-如何在Ruby字符串中插入项目符号字符?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1195

  6. ruby - 在 Rails 项目中测试本地版本的 gem - 2

    我的Rails站点使用了一个确实不是很好的gem。每次我需要做一些新的事情时,我最终不得不花费与向实际Rails项目添加代码一样多的时间来为gem添加功能。但我不介意,我将我的Gemfile设置为指向我的gem的GitHub分支(我尝试提交PR,但维护者似乎已经下台)。问题是我真的没有找到一种合理的方法来测试我添加到gem的新东西。在railsc中测试它会特别好,但我能想到的唯一方法是a)更改~/.rvm/gems/.../foo。rb,这看起来不对或者b)升级版本,推送到Github,然后运行​​bundleup,这除了耗时之外显然是一场灾难,因为我不确定我所做的promise是否正

  7. ruby - 如何更快地解决 project euler #21? - 2

    原始问题Letd(n)bedefinedasthesumofproperdivisorsofn(numberslessthannwhichdivideevenlyinton).Ifd(a)=bandd(b)=a,whereab,thenaandbareanamicablepairandeachofaandbarecalledamicablenumbers.Forexample,theproperdivisorsof220are1,2,4,5,10,11,20,22,44,55and110;therefored(220)=284.Theproperdivisorsof284are1,2,

  8. ruby-on-rails - rails : Find tasks that were created on a certain day? - 2

    我有一个任务列表(名称、starts_at),我试图在每日View中显示它们(就像iCal)。deftodays_tasks(day)Task.find(:all,:conditions=>["starts_atbetween?and?",day.beginning,day.ending]end我不知道如何将Time.now(例如“2009-04-1210:00:00”)动态转换为一天的开始(和结束),以便进行比较。 最佳答案 deftodays_tasks(now=Time.now)Task.find(:all,:conditio

  9. ruby - 合并 nanoc 中的项目 - 2

    我一直在尝试使用nanoc用于生成静态网站。我需要组织一个复杂的排列页面,我想让我的内容保持干燥。包含或合并的概念在nanoc系统中如何运作?我已阅读文档,但似乎找不到我想要的内容。例如:我如何获取两个部分内容项并将它们合并到一个新的内容项中。在staticmatic您可以在您的页面中执行以下操作。=partial('partials/shared/navigation')类似的约定在nanoc中如何运作? 最佳答案 这里是nanoc的作者。在nanoc中,部分是布局。因此,您可以拥有layouts/partials/shared/

  10. Ruby 和指南针路径与 yeoman 项目 - 2

    我安装了ruby​​、yeoman,当我运行我的项目时,出现了这个错误:Warning:Running"compass:dist"(compass)taskWarning:YouneedtohaveRubyandCompassinstalledthistasktowork.Moreinfo:https://github.com/gruUse--forcetocontinue.Use--forcetocontinue.我有进入可变session目标的路径,但它不起作用。谁能帮帮我? 最佳答案 我必须运行这个:geminstallcom

随机推荐