JavaScript

超轻量级php框架startmvc

JS实现图片拖拽交换效果

更新时间:2020-08-07 03:36 作者:startmvc
JS实现图片拖拽交换效果,供大家参考,具体内容如下听WEB前端javascript企业实战班公开课,

JS实现图片拖拽交换效果,供大家参考,具体内容如下

听 WEB前端javascript企业实战班 公开课,用JS实现了图片拖拽交换的目的;感谢老师的讲解。

实现要点

  • 鼠标点击onmousedown:获取鼠标在页面上可视区域的位置(clientX, clientY)和元素外边框距已定位父元素容器的位置(offsetLeft,offsetTop);
  • 鼠标移动onmousemove: 获取鼠标在页面上可视区域的位置(clientX, clientY),并实时改变目标元素位置;进行碰撞检测,同时计算被碰撞元素与目标元素中心点距离,将距离最小的定位交换元素;
  • 鼠标释放onmouseup: 进行元素交换

注意点

  • 排除没有碰撞成功的情况,进行特殊讨论;
  • 覆盖html5原有的图片拖拽功能,通过return false返回;
  • 交换时同时勿忘记交换图片的索引;

小技巧

  • 进行碰撞检测时,可以进行逆向思维,检测未碰撞的情况,即判断目标元素是否超过碰撞元素的边界(如:目标元素的右侧是否超过被碰撞元素的左侧)
  • 计算元素中心位置时,可以改为计算元素左上角之间的距离,从而转变为计算(offsetLeft1,offsetTop1)(offsetLeft1,offsetTop1)与(offsetLefti(offsetLefti, offsetTopi)offsetTopi)的距离,以简化计算;

实现

HTML


<div id="photo">
 <ul>
 <li><img src="" alt=""></li>
 <li><img src="" alt=""></li>
 <li><img src="" alt=""></li>
 <li><img src="" alt=""></li>
 <li><img src="" alt=""></li>
 <li><img src="" alt=""></li>
 <li><img src="" alt=""></li>
 <li><img src="" alt=""></li>
 <li><img src="" alt=""></li>
 </ul>
</div>

CSS


* {
 margin:0;
 padding: 0;
 }
 body {
 user-select: none; /*阻止文本选中*/
 }
 #photo {
 width: 600px;
 height: 600px;
 border: 2px solid #000;
 margin: 20px auto;
 }
 #photo ul li {
 list-style:none;
 width: 180px;
 height: 180px;
 margin: 10px;
 float: left;
 }
 #photo ul li:hover {
 background: #c0c;
 }
 #photo ul li img {
 width: 180px;
 height: 180px;
 border: 1px solid #ccc;
 }

JS


var photo = document.getElementById("photo");
 var oUl = photo.getElementsByTagName("ul")[0];
 var aLi = oUl.getElementsByTagName("li");
 var z = 2;

 var arr = [];
 for (var i = 0; i < aLi.length; i++) {
 arr.push([aLi[i].offsetLeft, aLi[i].offsetTop]);
 }

 for (var i = 0; i < aLi.length; i++) {
 aLi[i].style.position = "absolute";
 aLi[i].style.left = arr[i][0] + "px";
 aLi[i].style.top = arr[i][1] + "px";
 aLi[i].style.margin = 0;
 }

 for (var i = 0; i < aLi.length; i++) {
 aLi[i].index = i;
 drag(aLi[i]);
 }

 function drag(obj) {
 obj.onmousedown = function(ev) {
 ev = ev || window.ev;
 var x = ev.clientX;
 var y = ev.clientY;

 var l = obj.offsetLeft;
 var t = obj.offsetTop;

 this.style.zIndex = z++;

 document.onmousemove = function(ev) {
 ev = ev || window.ev;
 var _left = ev.clientX - x + l;
 var _top = ev.clientY - y + t;
 obj.style.left = _left + "px";
 obj.style.top = _top + "px";

 var li = near(obj);
 for (var i = 0; i < aLi.length; i++) {
 aLi[i].style.background = "";
 }
 if (li) {
 li.style.background = "#DF971F";
 }
 }
 document.onmouseup = function() {
 document.onmousemove = null;
 document.onmousedown = null;

 var nearLi = near(obj);
 var tmp = 0;
 if (nearLi) {
 move(nearLi, {left:arr[obj.index][0], top:arr[obj.index][1]});
 move(obj, {left:arr[nearLi.index][0], top:arr[nearLi.index][1]});
 nearLi.style.background = "";

 tmp = obj.index;
 obj.index = nearLi.index;
 nearLi.index = tmp;
 } else {
 move(obj, {left:arr[obj.index][0], top:arr[obj.index][1]});
 }
 }
 return false;
 }
 } 
 function impact(obj1, obj2) {
 var L1 = obj1.offsetLeft;
 var R1 = obj1.offsetLeft + obj1.offsetWidth;
 var T1 = obj1.offsetTop;
 var B1 = obj1.offsetTop + obj1.offsetHeight;

 var L2 = obj2.offsetLeft;
 var R2 = obj2.offsetLeft + obj2.offsetWidth;
 var T2 = obj2.offsetTop;
 var B2 = obj2.offsetTop + obj2.offsetHeight;

 if (L2 > R1 || T2 > B1 || R2 < L1 || B2 < T1) {
 return false;
 } else {
 return true;
 }
 }
 function near(obj) {
 var tmp = 5000;
 var oLi = '';
 for (var i = 0; i < aLi.length; i++) {
 if (impact(obj, aLi[i]) && obj != aLi[i]) {
 var c = disCalc(obj, aLi[i]);

 if (tmp > c) {
 tmp = c;
 oLi = aLi[i];
 }
 }
 }
 return oLi;
 }
 function disCalc(obj1, obj2) {
 var x = obj1.offsetLeft - obj2.offsetLeft; 
 var y = obj1.offsetTop - obj2.offsetTop;
 return Math.sqrt(x * x + y * y);
 }

move.js


function move(obj, json, endFn) {
 clearInterval(obj.timer);
 obj.timer = setInterval(function() {
 var bBtn = true;
 for (var attr in json) {
 var iCur = 0;
 if (attr == 'opacity') {
 if (Math.round(parseFloat(getStyle(obj,attr)) * 100) == 0) {
 iCur = Math.round(parseFloat(getStyle(obj,attr)) * 100);
 } else {
 iCur = Math.round(parseFloat(getStyle(obj,attr)) * 100) || 100;
 } 
 } else {
 iCur = parseInt(getStyle(obj,attr)) || 0;
 }

 var iSpeed = (json[attr] - iCur) / 8;
 iSpeed = iSpeed >0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
 if (iCur != json[attr]) {
 bBtn = false;
 }

 if (attr == 'opacity') {
 obj.style.filter = 'alpha(opacity=' +(iCur + iSpeed)+ ')';
 obj.style.opacity = (iCur + iSpeed) / 100;
 }
 else {
 obj.style[attr] = iCur + iSpeed + 'px';
 }
 }

 if (bBtn) {
 clearInterval(obj.timer);
 if (endFn) {
 endFn.call(obj);
 }
 } 
 }, 30);
}


function getStyle(obj, attr) { 
 if (obj.currentStyle) {
 return obj.currentStyle[attr];
 } else {
 return getComputedStyle(obj, false)[attr];
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。