H5 拖动排序 美食排行榜

news2024/9/30 11:30:27

尝试写一下拖动元素进行排序,真是想到什么去写什么 😂,有的时候很多人老是跟我说,别人都封装好了,你为什么还要自己去实现一下,写的还没别人好。但我总感觉所有都用别人写好的,就放弃思考的机会了。

效果

img

逻辑

通过改变position: absolute;改变每个元素的transform:translate3d来调整悬浮元素位置,使用dom.before(item)dom.after(item)来修改操作元素插入位置。

难点

无…这个算是个实验品,总感觉上下切换时,没有别人写的丝滑。

源码


<!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>Document</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            height: 100vh;
            margin: 0;
            overflow: hidden;
        }

        h1 {
            margin-top: -20vh;

        }

        .ranking-list {
            display: flex;
            flex-direction: column;
            position: relative;
            align-items: center;
        }

        .ranking-item {
            position: absolute;
            width: 200px;
            padding: 10px 20px;
            transition: transform .5s;
            box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
            user-select: none;
            background: #fff;
            z-index: 1;
        }

        .ranking-item.active {
            transition: transform .5s ease-in, background .5s ease-out;
            background-color: #aaa;
            z-index: 0;
            color: #eee;
        }

        .ranking-item.float {
            /* 悬浮元素不需要任何事件 只是方便用户查看当前操作的元素 */
            pointer-events: none;
            position: absolute;
            transform: translate(-50%, -50%);
            background: #fff;
            opacity: .7;
            z-index: 2;
        }

        .delete-area {
            position: absolute;
            right: 20px;
            top: 20vh;
            border: 1px dashed #f13;
            width: 100px;
            height: 100px;
            padding: 40px;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #f13;
        }

        .form-input {
            margin-bottom: 20px;
        }

        .form-input>input {
            width: 200px;
            padding: 0px 20px;
            height: 40px;
            outline: none;
            border: none;
            box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
        }
    </style>
</head>

<body>
    <h1>你心目中的美食排行榜</h1>
    <div class="form-input">
        <input type="text" placeholder="请输入您爱吃的美食">
    </div>
    <div class="ranking-list"></div>
    <div class="delete-area">拖至此处删除</div>


    <script>
        // 来源 https://baijiahao.baidu.com/s?id=1726366435512075604&wfr=spider&for=pc
        let rankingList = ['河南胡辣汤', '南京鸭血粉丝汤', '新疆大盘鸡', '西藏酥油茶', '西安肉夹馍', '兰州拉面', '广西螺蛳粉', '河北驴火烧', '延吉冷面']
        let moveItem = null
        let floatItem = null
        let rankingItemDoms = []

        ready();

        function ready() {
            let list = document.querySelector('.ranking-list')
            for (let i = 0; i < rankingList.length; i++) {
                let item = document.createElement('div')
                item.setAttribute('class', 'ranking-item')
                item.setAttribute('style', `transform:translate3d(0px,${i * 41}px,0px)`)
                item.textContent = rankingList[i]
                list.appendChild(item)
                rankingItemDoms.push(item)
            }
            let float = document.createElement('div')
            float.setAttribute('class', 'ranking-item float')
            float.hidden = true
            document.body.appendChild(float)
            floatItem = float;
            list.setAttribute('style', `height:${rankingList.length * 41}px`)
        }
        // 渲染
        function rendering() {
            // 获取最新的dom数据
            rankingItemDoms = document.querySelectorAll('.ranking-list > .ranking-item')
            for (let i = 0; i < rankingItemDoms.length; i++) {
                const rankingItemDom = rankingItemDoms[i];
                rankingItemDom.setAttribute('style', `transform:translate3d(0px,${i * 41}px,0px)`)
            }
        }

        // 更新数据
        function updateData() {
            // 获取最新的dom数据
            rankingItemDoms = document.querySelectorAll('.ranking-list > .ranking-item')
            let result = []
            for (let i = 0; i < rankingItemDoms.length; i++) {
                const rankingItemDom = rankingItemDoms[i];
                result.push(rankingItemDom.textContent)
            }
            rankingList = result;
        }



        // 给输入框增加变更事件
        document.querySelector('.form-input>input').addEventListener('change', (ev) => {
            let list = document.querySelector('.ranking-list')
            let item = document.createElement('div')
            item.setAttribute('class', 'ranking-item')
            item.setAttribute('style', `transform:translate3d(0px,${list.children.length * 41}px,0px)`)
            item.textContent = ev.target.value
            list.appendChild(item)
            ev.target.value = ''
            updateData()
        })

        document.addEventListener("mousedown", (ev) => {
            // 如果点击是条目元素
            if (ev.target.className.includes('ranking-item')) {
                moveItem = ev.target
                moveItem.setAttribute('class', 'ranking-item active')
                floatItem.setAttribute('data-index', moveItem.getAttribute('data-index'))
                floatItem.textContent = moveItem.textContent
                floatItem.setAttribute('style', `left:${ev.clientX}px;top:${ev.clientY}px;`)
                floatItem.hidden = false;
            }
        })
        document.addEventListener("mousemove", (ev) => {
            if (moveItem) {
                // 更新悬浮元素位置
                floatItem.setAttribute('style', `left:${ev.clientX}px;top:${ev.clientY}px;`)
                // 如果点击是条目元素
                if (ev.target.className.includes('ranking-item') && ev.target !== moveItem) {
                    if (ev.offsetY < 20) ev.target.before(moveItem)
                    else ev.target.after(moveItem)
                    rendering()
                    updateData()
                }
            }
        })
        document.addEventListener("mouseup", (ev) => {
            if (moveItem) {
                moveItem.setAttribute('class', 'ranking-item')
                // 当鼠标进入删除区域时
                if (ev.target.className.includes('delete-area')) {
                    moveItem.remove()
                    rendering()
                    updateData()
                }
                moveItem = null
                floatItem.hidden = true
            }
        })


    </script>
