实现这个案例,需要考虑到鼠标的拖拽效果(onmousedown/onmousemove/mouseup)

拖拽分解:

  按下鼠标---->移动鼠标----->松开鼠标

1.给目标元素添加onmousedown事件,拖拽的前提是在目标元素按下鼠标左键

2.当onmousedown事件发生后,此刻给document添加onmousemove事件,意味着此刻鼠标在网页的移动都将改变元素的位置

3.在onmousemove事件中,设定目标元素的left和top

  公式:

    目标元素的left = 鼠标的clienX - (鼠标和元素的横坐标差,即offsetX)

    目标元素的top = 鼠标的clientY -(鼠标和元素的纵坐标差,即offsetY)

4.当onmousedown发生以后,此刻给document添加onmouseup事件,意味着此刻鼠标在网页的任意位置松开鼠标,都会放弃拖拽效果,在onmouseup事件中,取消document的onmousemove事件即可

当然这个小案例也用到了关于DOM元素系列的操作,对于新手而言,算一个很好的综合训练

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>九宫格</title>
<style>
#box {
height: 300px;
width: 300px;
position: relative;
background-color: brown;
margin: 10px auto;
} span {
width: 100px;
height: 100px;
position: absolute;
font-size: 50px;
text-align: center;
line-height: 100px;
color: #FFF;
user-select: none;
cursor: pointer;
font-weight: bolder;
} #one {
top: 0;
left: 0;
background: url(./5.jpg);
background-size: 100% 100%;
} #two {
top: 0;
left: 100px;
background: url(./7.jpg);
background-size: 100% 100%;
} #three {
top: 0;
left: 200px;
background: url(./9.jpg);
background-size: 100% 100%;
} #four {
top: 100px;
left: 0;
background: url(./1.jpg);
background-size: 100% 100%;
} #five {
top: 100px;
left: 100px;
background: url(./2.jpg);
background-size: 100% 100%;
} #six {
top: 100px;
left: 200px;
background: url(./4.jpg);
background-size: 100% 100%;
} #seven {
top: 200px;
left: 0;
background: url(./3.jpg);
background-size: 100% 100%;
} #eight {
top: 200px;
left: 100px;
background: url(./6.jpg);
background-size: 100% 100%;
} #nine {
top: 200px;
left: 200px;
background: url(./8.jpg);
background-size: 100% 100%;
} #box .cBox {
position: absolute;
}
</style>
</head> <body>
<div id="box">
<span id="one"></span>
<span id="two"></span>
<span id="three"></span>
<span id="four"></span>
<span id="five"></span>
<span id="six"></span>
<span id="seven"></span>
<span id="eight"></span>
<span id="nine"></span>
</div>
</body>
<script>
var oBox = document.getElementById("box")
var box = document.querySelectorAll("span"); function Box(boxName) {
boxName.onmousedown = function (eve) {
var e = eve || window.event;
var cSpan = document.createElement("span");
cSpan.style.background = getComputedStyle(boxName).background;
cSpan.style.top = boxName.offsetTop + "px";
cSpan.style.left = boxName.offsetLeft + "px";
cSpan.className = "cBox"
oBox.appendChild(cSpan)
var offsetX = e.pageX - cSpan.offsetLeft;
var offsetY = e.pageY - cSpan.offsetTop;
document.onmousemove = function (eve) {
var e = eve || window.event;
cSpan.style.left = e.pageX - offsetX + "px";
cSpan.style.top = e.pageY - offsetY + "px";
}
document.onmouseup = function () {
document.onmousemove = null;
var spans = oBox.getElementsByTagName("span")
var minSpan = null;
var min = 1000;
for (var i = 0; i < spans.length - 1; i++) {
var span = spans[i];
var dis = distance(cSpan, span);
if (dis <= min) {
min = dis;
minSpan = span;
}
}
var lsColor = getComputedStyle(minSpan).background;
minSpan.style.background = getComputedStyle(boxName).background;
boxName.style.background = lsColor;
oBox.removeChild(cSpan);
document.onmouseup = null;
}
return false;
}
} function distance(span1, span2) {
var a = span1.offsetLeft - span2.offsetLeft;
var b = span1.offsetTop - span2.offsetTop;
var c = Math.sqrt(a * a + b * b);
return c;
}
for (var i = 0; i < box.length; i++) {
Box(box[i]);
}
</script>
</html>

ps:案例中的图片没有办法上传,想要的同学可以自行百度

完整效果:

  

