html+js+css实现拖拽式便签留言

前些日子在网上冲浪时,看到一个便签式留言墙,让人耳目一新。心想这个看着不错,额想要。于是便开始搜寻是否有相应开源插件,想将其引入自己的博客中。但是搜寻了一圈,都没有符合预期的,要么功能不符合。有的功能符合,样式差强人意。我想两者结合一下就好了~于是乎,我开始自己动手,先整理一个独立的html留言版页面来试试效果。

1.便签效果图

功夫不负有心人,最终实现效果如图:

怎么样,是不是一眼就喜欢上了,纯js版出来了,后面要引入到博客中也简单了。最近lz一直在建设自己的博客,也了解了一些开源的博客框架,诸如Hexo、WordPress、VuePress、Hugo、Solo、Halo。

lz用的博客用的typecho框架,选择的主题是jasmine,这个主题是比较朴素的,功能很少,很干净。这正是lz所看重的,同时也是遗憾的点,太过于简洁以致于百废待兴。要"装饰"的地方很多,不过这种一点点从无到有的感觉也挺让人充满成就感的。因此最近一直在"装饰"博客。后面有时间lz会整理一个关于博客装修的系列博文说明。

2.单html源码

html 复制代码
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        #messagewall {
            margin: 0 auto;
            width: 960px;
            background: url(https://ktcry.cn/blog/messbg.png);
            background-size: cover;
            height: 627px;
            position: relative;
        }

        #messagewall .tip1, #messagewall .tip2, #messagewall .tip3, #messagewall .tip4, #messagewall .tip5, #messagewall .tip6, #messagewall .tip7, #messagewall .tip8 {
            position: absolute;
            width: 227px;
            left: 200px;
            top: 100px;
            background: rgb(187, 78, 117);
            box-shadow: 0 2px 10px 1px rgba(0,0,0,0.2);
            opacity: 0.88;
            border-radius: 400px 20px 30px 30px / 40px 400px 500px 300px;
        }

        #messagewall .tip1 .tip_h, #messagewall .tip2 .tip_h, #messagewall .tip3 .tip_h, #messagewall .tip4 .tip_h, #messagewall .tip5 .tip_h, #messagewall .tip6 .tip_h, #messagewall .tip7 .tip_h, #messagewall .tip8 .tip_h {
            width: 207px;
            padding: 10px 10px 5px;
            height: 23px;
            text-align: left;
            cursor: move;
            color: #fff;
            border-bottom: 1px dashed rgba(255,255,255,0.85);
            font-size: 15px;
        }

        #messagewall .tip1 .tip_c, #messagewall .tip2 .tip_c, #messagewall .tip3 .tip_c, #messagewall .tip4 .tip_c, #messagewall .tip5 .tip_c, #messagewall .tip6 .tip_c, #messagewall .tip7 .tip_c, #messagewall .tip8 .tip_c {
            width: 200px;
            padding-top: 20px;
            padding-left: 15px;
            padding-right: 15px;
            min-height: 40px;
            color: #fff;
            font-size: 14px;
            text-align: left;
            line-height: 20px;
            max-height: 160px;
            word-wrap: break-word;
            word-break: break-all;
            overflow: hidden;
        }

        #messagewall .tip1 .tip_f, #messagewall .tip2 .tip_f, #messagewall .tip3 .tip_f, #messagewall .tip4 .tip_f, #messagewall .tip5 .tip_f, #messagewall .tip6 .tip_f, #messagewall .tip7 .tip_f, #messagewall .tip8 .tip_f {
            width: 227px;
            height: 53px;
            padding-top: 20px;
        }
        .clr {
            clear: both;
            overflow: auto;
            display: block;
            height: 0px;
        }
        #messagewall .icon {
            float: left;
            width: 35px;
            padding-left: 15px;
            height: 35px;
            text-align: center;
        }
        #messagewall .name {
            float: right;
            padding-right: 15px;
            text-align: right;
            font-size: 14px;
            line-height: 35px;
            color: #C0F;
        }
        #messagewall .num {
            float: left;
            padding-left: 7px;
            width: 195px;
        }
    </style>
