首页 > 开发 > JS > 正文

JS实现图片拖拽交换效果

2024-05-06 16:46:59
字体:
来源:转载
供稿:网友

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=""      <li><img src=""      <li><img src=""      <li><img src=""      <li><img src=""      <li><img src=""      <li><img src=""      <li><img src=""      <li><img src=""    </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];  }}

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


注:相关教程知识阅读请移步到JavaScript/Ajax教程频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表