原生JS实现九宫格拼图的更多相关文章

  1. js版九宫格拼图与启发式搜索(A*算法)

    九宫格拼图游戏大家都很熟悉,这里给大家如介绍何应用状态空间搜索的方式求解拼图的最佳路径和一个游戏dome及自动求解方法: 本文分web版游戏的实现和启发式搜索算法两部分: 先看dome,直接鼠标点击要 ...

  2. 原生js实现九宫格,全解析

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  3. 原生JS实现拼图游戏

    最近无聊,练练原生JS:实现拼图游戏.两种玩法:第一种是单击元素进行交换位置:第二种是拖拽元素进行位置交换.首先需要上传图片并进行回显(需要用到FileReader):下面是部分截图: 可以自行设置切 ...

  4. JS 九宫格算法 用原生js实现

    九宫格算法核心: 利用控件索引index计算出控件所在的行数和列数: 利用控件计算出left距离: 利用控件计算出top距离: 写特效时需要用到定位 公式: 行 row=parseInt(i/cols ...

  5. 原生JS封装Ajax插件(同域&&jsonp跨域)

    抛出一个问题,其实所谓的熟悉原生JS,怎样的程度才是熟悉呢? 最近都在做原生JS熟悉的练习... 用原生Js封装了一个Ajax插件,引入一般的项目,传传数据,感觉还是可行的...简单说说思路,如有不正 ...

  6. 常用原生JS方法总结(兼容性写法)

    经常会用到原生JS来写前端...但是原生JS的一些方法在适应各个浏览器的时候写法有的也不怎么一样的... 今天下班有点累... 就来总结一下简单的东西吧…… 备注:一下的方法都是包裹在一个EventU ...

  7. 原生JS实现"旋转木马"效果的图片轮播插件

    一.写在最前面 最近都忙一些杂七杂八的事情,复习软考.研读经典...好像都好久没写过博客了... 我自己写过三个图片轮播,一个是简单的原生JS实现的,没有什么动画效果的,一个是结合JQuery实现的, ...

  8. 再谈React.js实现原生js拖拽效果

    前几天写的那个拖拽,自己留下的疑问...这次在热心博友的提示下又修正了一些小小的bug,也加了拖拽的边缘检测部分...就再聊聊拖拽吧 一.不要直接操作dom元素 react中使用了虚拟dom的概念,目 ...

  9. React.js实现原生js拖拽效果及思考

    一.起因&思路 不知不觉,已经好几天没写博客了...近来除了研究React,还做了公司官网... 一直想写一个原生js拖拽效果,又加上近来学react学得比较嗨.所以就用react来实现这个拖 ...

随机推荐

  1. SpringMVC获取参数的几种方式

    前言: 年末了,忙了一年了却发现系统的整理的东西很少,一些基础的东西都未做整理,这里就将它随便整理一下,增加一些印象,当然在网上看到一些好的资料也会整理下来以备后用.今天整理一下springMVC获取 ...

  2. React项目使用React-Router

    ⒈初始化React项目(略) 请参考 初始化一个React项目(TypeScript环境) ⒉集成React-Router 在React世界里,公认最好用的路由是React-Router.那我们直接来 ...

  3. CentOS下使用yum安装Apache极为方便,只需要在终端键入以下命令即可

    CentOS下使用yum安装Apache极为方便,只需要在终端键入以下命令即可 1.安装Apache yum install httpd 2.设置服务器开机自动启动Apache systemctl e ...

  4. MappingJackson2JsonView——model转成json

    一.ajax请求,返回ModelAndView对象,结果报404: @RequestMapping(value = "/video") public ModelAndView jj ...

  5. go语言的3个包——strconv、os.Args、flag

    1. strconv包: 2. os.Args: 获取运行程序时给出的参数,可以通过os包来实现.看代码: package main import ( "fmt" "os ...

  6. CSS实现自适应分隔线的N种方法

    分割线是网页中比较常见的一类设计了,比如说知乎的更多回答 这里的自适应是指两边的横线会随着文字的个数和父级的宽度自适应 偷偷的看了一下知乎的实现,很显然是用一块白色背景覆盖的,加一点背景就露馅了 心想 ...

  7. Kubernetes(k8s) docker 修改 /dev/shm大小

    一.问题 /dev/shm在/etc/fstab中挂载,对应tmpfs,实际使用的是内存的空间.默认情况下,/dev/shm为物理内存大小的一半. 在Kubernetes上跑docker,发现/dev ...

  8. Golang安装和配置

    Golang安装和配置 Linux Golang 下载源码,解压. # /home/superpika为你的主目录 mkdir /home/superpika/go mkdir /home/super ...

  9. winform 替换word文档中的字段(包含图片添加),生成导出PDF文件(也可是word文件)

    1.先打开你需要替换的word文档,在想要后续更换字段值的地方添加“书签”. 2.将模板文档存放在 程序的Debug文件下. 3.生成文件的按钮点击事件 代码: string templatePath ...

  10. VBA for循环

    for循环是一种重复控制结构,它允许开发人员有效地编写需要执行特定次数的循环. 语法 以下是VBA中for循环的语法. For counter = start To end [Step stepcou ...