这几天在做一个拖拽元素的附加功能,就是对齐到网格,实际上就是确定好元素的初始位置,然后拖拽元素时,每次移动固定的距离。让元素都可以在网格内对齐。先上效果图,然后在详细说明一下细节问题

做了一个gif图,可以看到,每次元素的移动都是按照最小单位距离移动的。且每次元素都是对齐到网格的。

先根据demo说明一下思路和细节,后面会给出demo代码。

1. 确定元素的每次移动的最小单位(demo中为10px和10px),也就是每次水平或垂直的位移量都是10px。铺上一层网格背景是为了帮助我们更好的看到效果(demo中的每个网格也是10px * 10px)。

2. 为了可以更加明显的看到效果,初始化了元素的宽高(均为10px的倍数)和默认位置(同样为10px的倍数)。举例说明:元素宽高 50px * 50px,元素的初始位置为0xp * 0px。这样做的好处是一开始加载时就可以保证元素覆盖整数个的小网格(也就是 5 * 5 个小网格),不会出现覆盖不完整的网格。这一条其实为了让用户或者有强迫症的人不用这么纠结,实际上只是一个美化规置位置的操作。懂的朋友可以不用这么刻意,明白就好。

3. 最重要就是要如何确定什么时候移动固定的距离。这个demo效果要明白一件事:鼠标移动和元素移动是对应的,但不是实时对等的(当然,如果不考虑最小单位,只是纯拖拽元素,然后将元素的位置设置为鼠标的位置,这时可以理解为鼠标移动和元素移动是实时对等的)。回到demo说明,鼠标在网页上移动时,是一个像素一个像素移动的(可以通过console.log(e.pageX) 观察鼠标移动的位置 )。而元素是每10px移动一次。这一点就是我们要理解的关键,也是整个demo的关键。

了解了上面的思路,结合代码和注释,再说明一下:

<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
body{
margin:0px;
padding:0px;
}
div{
margin:0px;
padding:0px;
}
</style>
<script src="js/jquery-1.11.2.js"></script>
</head>
<body>
<div style="height: 600px;background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPiAgICA8ZGVmcz4gICAgICAgIDxwYXR0ZXJuIGlkPSJncmlkIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiPiAgICAgICAgICAgIDxwYXRoIGQ9Ik0gMTAgMCBMIDAgMCAwIDEwIiBmaWxsPSJub25lIiBzdHJva2U9IiNkZGRkZGQiIHN0cm9rZS13aWR0aD0iMSIgb3BhY2l0eT0iMSIgLz4gICAgICAgIDwvcGF0dGVybj4gICAgPC9kZWZzPiAgICA8cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyaWQpIiAvPjwvc3ZnPg==)">
<div id="bk" style="width:50px;height:50px;background: red;position: absolute"></div>
</div>
</body>
<script>
$(function(){
var orgX,orgY,eleX,eleY,hasMove=false;
$("#bk").on("mousedown",function(e){
orgX= e.pageX; //记录鼠标的水平位置
orgY= e.pageY; //记录鼠标的垂直位置
eleX=$(this).offset().left; //记录元素的水平位置
eleY=$(this).offset().top; //记录元素的垂直位置
hasMove=true; //鼠标按下时标明当前元素可以拖拽标识
});
$(document).on("mousemove",function(e){
if(hasMove){ //当元素可以拖拽时执行操作
//新位置计算方法为元素的上次位置加上新的位移量
var left=eleX+Math.round( ( e.pageX - orgX ) / 10 ) * 10;
var top= eleY+Math.round( ( e.pageY - orgY) / 10 ) * 10;
//更新位置信息
$("#bk").css({
top:top,
left:left
});
}
}).on("mouseup",function(e){
hasMove=false; //鼠标松开时设置元素不可拖拽
});
})
</script>
</html>

上面的代码给出的较详细的注释,其中,最为关键的代码就是

Math.round( ( e.pageX - orgX ) / 10 ) * 10;

该代码是计算元素新的位移量,用鼠标的最新位置减去在元素按下时的鼠标位置,除以最小单位10,进行四舍五入后获得整数值,然后在乘以最小单位10。就可以获得元素应该需要移动的单位距离了。这条如果不明白可以运行代码自己思考体会一下。(当然使用Mach的ceil和floor方法也可以)。

okay,以上就是javascript实现拖拽元素对齐到网格的实现方法。实质上是在初始化好元素的位置后(按照最小单位倍数初始化),每次移动固定距离(最小单位距离)即可。

感谢阅读。

转载请说明出处~~~3Q

