当前位置: 代码网 > it编程>编程语言>Javascript > 基于React实现一个todo打勾效果

基于React实现一个todo打勾效果

2024年05月18日 Javascript 我要评论
正好呢,最近做的一些东西让我燃起了一些些记录的热情,不能再咕咕了。背景是我自己做的 landing 项目里有一个实现类似飞书里的 todo 的效果,然后我研究了下飞书,写出来了一个 demo。我们先来

正好呢,最近做的一些东西让我燃起了一些些记录的热情,不能再咕咕了。

背景是我自己做的 landing 项目里有一个实现类似飞书里的 todo 的效果,然后我研究了下飞书,写出来了一个 demo。

我们先来提出几个问题,解决了之后,我们也就实现了一个todo

  • 前面的 icon 用什么来实现。
  • 如何实现文字不可点击,前方icon可点击的效果?
  • 如果有多个元素循环渲染的情况下,我们怎么在点击的时候对单个元素做样式的修改?(react)

这里有几个部分需要来讨论:

首先是整个用什么来实现这个前面的 icon,是使用伪元素,还是使用一个真实的元素?

这里我看飞书直接用的伪元素来实现的,感觉可能是能用 css 解决的问题就没有必要再去用 html 去写了,那么大致实现逻辑如下。

 <div class="todo" id="todo">11111</div>

我们使用伪元素实现这个样式的时候,左侧并不会撑开,也就是说,我们需要去给这个 div 一个靠左的 margin 值。然后再去做具体的打勾框。

    .todo {
        pointer-events: none;
        margin-left: 20px;
    }

    .todo:before {
        content: " ";
        display: inline-block;
        line-height: normal;
        font-size: 16px;
        border: 1px solid black;
        border-radius: 4px;
        background-position: 50%;
        white-space: normal;
        width: 16px;
        height: 16px;
        margin-right: 8px;
        margin-left: -24px;
        box-sizing: border-box !important;
        position: relative;
        cursor: pointer;
        pointer-events: auto;
        top: 2px;
    }

那么上面这些代码,就可以得到下图的展示效果:

是不是看起来已经有了完整的样子啦。

这是我们的 todo 状态,我们还需要实现一个 done的状态,所以还需要额外的 css 去书写,这里需要注意的是,为了交互更加好看,我们在 hover 的时候会让伪元素的样式变蓝。于是增加了如下代码,有了下图所示的效果

    .todo:hover:before {
        border: 1px solid rgb(100, 149, 237);
    }

第二个点就是,我们如何实现一个文字不可点击,前方icon可点击的效果呢?

其实在上面的代码中已经展示出来了,为这个 div设置pointer-events: none;,然后给伪元素设置pointer-events: auto;就可以啦。

这些考虑完之后,我再给你们展示一下点击状态的css咋写的:

    .done {
        text-decoration: line-through;
    }

    .done::before {
        background-image: url(data:image/svg+xml;base64,phn2zyb3awr0ad0imtqiighlawdodd0imtqiigzpbgw9im5vbmuiihhtbg5zpsjodhrwoi8vd3d3lnczlm9yzy8ymdawl3n2zyi+phbhdgggzd0ittewlju4osazljkwm2wuoda4ljgwogeumzuumzugmcawmtagljq5nuw2lje4idewljqynweumzuumzugmcawms0undk1idbmmi43mdmgny40ndrhljm1ljm1idagmdewls40otvsljgwoc0uoda4ys4zns4znsawidaxljq5nsawbdeuoti1ideuoti0idqumtyzltqumtyzys4zns4znsawidaxljq5nsaweiigzmlsbd0iizmznzbgriivpjwvc3znpg==);
    }

那么你给这个 div 再加上 done 的类名,就可以得到下图的效果了:

最后呢,如果我们有多个 div,我们如何去做类名的处理呢?

答案是监听点击事件,然后在点击的时候更换类名,代码如下:

    const div = document.getelementbyid('todo');
    div.addeventlistener('click', (target) => {
        const classarr = target.currenttarget.classname.split(' ');
        if (classarr.length > 1) {
            target.currenttarget.classname = 'todo'
        } else {
            target.currenttarget.classname = 'todo done'
        }
    })

完整代码如下:

<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>document</title>
</head>

<body>
    <div class="todo" id="todo">11111</div>
</body>
<script>
    const div = document.getelementbyid('todo');
    div.addeventlistener('click', (target) => {
        const classarr = target.currenttarget.classname.split(' ');
        if (classarr.length > 1) {
            target.currenttarget.classname = 'todo'
        } else {
            target.currenttarget.classname = 'todo done'
        }
    })
</script>
<style>
    .todo {
        margin-left: 20px;
    }

    .todo:before {
        content: " ";
        display: inline-block;
        line-height: normal;
        font-size: 16px;
        border: 1px solid black;
        border-radius: 4px;
        background-position: 50%;
        white-space: normal;
        width: 16px;
        height: 16px;
        margin-right: 8px;
        margin-left: -24px;
        box-sizing: border-box !important;
        position: relative;
        cursor: pointer;
        pointer-events: auto;
        top: 2px;
    }

    .todo:hover:before {
        border: 1px solid rgb(100, 149, 237);
    }

    .done {
        text-decoration: line-through;
    }

    .done::before {
        background-image: url(data:image/svg+xml;base64,phn2zyb3awr0ad0imtqiighlawdodd0imtqiigzpbgw9im5vbmuiihhtbg5zpsjodhrwoi8vd3d3lnczlm9yzy8ymdawl3n2zyi+phbhdgggzd0ittewlju4osazljkwm2wuoda4ljgwogeumzuumzugmcawmtagljq5nuw2lje4idewljqynweumzuumzugmcawms0undk1idbmmi43mdmgny40ndrhljm1ljm1idagmdewls40otvsljgwoc0uoda4ys4zns4znsawidaxljq5nsawbdeuoti1ideuoti0idqumtyzltqumtyzys4zns4znsawidaxljq5nsaweiigzmlsbd0iizmznzbgriivpjwvc3znpg==);
    }
</style>

</html>

到此这篇关于基于react实现一个todo打勾效果的文章就介绍到这了,更多相关react todo打勾内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com