JS實(shí)現(xiàn)圖片拖拽交換效果
JS實(shí)現(xiàn)圖片拖拽交換效果,供大家參考,具體內(nèi)容如下
聽(tīng) WEB前端javascript企業(yè)實(shí)戰(zhàn)班 公開(kāi)課,用JS實(shí)現(xiàn)了圖片拖拽交換的目的;感謝老師的講解。
實(shí)現(xiàn)要點(diǎn)
- 鼠標(biāo)點(diǎn)擊onmousedown:獲取鼠標(biāo)在頁(yè)面上可視區(qū)域的位置(clientX, clientY)和元素外邊框距已定位父元素容器的位置(offsetLeft,offsetTop);
- 鼠標(biāo)移動(dòng)onmousemove: 獲取鼠標(biāo)在頁(yè)面上可視區(qū)域的位置(clientX, clientY),并實(shí)時(shí)改變目標(biāo)元素位置;進(jìn)行碰撞檢測(cè),同時(shí)計(jì)算被碰撞元素與目標(biāo)元素中心點(diǎn)距離,將距離最小的定位交換元素;
- 鼠標(biāo)釋放onmouseup: 進(jìn)行元素交換
注意點(diǎn)
- 排除沒(méi)有碰撞成功的情況,進(jìn)行特殊討論;
- 覆蓋html5原有的圖片拖拽功能,通過(guò)return false返回;
- 交換時(shí)同時(shí)勿忘記交換圖片的索引;
小技巧
- 進(jìn)行碰撞檢測(cè)時(shí),可以進(jìn)行逆向思維,檢測(cè)未碰撞的情況,即判斷目標(biāo)元素是否超過(guò)碰撞元素的邊界(如:目標(biāo)元素的右側(cè)是否超過(guò)被碰撞元素的左側(cè))
- 計(jì)算元素中心位置時(shí),可以改為計(jì)算元素左上角之間的距離,從而轉(zhuǎn)變?yōu)橛?jì)算(offsetLeft1,offsetTop1)(offsetLeft1,offsetTop1)與(offsetLefti(offsetLefti, offsetTopi)offsetTopi)的距離,以簡(jiǎn)化計(jì)算;
實(shí)現(xiàn)
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];
}
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 原生JS實(shí)現(xiàn)拖拽圖片效果
- js實(shí)現(xiàn)使用鼠標(biāo)拖拽切換圖片的方法
- JS實(shí)現(xiàn)放大、縮小及拖拽圖片的方法【可兼容IE、火狐】
- JS HTML5拖拽上傳圖片預(yù)覽
- js實(shí)現(xiàn)圖片放大和拖拽特效代碼分享
- js實(shí)現(xiàn)拖拽上傳圖片功能
- javascript 網(wǎng)頁(yè)編輯框及拖拽圖片的問(wèn)題
- JavaScript實(shí)現(xiàn)文字與圖片拖拽效果的方法
- JS實(shí)現(xiàn)簡(jiǎn)易的圖片拖拽排序?qū)嵗a
- js css3實(shí)現(xiàn)圖片拖拽效果
相關(guān)文章
理解Javascript_02_理解undefined和null
其實(shí)在 ECMAScript 的原始類型中,是有Undefined 和 Null 類型的。 這兩種類型都分別對(duì)應(yīng)了屬于自己的唯一專用值,即undefined 和 null。2010-10-10
詳解JavaScript基于面向?qū)ο笾^承實(shí)例
這篇文章主要介紹了JavaScript基于面向?qū)ο笾^承實(shí)例,需要的朋友可以參考下2015-12-12
js將滾動(dòng)條滾動(dòng)到指定位置的簡(jiǎn)單實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇js將滾動(dòng)條滾動(dòng)到指定位置的簡(jiǎn)單實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的, 現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06
原生Javascript和jQuery做輪播圖簡(jiǎn)單例子
這篇文章主要為大家詳細(xì)介紹了原生Javascript和jQuery做輪播圖簡(jiǎn)單例子,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10
JS中生成隨機(jī)數(shù)的用法及相關(guān)函數(shù)
這篇文章主要為大家介紹了JS中生成隨機(jī)數(shù)的用法,為大家提供了相關(guān)函數(shù)的使用方法,感興趣的朋友可以參考一下2016-01-01
如何基于filter實(shí)現(xiàn)網(wǎng)站整體變灰功能
這篇文章主要介紹了如何基于filter實(shí)現(xiàn)網(wǎng)站整體變灰功能,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04