</head>
<body>
    <p style="text-align: center;">
        <strong><span style="font-size: 20px;">为你停留,因你回首</span></strong>
    </p>
    <p style="text-align: center;">
        你站在桥上看风景,看风景的人却在楼上看你。 明月装饰了你的房子,你装饰了我的梦。
    </p>
    <!--纸条墙-->
    <div id="messagewall">
        
    </div>
    <!-- 悬浮播放器:https://musicplayer.xfyun.club/ -->
    <div id="xf-MusicPlayer" data-cdnName="https://player.xfyun.club/js"  data-memory="1"></div>
    <script src="https://player.xfyun.club/js/xf-MusicPlayer/js/xf-MusicPlayer.min.js"></script>
    <script src="https://player.xfyun.club/js/yinghua.js"></script>
<script>
    //模拟数据库,获取信息
    var messages = [
            {"id":1,"name":"mahu","content":"今天你拿苹果支付了么","time":"2024-06-17"},
            {"id":2,"name":"haha","content":"今天天气不错,风和日丽的","time":"2024-06-18"},
            {"id":3,"name":"jjjj","content":"常要说的事儿是乐生于苦","time":"2016-03-18"},
            {"id":4,"name":"9.8的妹纸","content":"把朋友家厕所拉堵了 不敢出去 掏了半小时了都","time":"2016-03-18"},
            {"id":5,"name":"雷锋ii.","content":"元宵节快乐","time":"2024-06-22"},
            {"id":6,"name":"哎呦哥哥.","content":"据说今晚央视的元宵晚会导演和春晚导演是同一个人,真是躲得过初一,躲不过十五。","time":"2024-06-22"},
            {"id":7,"name":"没猴哥,不春晚","content":"班主任:"小明,你都十二岁了,还是三年级,不觉得羞愧吗"?。小明:"一点也不觉得,老师你都四十多岁了,不也是年年在三年级混日子吗?羞愧的应该是你"。老师:......","time":"2024-06-22"},
            {"id":8,"name":"哎呦杰杰.","content":"真搞不懂你们地球人,月亮有什么好看的,全是坑,还是对面那哥们好看,","time":"2024-06-22"},
            {"id":9,"name":"哎呦哎呦","content":"今天哪里的烟花最好看!!?答:朋友圈。。。","time":"2024-06-22"}
        ];

    //需求1:模拟数据库获取信息,然后在页面上生成数组的长度个tip,然后分别问起内容进行修改。
    //需求2:点击内容,提高层级;点击关闭按钮,删除tip标签;双击顶部,删除标签.....

    //需求1:模拟数据库获取信息,然后在页面上生成数组的长度个tip,然后分别问起内容进行修改。
    //步骤:
    //获取相关元素
        var content = document.getElementById("messagewall");
        var containerWidth = content.offsetWidth;  //获取容器位置,限制便签生成位置在容器内
        var containerHeight = content.offsetHeight;
        //循环生成div标签,然后为innerHTML属性添加内容
        for(var i=0;i<messages.length;i++){
            //生成新标签
            var newDiv = document.createElement("div");
            //绑定类名和ID
            newDiv.className = "tip1 draggable";
            newDiv.id = "tip"+messages[i].id;
            //改变位置
            var topValue = parseInt(Math.random()*(containerHeight-250));
            var leftValue = parseInt(Math.random()*(containerWidth-250));
            newDiv.style.top = topValue+"px";
            newDiv.style.left = leftValue+"px";
            //赋值内容
            newDiv.innerHTML = '<div class="tip_h" title="双击关闭纸条">'+
                                        '<div class="num">'+messages[i].time+'</div>'+
                                        '<div class="clr"></div>'+
                                '</div>'+
                                '<div class="tip_c">'+
                                    messages[i].content+
                                 '</div>'+
                                '<div class="tip_f">'+
                                    '<div class="icon">'+
                                    '<img src="https://cravatar.cn/avatar/00c96b1072831e92d1ab6ffd361a0b94?d=mm&s=35" alt="" title="">'+
                                '</div>'+
                                '<div class="name">'+messages[i].name+'</div>'+
                                    '<div class="clr"></div>'+
                                '</div>';
            //把新创建的元素放入content里面
            content.appendChild(newDiv);
            //随机背景色
            var elements = document.querySelectorAll('.tip1');
            const colors = ['#F8D800', '#0396FF', '#EA5455', '#7367F0', '#32CCBC', '#F6416C', '#28C76F', '#9F44D3', '#F55555', '#736EFE', '#E96D71', '#DE4313', '#D939CD', '#4C83FF', '#F072B6', '#C346C2', '#5961F9', '#FD6585', '#465EFB', '#FFC600', '#FA742B', '#5151E5', '#BB4E75', '#FF52E5', '#49C628', '#00EAFF', '#F067B4', '#F067B4', '#ff9a9e', '#00f2fe', '#4facfe', '#f093fb', '#6fa3ef', '#bc99c4', '#46c47c', '#f9bb3c', '#e8583d', '#f68e5f'];
            const random = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
            // 为每个元素生成随机 RGB 背景色
            elements.forEach(function(el) {
                // 生成随机 RGB 值
                const background = colors[random(0, colors.length - 1)];
                // 应用样式
                el.style.backgroundColor = background;
            })
            //绑定事件,提高层级
            //newDiv.onclick = fn;

            //双击关闭按钮类名叫做tip_h
            var dbDiv = newDiv.getElementsByClassName("tip_h")[0];
            dbDiv.ondblclick = function () {
                //不能用newDiv,因为在页面加载的时候newDiv,已经变成最后一个了,当你点击的时候,用远关闭的是最后的那个div。
                //content.removeChild(newDiv);
                content.removeChild(this.parentNode);
            }

        }

        var index = 1;
        function fn(){
            this.style.zIndex = index;
            index++;
        }
    // 如果你有多个.draggable元素
    // 首先获取所有的拖拽元素
    var draggableElems = document.querySelectorAll('.draggable');
    // 设置一个数组用来存放初始化后的所有拖拽元素
    var draggies = []
    // 初始化
    for ( var i=0, len = draggableElems.length; i < len; i++ ) {
    var draggableElem = draggableElems[i];
    var draggie = new Draggabilly( draggableElem, {
        containment:'#messagewall'
    });
    // 设置拖拽开始时的事件处理函数
    draggie.on('dragStart', function() {
        this.element.style.zIndex = index++;
    });
    draggies.push( draggie );
    }
