热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

原生js写九宫格拖拽换位原创

原标题:原生js写九宫格拖拽换位原创使用原生JS写出一个九宫格,实现九个格子可以拖拽换位的效果

原标题:原生js写九宫格拖拽换位
原创


使用原生JS写出一个九宫格,实现九个格子可以拖拽换位的效果


效果演示

在这里插入图片描述


具体思路分析和代码:

图解1:
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="U文章来源站点https://www.yii666.com/TF-8">
<meta name="viewport" content=">
<title>Document</title>
<!--
思路梳理:
1,样式设置:在样式里最好使用定位来布局,不然以后拖拽代码会麻烦点儿。
(这里没有设置父容器的具体位置,如果设置了父容器的具体位置,则在移动
时top和left的值需要根据情况计算位置)
2,父容器盒子里的内容最好使用js代码来生成,方便使用和添加样式
2-1:(循环生成子元素)
我们子元素使用的定位布局,不难发现:每行的top值一样,每列的left值一样,因此循环生
成子元素我们可以使用3*3的循环嵌套来写,这样就可以讲文章来源地址37475.html每行的样式设置了。
2-2:(给循环生成的标签添加随机颜色和文字)
随机颜色我是用的时rgb()来实现的,文字可以使用ASCII码来生成,也可以使用字符串拼接
来生成,我这里使用ASCII码生成。
PS:这样我们的基本样式就设置完毕了,接下来就是设置拖拽的事件
3,给每一个元素添加事件,这里我们需要三个事件: onmousedown - onmousemove - onmouseup
3-1:(首先是按下事件 onmousedown)
当我们在对应子元素按下时,我们要获取鼠标到按下目标边框线内的距离,并且克隆这个元素,
将这个元素扔到父容器里面充当占位,(这里注意,克隆的这个节点在HTML结构里是放到最后
的,如果不处理后面会出BUG!!!)。
3-2:(然后处理移动事件 onmousemove)
在按下子元素块儿并且移动时,我们要给目标设置他的top和left值,来实现跟随移动,所以
我们需要获取鼠标到可视窗口的距离,目标的top和left值 = 鼠标到可视窗口的距离 - 鼠标
到目标边缘的距离(这里无边框,如果有需要额外减去边框宽度)。
PS
这里存在一个BUG!!!!在拖拽时,存在一个默认事件--选中文字,当你松开之后,目
标还会跟着走,就算你关闭了onmousemove这个事件。所以这里需要阻止一下默认事件。
3-3:(最后处理抬起事件 onmouseup)这里也是最重要的一步!!!!
核心思想:
当鼠标抬起时,我们要计算当前移动目标的中心点和每一个子元素中心点的距离,
哪一个离得最近,和哪个交换位置(注意,这里存在一个BUG,这里的BUG就是
3-1 里提到的BUG,需要提前处理)。
具体过程:
3-3-1
首先我们要进行循环,计算拖拽目标的中心点与每一个子元素的中心点的距离,具体
参照 图解1 。 (拖拽目标距离可视窗口的左边距 - 子元素距离可视窗口的左边
距)平方 + (拖拽目标距离可视窗口的上边距 - 子元素距离可视窗口的上边距)
平方。最后在开方,得到中心点的距离(注意3-1BUG要处理掉,把,要把移动的
标签放到结构的最后,然后循环的时候将他排除掉,不然每次距离最近的都是它本身)。
3-3-2
我们循环会得到我们想要的每一个距离,然后将这些距离放到一个数组里,并且再定
义一个数组备份一下,方便对照具体是哪个标签。
将其中一个数组进行排序,然后再备份数组中查一下最小的值在备份数组中的索引下
标,这个索引下标也就是对应的子元素了。
3-3-3
然后将距离最近的子元素的 left和top值给 目标元素
然后将克隆的标签的 left和top值给 距离最近的子元素
最后在将克隆的标签移除掉
www.yii666.com 这里还是会有一个BUG!!!如果不在标签上按 直接抬起鼠标的话,会报错,这是因
为直接执行了onmouseup事件,所以需要移除掉onmouseup事件
-->
<style>
*{margin: 0;padding: 0;}
.father{position: relative;}
.father div{position: absolute;width: 100px;height: 100px;border-radius: 10px;text-align: center;line-height: 100px;font-size: 30px;cursor: pointer;}
</style>
</head>
<body>
<div class="father"></div>
<script>
// 3*3 循环生成子元素div,并给他们设置定位值
// 设定固定的margin值
var mT = 15;
var mL = 15;
var asc = 65;//ASCII码值
var oFather = document.querySelector('.father');
for(var i = 0; i < 3; i++){
for(var j = 0; j < 3; j++){
var oDiv = document.createElement('div');//创建子元素
oFather.appendChild(oDiv);
oDiv.style.left = j * (oDiv.offsetWidth + mL) +'px';
oDiv.style.top = i * (oDiv.offsetHeight + mT) +'px';
// 随机颜色设置
oDiv.style.background = 'rgb('+parseInt(Math.random()*256) + "," +parseInt(Math.random()*256) + ","+parseInt(Math.random()*256)+')';
// 加上字母
oDiv.innerText = String.fromCharCode(asc++);
}
}
// 为了方便理解,将事件写到了外面,这里可以生成标签循环内部
/* var oItem = document.querySelectorAll('.father>div');
这种方式获取的是静态集合,只会获取到初次页面加载的内容,用这种办法获取子元素会出BUG */

