拖拽交換

面試的時(shí)候碰到過這樣一個(gè)問題


需求

目錄結(jié)構(gòu)用以下的html文件

<ul id="content">
    <li class="list-item">1</li>
    <li id="add-li">+</li>
</ul>

首先是右鍵的自定義點(diǎn)擊事件,事件名為contextmenu,綁定到所需要?jiǎng)h除的元素塊里,取消默認(rèn)事件。

dom.oncontextmenu=function (e) {
 //e.button判斷鼠標(biāo)的按鍵
  if (e.button == 2){
    e.preventDefault();
   //這里是需要執(zhí)行的語句
  } 
}

然后模擬快捷菜單,思路就是在指針位置彈出一個(gè)列表,將對話框設(shè)為position:absolute,每次點(diǎn)擊的改變其定位,獲取指針的地方為(e.clientX,e.clientY)

添加元素和刪除元素調(diào)用removeChild()和insertBefore(),需注意的是新添加的元素也得綁定所有的事件。

另外一個(gè)難點(diǎn)就是拖拽事件的,鼠標(biāo)點(diǎn)擊事件有三個(gè)階段mousedown,mousemove,mouseup。mousedown的時(shí)候,獲取當(dāng)前位置,這里使用offsetLeft和offsetTop表示,然后在mousemove的時(shí)候監(jiān)聽鼠標(biāo)位置,然后設(shè)定top和left的值,這樣每個(gè)元素都要設(shè)置為絕對定位,所以初始化的時(shí)候要通過js來設(shè)定列表的位置。

   function init() {
        var lis = content.getElementsByTagName('li')
        for (let i = 0;i<lis.length;i++){
            lis[i].style.left = i%4*120+'px';
            lis[i].style.top = Math.floor(i/4)*120+'px';
        }
    }

當(dāng)然,鼠標(biāo)點(diǎn)擊的時(shí)候也需要判斷,不然會(huì)和之前綁定的contextmenu沖突,(左鍵的e.button=0),在mouseup的時(shí)候還要注意取消之前mousemove的事件,不然就會(huì)鼠標(biāo)松開后還一直移動(dòng)。

這里有個(gè)簡單的拖拽demo(這里沒有判斷e.button的值)

var startX, startY, moveX, moveY, x, y;
        box.onmousedown = function (e) {
            startX = e.clientX;
            startY = e.clientY;
            x = box.offsetLeft;
            y = box.offsetTop;
            //為了避免拖動(dòng)出box,事件綁定在document上
            document.onmousemove = function (e) {
                moveX = e.clientX - startX
                moveY = e.clientY - startY
                box.style.left = x + moveX + 'px';
                box.style.top = y + moveY + 'px';
            }
            document.onmouseup = function () {
                //移除后移除拖動(dòng)事件
                document.onmousemove = function () {
                    return false
                }
            }
        }

最后就是拖拽的交換判斷,這里我做的處理是被拖拽的元素的左上角拖拽到某元素的右下角時(shí),如果滿足,就交換元素里面的內(nèi)容,然后被拖動(dòng)的元素恢復(fù)到原始位置。


    function getSwap() {
        areaArr=[];
        for (var i = 0;i<listArr.length;i++){
            var left = listArr[i].offsetLeft;
            var top = listArr[i].offsetTop;
            areaArr.push({index:i,leftmin:left+50,topmin:top+50,leftmax:left+100,topmax:top+100})
        }
    }

    function swapNum(dom) {
        // 獲取元素節(jié)點(diǎn)的交換區(qū)域

        for(var i=0;i<areaArr.length;i++){
            if (domleft>=areaArr[i].leftmin&&domleft<=areaArr[i].leftmax&&domtop>=areaArr[i].topmin&&domtop<=areaArr[i].topmax) {
                console.log(areaArr[i].index)
                var target= listArr[i].innerText
                listArr[i].innerText = dom.innerText
                dom.innerText = target
            }
        }

    }

傳入dom進(jìn)行判斷,然后
完整demo放在了下面的頁面:https://github.com/SNJiang1992/somedemo/blob/master/dragswap.html

待優(yōu)化的部分:
1.綁定事件可以做一個(gè)封裝,后段創(chuàng)建了一個(gè)新的元素后,綁定事件又重復(fù)了一遍。
2.刪除元素時(shí)會(huì)有報(bào)錯(cuò)提示,但是具體原因不是很清楚。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • (續(xù)jQuery基礎(chǔ)(1)) 第5章 DOM節(jié)點(diǎn)的復(fù)制與替換 (1)DOM拷貝clone() 克隆節(jié)點(diǎn)是DOM的常...
    凜0_0閱讀 1,518評論 0 8
  • ??JavaScript 與 HTML 之間的交互是通過事件實(shí)現(xiàn)的。 ??事件,就是文檔或?yàn)g覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,701評論 1 11
  • 總結(jié): 鼠標(biāo)事件 1.click與dbclick事件$ele.click()$ele.click(handler(...
    阿r阿r閱讀 1,721評論 2 10
  • <!DOCTYPE html> 導(dǎo)航欄拖拽 ul{list-style: none;width: 1200...
    小飛俠zzr閱讀 494評論 0 0
  • 第1章 鼠標(biāo)事件 1-1 jQuery鼠標(biāo)事件之click與dbclick事件 用交互操作中,最簡單直接的操作就是...
    mo默22閱讀 1,346評論 0 6

友情鏈接更多精彩內(nèi)容