</script>

</html>

3.小结

还是老规矩,直接单文件,拿来即用。了解我的人都知道,我是一个"懒人"。能凑一块发出来的,并不细分。方便你我他。另外,该便签留言效果已引入博客中,也欢迎各种有识之士来访留言,多多交流,下面附上博客地址:

流情无水的博客

相关推荐
北极糊的狐42 分钟前
vue使用v-if和:class完成条件渲染
javascript·vue.js·ecmascript
2402_857589361 小时前
便捷就医新引擎:SSM 医院预约挂号系统 Vue 实现方案设计
前端·javascript·vue.js
冴羽2 小时前
Solid.js 最新官方文档翻译(6)—— 组件事件处理程序
前端·javascript·react.js
weixin_307779132 小时前
用SparkSQL和PySpark完成按时间字段顺序将字符串字段中的值组合在一起分组显示
javascript·ajax·ecmascript
elirlove13 小时前
html在线转换工具集合大全
前端·javascript·html
阿琳a_4 小时前
解决uniapp中使用axios在真机和模拟器下请求报错问题
前端·javascript·uni-app
m0_748235955 小时前
前端三件套-css
前端·css
Riesenzahn5 小时前
写一个方法反转给定的字符串
前端·javascript
风清云淡_A6 小时前
【原生js案例】移动端如何实现页面的入场和出场动画
前端·javascript
一叶茶6 小时前
前端生成docx文档、excel表格、图片、pdf文件
前端·javascript·react