</body>

</html>

地址

https://github.com/linyisonger/H5.Examples

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/128617.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux的CPU使用率达到100%的快速定位方式

一.问题现象 Linux服务器&#xff08;操作系统版本是centos7.9&#xff09;上面部署了若干Java站点服务,突然收到运维的CPU异常g告警&#xff0c;到了影响业务的情况发生&#xff0c;经初步排查&#xff0c;未出现异常进程&#xff0c;排除挖矿病毒的原因。 二.排查思路 &am…

[Verilog]Verilog经典电路设计(一)

Verilog经典电路设计&#xff08;一&#xff09; 1.1 8位移位寄存器 module shifter (din , clk, clr, dout) ; input din, clk, clr; output [7:0] dout; reg [7:0] dout_data;always (posedge clk) begin if (!clr) dout_data < 8b0; //同步清 &#xff0c;高电平…

第二证券|美国巨头向欧盟宣战,暴跌25%,芯片大国告急

“暴利税”完全激怒美国动力巨子。 3万亿美国巨子直接将欧盟告上法庭&#xff0c;当地时间12月28日&#xff0c;埃克森美孚公司正式申述欧盟&#xff0c;要求其撤销对石油集团征收的一项新“暴利税”。该公司表明&#xff0c;欧盟方面征收“暴利税”的行为超出了法律权限。别的…

蓝牙学习八(配对与绑定)

1.简介 Paring&#xff08;配对&#xff09;和Bonding&#xff08;绑定&#xff09;是实现蓝牙射频通信安全的一种机制&#xff0c;有两点需要注意&#xff1a; Paring/bonding实现的是蓝牙链路层的安全&#xff0c;对应用层来说是完全透明的。也就是说&#xff0c;不管有没有…

GitHub入门指南(下)

三、新手必备的GitHub基本操作 1.配置SSH Key (1) 第一次使用时&#xff0c;要配置一下账户。 在 Git Bash 客户端&#xff0c;输入&#xff1a; git config --global user.name “这里输入你在GitHub的账户名” git config --global user.email “这里输入你在GitHub的注册邮…

基于51单片机的数字电压表(PCF8591)(Proteus仿真+程序)

编号&#xff1a;32 基于51单片机的数字电压表&#xff08;PCF8591&#xff09; 功能描述&#xff1a; 本设计由51单片机最小系统PCF8591模块四路模拟量输入模块一路DA输出液晶1602显示模块 1、主控制器是89C82单片机。 2、PCF8591模数转换器进行A/D转换&#xff0c;读取四路…

Java中常见的文件操作

作者&#xff1a;~小明学编程 文章专栏&#xff1a;JavaEE 格言&#xff1a;热爱编程的&#xff0c;终将被编程所厚爱。 目录 操作文件 File类 属性 构造方法 常见方法 重要方法的操作演示 文件内容的读写 FileInputStream OutputStream 按照字符读入 按照字符写入…

『分分钟玩转VueRouter●中』少开一把王者荣耀掌握VueRouter的基本使用

文章目录一、编程式路由导航二、缓存路由组件三、两个新的声明周期钩子四、路由守卫五、路由器的两种工作模式本篇博客会介绍Vue中的VueRouter的基本使用&#xff0c;编程式路由导航增加了我们进行路由跳转的灵活性&#xff0c;缓存路由组件保障了我们使用路由时的便捷性&#…

【高阶数据结构】搜索二叉树 经典习题讲解

