您的位置:首页 > Web前端 > JavaScript

JS实现图片拖拽交换效果

2017-03-03 16:00 786 查看

JS实现图片拖拽交换效果

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

实现要点

鼠标点击
onmousedown
:获取鼠标在页面上可视区域的位置(
clientX
,
clientY
)和元素外边框距已定位父元素容器的位置(
offsetLeft
,
offsetTop
);

鼠标移动
onmousemove
: 获取鼠标在页面上可视区域的位置(
clientX
,
clientY
),并实时改变目标元素位置;进行碰撞检测,同时计算被碰撞元素与目标元素中心点距离,将距离最小的定位交换元素;

鼠标释放
onmouseup
: 进行元素交换

注意点

排除没有碰撞成功的情况,进行特殊讨论;

覆盖html5原有的图片拖拽功能,通过
return false
返回;

交换时同时勿忘记交换图片的索引;

小技巧

进行碰撞检测时,可以进行逆向思维,检测未碰撞的情况,即判断目标元素是否超过碰撞元素的边界(如:目标元素的右侧是否超过被碰撞元素的左侧)

计算元素中心位置时,可以改为计算元素左上角之间的距离,从而转变为计算(offsetLeft1,offsetTop1)与(offsetLefti, 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];
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript web前端