JavaScript实现拖拽元素对齐到网格(每次移动固定距离)的更多相关文章

  1. juqery 拖拽元素

    转自  http://www.cnblogs.com/holbrook/archive/2012/03/13/2394111.html 因为怕博主删除博客,所以复制过来! JQuery UI是JQue ...

  2. Javascript自由拖拽类

    基本拖拽配置 new Dragdrop({target 拖拽元素 HTMLElemnt 必选bridge 指定鼠标按下哪个元素时开始拖拽,实现模态对话框时用到 dragable 是否可拖拽 (true ...

  3. javascript鼠标拖拽的那些事情

    <html> <head> <title>javascript鼠标拖拽的那些事情</title> <meta http-equiv="C ...

  4. 关于js拖拽功能,拖拽元素的position:fixed;left:0;right:0;样式引起左右拖动元素会出现落后鼠标移动距离的问题

    被拖拽元素的样式如果为:position:fixed;left:0;right:0;(当时是为了让fixed定位的元素水平居中加的left:0;right:0;避免js动态计算定位的麻烦)时左右拖动会 ...

  5. H5 拖拽元素

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. vue-drag-resize 可拖拽可缩放的标签,如何管理多个拖拽元素之间的zIndex?操作上需要保持当前激活的组件是最上层,但是在总体上,又要确保其图层管理的顺序。

    麻烦总是不断出现,还好办法总比困难多, 1.公司开发一款可视化编辑html网页的多媒体编辑平台,牵扯到标签元素的拖拽,缩放,我找了找方法发现原生技术实现起来代码太多,麻烦,还好找到了一个vue组件,可 ...

  7. JavaScript动画-拖拽改变元素大小

    ▓▓▓▓▓▓ 大致介绍 拖拽改变元素大小是在模拟拖拽上增加了一些功能 效果:拖拽改变元素大小 ▓▓▓▓▓▓ 拖拽改变元素大小原理 首先这个方块得知道我们想要改变这个它的大小,所以我给它设定一个范围,当 ...

  8. js 鼠标拖拽元素

    基础知识 event.clientX.event.clientY 鼠标相对于浏览器窗口可视区域的X,Y坐标(窗口坐标),可视区域不包括工具栏和滚动条.IE事件和标准事件都定义了这2个属性 event. ...

  9. JavaScript鼠标拖拽特效及相关问题总结

    #div1{width:200px;height:200px;background:red;position:absolute;} #div2{width:200px;height:200px;bac ...

随机推荐

  1. Sql Server系列:聚合函数

    1 SUM SUM是一个求和函数,返回指定列值的总和.SUM 只能用于数字列. 其中忽略 Null 值. 语法 SUM ( [ ALL | DISTINCT ] expression ) OVER ( ...

  2. MVC4做网站后台:栏目管理2、修改栏目

    接上节添加栏目. 修改栏目与添加栏目非常相似,主要区别在于先向视图传递要修改栏目的model.另外在保存时比添加栏目验证要更多一些. 1.要验证父栏目不能是其本身: 2.父栏目不能是其子栏目: 3.父 ...

  3. 深入理解客户区尺寸client

    前面的话 关于元素尺寸,一般地,有偏移大小offset.客户区大小client和滚动大小scroll.前文已经介绍过偏移属性,后文将介绍scroll滚动大小,本文主要介绍客户区大小client 客户区 ...

  4. Hawk使用补充说明

    软件在发布后,收到了各方朋友的反馈和提问.此处统一对一部分问题作出回复. 感谢你使用Hawk,软件是我写的,坑是我挖的.做爬虫本来就比较复杂,一些公司有专门的程序员做爬虫工程师.因此如果你很沮丧,很有 ...

  5. JavaScript的Tab切换

    在网页设计中经常要用到tab切换,遂整理了一下常用的两种方法. 先看一下示例代码: HTML: <!doctype html> <html lang="en"&g ...

  6. DDD 领域驱动设计-谈谈 Repository、IUnitOfWork 和 IDbContext 的实践(1)

    好久没写 DDD 领域驱动设计相关的文章了,嘎嘎!!! 这几天在开发一个新的项目,虽然不是基于领域驱动设计的,但我想把 DDD 架构设计的一些东西运用在上面,但发现了很多问题,这些在之前的短消息项目中 ...

  7. 【记录】GitHub/TortoiseGit 修改邮箱/提交者

    我使用 Git 客户端工具是 TortoiseGit,在提交更新的时候,不知何时起会出现下面这种情况: 正常提交作者信息显示应该是: 本来也没怎么注意,但是在提交历史中,记录就不显示出来了,也就是在首 ...

  8. geotrellis使用(三)geotrellis数据处理过程分析

    之前简单介绍了geotrellis的工作过程以及一个简单的demo,最近在此demo的基础上实现了SRTM DEM数据的实时分析以及高程实时处理,下面我就以我实现的上述功能为例,简单介绍一下geotr ...

  9. C++ 制作 json 数据 并 传送给服务端(Server) 的 php

    json数据格式,这里举个基础的例子: {"name":"LGH"} 在C++里面,我用个函数把特定的数据组合成 json void toJson(int co ...

  10. 【十大经典数据挖掘算法】C4.5

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 1. 决策树模型与学习 决策树(de ...