var oItem = oFather.children;
for(var k = 0 ;k<oItem.length; k++){
oItem[k].onmousedown = function(e){
var evt = e || event;
// 获取鼠标到目标边框内的距离
var x = e.offsetX;
var y = e.offsetY;
var tagNode = this;
// 克隆目标标签
var cloneNode = tagNode.cloneNode();
cloneNode.style.border = '1px dashed #fff';
oFather.appendChild(cloneNode);
tagNode.style.zIndex = 1;
// 在思路里提到过,这里存在一个BUG需要将克隆的和被拖拽换位置
oFather.replaceChild(cloneNode, tagNode);
oFather.appendChild(tagNode);
document.onmousemove = function(e){
var evt = e || event ;
var l = evt.clientX - x;
var t = evt.clientY - y;
tagNode.style.left = l + 'px';
tagNode.style.top = t + 'px';
// 阻止默认事件,防止bug
return false;
}
document.onmouseup = function(){
// 抬起鼠标后,要判断离那个最近,然后交换
var oldArr = [];
var newArr = [];
for(var l = 0; l<oItem.length - 1;l++){
var disX = tagNode.offsetLeft - oItem[l].offsetLeft;
var disY = tagNode.offsetTop - oItem[l].offsetTop;
// 勾股定理
var dis = Math.sqrt( Math.pow(disX,2) + Math.pow(disY,2) );
oldArr.push(dis);
newArr.push(dis);
}
// 将oldArr从小到大排序
oldArr.sort(function(a,b){return a-b});
var minIndex = newArr.indexOf(oldArr[0]);
console.log('oldArr' , oldArr, 'newArr' ,newArr);
// 将距离最近的元素的定位给移动的目标
tagNode.style.top = oItem[minIndex]文章来源地址37475.html.style.top;
tagNode.style.left = oItem[minIndex].style.left;
// 把克隆的定位给距离最近的
oItem[minIndex].style.top = clonewww.yii666.comNode.style.top;
oItem[minIndex].style.left = cloneNode.style.left;
//把克隆节点移除
oFather.removeChild(cloneNode);
document.onmousemove = null;
document.onmouseup = null;
}
return false;
}
}
</script>
</body>
</html>

来源于:原生js写九宫格拖拽换位
原创


推荐阅读
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 本文介绍了Java的公式汇总及相关知识,包括定义变量的语法格式、类型转换公式、三元表达式、定义新的实例的格式、引用类型的方法以及数组静态初始化等内容。希望对读者有一定的参考价值。 ... [详细]
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
  • C++语言入门:数组的基本知识和应用领域
    本文介绍了C++语言的基本知识和应用领域,包括C++语言与Python语言的区别、C++语言的结构化特点、关键字和控制语句的使用、运算符的种类和表达式的灵活性、各种数据类型的运算以及指针概念的引入。同时,还探讨了C++语言在代码效率方面的优势和与汇编语言的比较。对于想要学习C++语言的初学者来说,本文提供了一个简洁而全面的入门指南。 ... [详细]
  • STL迭代器的种类及其功能介绍
    本文介绍了标准模板库(STL)定义的五种迭代器的种类和功能。通过图表展示了这几种迭代器之间的关系,并详细描述了各个迭代器的功能和使用方法。其中,输入迭代器用于从容器中读取元素,输出迭代器用于向容器中写入元素,正向迭代器是输入迭代器和输出迭代器的组合。本文的目的是帮助读者更好地理解STL迭代器的使用方法和特点。 ... [详细]
  • 本文介绍了Cocos2dx学习笔记中的更新函数scheduleUpdate、进度计时器CCProgressTo和滚动视图CCScrollView的用法。详细介绍了scheduleUpdate函数的作用和使用方法,以及schedule函数的区别。同时,还提供了相关的代码示例。 ... [详细]
  • Spring框架《一》简介
    Spring框架《一》1.Spring概述1.1简介1.2Spring模板二、IOC容器和Bean1.IOC和DI简介2.三种通过类型获取bean3.给bean的属性赋值3.1依赖 ... [详细]
  • yii2 绑定框架事件
    后端开发|php教程php,yii2后端开发-php教程我想要添加自定义代码处理yii2框架的Application::EVENT_BEFORE_REQUEST时触发的事件,但是不 ... [详细]
author-avatar
丽sd园印章
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有