&#x1f308;欢迎来到数据结构专栏~~搜索二叉树 (꒪ꇴ꒪(꒪ꇴ꒪ )&#x1f423;,我是Scort目前状态&#xff1a;大三非科班啃C中&#x1f30d;博客主页&#xff1a;张小姐的猫~江湖背景快上车&#x1f698;&#xff0c;握好方向盘跟我有一起打天下嘞&#xff01;送给自己的一句…

【OpenFOAM】-olaFlow-算例6- waveFloatingObject

算例路径&#xff1a; olaFlow\tutorials\waveFloatingObject 算例描述&#xff1a; 波浪作用下的浮体的刚体运动&#xff0c;属于流固耦合&#xff08;FSI&#xff09;问题 学习目标&#xff1a; 动网格设置和使用&#xff0c;网格变形控制&#xff0c;浮体的物理参数设置&…

23种设计模式(二)——享元模式【对象性能】

文章目录意图什么时候使用享元享元模式的实现内部状态和外部状态享元模式的优缺点与其他模式的关系亦称&#xff1a; 缓存、Cache、Flyweight 意图 享元模式是一种结构型设计模式&#xff0c; 它摒弃了在每个对象中保存所有数据的方式&#xff0c; 通过共享多个对象所共有的相…

数图互通房产管理系统架构分析

数图互通高校房产管理系统V5.0 使用JAVA、Canvas、H5等技术开发的图形数据交互技术架构平台&#xff1b;本系统满足XX大学房屋管理系统需求&#xff0c;高校房产综合管理信息系统平台V5.0遵循高校房产“分级授权、分类管理、网络化、图形化、精细化、流程化”的管理理念&#x…

关于新冠的几点总结

关于新冠的几点总结一、前言:二、病程阶段1. 第一阶段 反复发热2. 第二极端 退烧虚弱3. 第三阶段 咳嗽嗜睡三、处置措施:1. 思想准备2. 药/物准备3. 退烧方式4. 保持体温5. 通则不痛&#xff0c;痛则不通6. 营养补充7. 恢复关键期写在最后一、前言: 所写内容&#xff0c;为个人…

磊科路由器后门蜜罐捕获的事件分布情况

重点物联网 漏洞利用情况本节我们选取了两个漏洞进行分析。UPnP 相关的漏洞我们将在 4.4.3 进行分析&#xff0c;除去 UPnP 相关漏 洞外&#xff0c;被利用最多的是 Eir D1000 路由器的一个漏洞 [44]&#xff08;CVE-2016-10372&#xff09;&#xff0c;我们将对其进行分析。 …

Apollo浅解2

目录 用户、角色、权限 三者间的关系 权限Permission 新增一个应用时 新增一个命名空间时 角色Role 新增一个应用时 新增一个命名空间时 第三方应用 用户、角色、权限 三者间的关系 apollo也采用经典的三层权限设计&#xff0c;用户关联角色&#xff0c;角色关联权限…

DOM基础

一、DOM的概念 文档对象模型(DOM,Document Object Module)是W3C组织推荐的处理可扩展标志语言的标准编程接口&#xff0c;它允许程序和脚本动态的访问和更新文档的内容、结构和样式。 HTML的DOM操作是将文档里所有的内容(包括标签、标签里的内容、标签属性甚至注释等)都当做一…

51单片机入门 第一篇:LED灯

文章目录前言一、LED原理图二、创建keil5工程三、代码的编写四、程序的烧录总结前言 本篇文章讲正式带大家开始学习51单片机&#xff0c;希望这些文章能够很好的帮助到大家学习51单片机。 一、LED原理图 一般的51单片机上都带有8个LED灯&#xff0c;这里8个LED灯分别接到了板…

JS逆向——工信部ICP、IP、域名信息备案管理平台

问题&#xff1a;&#xff08;1&#xff09;数据列表接口token参数验证&#xff08;2&#xff09;authKey参数加密生成 1、页面中请求接口&#xff0c;观察请求头可发现&#xff0c;校验参数token为加密的字符串&#xff0c;根据该字符串并不能直观得到所用的加密方式是什么。 …

数据库大小写不敏感后,值也不敏感了

现象&#xff1a;我有一个账号admin&#xff0c;结果莫名多了一个ADMIN、Admin、AdMin等一些列账号&#xff1b;细品你的密码就算密文签名&#xff0c;是不是在你不知情的情况下也有很多。 原因&#xff1a;数据库安装的时候设置的大小写不敏感导致 解决&#xff1a;建议第三…

Spark 的学习笔记

Spark 的学习笔记 文章目录Spark 的学习笔记1. 概述Spark 优势及特点优秀的数据模型和丰富计算抽象Spark 生态圈Spark 特点Spark 与 HadoopSpark与MRSpark Streaming与StormSpark SQL与HiveSpark 运行模式2. 快速入门使用 Spark Shell 进行交互式分析基础Dataset 上的更多操作缓…