原生js实现九宫格,全解析
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>九宫格</title> <style type="text/css"> *{ margin: 0; padding: 0; } ul{ width: 320px; height: 320px; position: relative; left: 300px; top: 100px; border: 1px solid red; } li{ list-style: none; position: absolute; width: 100px; text-align: center; line-height: 100px; font-size: 18px; height: 100px; user-select: none; } </style> </head> <body> <ul> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> <script type="text/javascript"> var oUl=document.querySelector("ul");//获取第一个ul的dom var aLis=document.querySelectorAll("li");//获取所有的li var lt=mt=10;//margin左和margin右值 function RandColor(){ return Math.floor(Math.random()*256);//定义一个函数返回一个0-255之间的值 } for(var i=0;i<aLis.length;i++){ aLis[i].style.left=(i%3)*(100+lt)+"px";//通过取余运算对列排列 aLis[i].style.top=Math.floor(i/3)*(100+mt)+"px";//通过向下取整进行行排列 aLis[i].style.backgroundColor="rgb("+RandColor()+","+RandColor()+","+RandColor()+")";//背景色 aLis[i].innerText=i+1;//li内的内容填充 aLis[i].onmousedown=function(e){//添加事件 var evt=e||event; var dragNode=this;//把DOM对象(this)赋给dragNode,因为this指向问题,需要保存this var cloneNode=dragNode.cloneNode();//克隆一个元素留在原地 dragNode.style.zIndex=2;//拖拽时置于顶部 dragNode.style.border="2px solid black";//突出样式 oUl.replaceChild(cloneNode,dragNode);//把拖拽节点换成克隆节点 oUl.appendChild(dragNode);//把拖拽节点放到oUl尾部 var x=evt.offsetX;//鼠标在事件源的位置 var y=evt.offsetY;//鼠标在事件源的位置 document.onmousemove=function(e){ var evt=e||event; var _x=evt.clientX-x-oUl.offsetLeft;//求坐标 var _y=evt.clientY-y-oUl.offsetTop; _x=_x<0 ? 0 : _x>oUl.offsetWidth-100 ? oUl.offsetWidth-100 : _x; _y=_y<0 ? 0 : _y>oUl.offsetHeight-100 ? oUl.offsetHeight-100 : _y; dragNode.style.left=_x+"px"; dragNode.style.top=_y+"px"; } document.onmouseup=function(){ var arr=[];//定义空数组用来存放dragNode每一个兄弟元素的坐标 aLis=oUl.children; for(var i=0;i<aLis.length-1;i++){//开始存放 arr.push({left:aLis[i].offsetLeft,top:aLis[i].offsetTop}) } var _x=dragNode.offsetLeft; var _y=dragNode.offsetTop; var resurt=[];//定义一个空的结果数组 var num=Infinity;//定义一个值用来保存结果的最小值 arr.forEach(function(item){ resurt.push(Math.sqrt(Math.pow(Math.abs(_x-item.left),2)+Math.pow(Math.abs(_y-item.top),2))); if(num>Math.sqrt(Math.pow(Math.abs(_x-item.left),2)+Math.pow(Math.abs(_y-item.top),2))){ num=Math.sqrt(Math.pow(Math.abs(_x-item.left),2)+Math.pow(Math.abs(_y-item.top),2)); } }) num=resurt.indexOf(num);//把resurt数组中的最小值的索引赋给num //交换位置 dragNode.style.left=aLis[num].style.left; dragNode.style.top=aLis[num].style.top; aLis[num].style.left=cloneNode.style.left; aLis[num].style.top=cloneNode.style.top; //回置样式 dragNode.style.zIndex=1; dragNode.style.border="none"; oUl.removeChild(cloneNode); document.onmouseup=null; document.onmousemove=null; } } } </script> </body> </html>