一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術(shù)及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務器之家 - 編程語言 - JavaScript - js教程 - 原生js實現(xiàn)九宮格拖拽換位

原生js實現(xiàn)九宮格拖拽換位

2022-01-07 17:17_小木不是木_ js教程

這篇文章主要為大家詳細介紹了原生js實現(xiàn)九宮格拖拽換位,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

使用原生JS寫出一個九宮格,實現(xiàn)九個格子何以拖拽換位的效果,供大家參考,具體內(nèi)容如下

效果演示

原生js實現(xiàn)九宮格拖拽換位

具體思路分析和代碼:

圖解1:

原生js實現(xiàn)九宮格拖拽換位

代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Document</title>
 <!--
  思路梳理:
   1,樣式設(shè)置:在樣式里最好使用定位來布局,不然以后拖拽代碼會麻煩點兒。
    (這里沒有設(shè)置父容器的具體位置,如果設(shè)置了父容器的具體位置,則在移動
    時top和left的值需要根據(jù)情況計算位置)
   2,父容器盒子里的內(nèi)容最好使用js代碼來生成,方便使用和添加樣式
    2-1:(循環(huán)生成子元素)
     我們子元素使用的定位布局,不難發(fā)現(xiàn):每行的top值一樣,每列的left值一樣,因此循環(huán)生
     成子元素我們可以使用3*3的循環(huán)嵌套來寫,這樣就可以講每行的樣式設(shè)置了。
    2-2:(給循環(huán)生成的標簽添加隨機顏色和文字)
     隨機顏色我是用的時rgb()來實現(xiàn)的,文字可以使用ASCII碼來生成,也可以使用字符串拼接
     來生成,我這里使用ASCII碼生成。
    PS:這樣我們的基本樣式就設(shè)置完畢了,接下來就是設(shè)置拖拽的事件
   3,給每一個元素添加事件,這里我們需要三個事件: onmousedown - onmousemove - onmouseup
    3-1:(首先是按下事件 onmousedown)
     當我們在對應子元素按下時,我們要獲取鼠標到按下目標邊框線內(nèi)的距離,并且克隆這個元素,
     將這個元素扔到父容器里面充當占位,(這里注意,克隆的這個節(jié)點在HTML結(jié)構(gòu)里是放到最后
     的,如果不處理后面會出BUG!!!)。
    3-2:(然后處理移動事件 onmousemove)
     在按下子元素塊兒并且移動時,我們要給目標設(shè)置他的top和left值,來實現(xiàn)跟隨移動,所以
     我們需要獲取鼠標到可視窗口的距離,目標的top和left值 = 鼠標到可視窗口的距離 - 鼠標
     到目標邊緣的距離(這里無邊框,如果有需要額外減去邊框?qū)挾龋?/code>
     PS:
      這里存在一個BUG!!!!在拖拽時,存在一個默認事件--選中文字,當你松開之后,目
      標還會跟著走,就算你關(guān)閉了onmousemove這個事件。所以這里需要阻止一下默認事件。
    3-3:(最后處理抬起事件 onmouseup)這里也是最重要的一步!!!!
     核心思想:
       當鼠標抬起時,我們要計算當前移動目標的中心點和每一個子元素中心點的距離,
       哪一個離得最近,和哪個交換位置(注意,這里存在一個BUG,這里的BUG就是
        3-1 里提到的BUG,需要提前處理)。
     具體過程:
      3-3-1:
       首先我們要進行循環(huán),計算拖拽目標的中心點與每一個子元素的中心點的距離,具體
       參照 圖解1 。 (拖拽目標距離可視窗口的左邊距 - 子元素距離可視窗口的左邊
       距)平方 + (拖拽目標距離可視窗口的上邊距 - 子元素距離可視窗口的上邊距)
       平方。最后在開方,得到中心點的距離(注意3-1的BUG要處理掉,把,要把移動的
       標簽放到結(jié)構(gòu)的最后,然后循環(huán)的時候?qū)⑺懦簦蝗幻看尉嚯x最近的都是它本身)。
      3-3-2:
       我們循環(huán)會得到我們想要的每一個距離,然后將這些距離放到一個數(shù)組里,并且再定
       義一個數(shù)組備份一下,方便對照具體是哪個標簽。
       將其中一個數(shù)組進行排序,然后再備份數(shù)組中查一下最小的值在備份數(shù)組中的索引下
       標,這個索引下標也就是對應的子元素了。
      3-3-3:
       然后將距離最近的子元素的 left和top值給 目標元素
       然后將克隆的標簽的 left和top值給 距離最近的子元素
       最后在將克隆的標簽移除掉
 
       這里還是會有一個BUG!!!如果不在標簽上按 直接抬起鼠標的話,會報錯,這是因
       為直接執(zhí)行了onmouseup事件,所以需要移除掉onmouseup事件
  -->
  <style>
  *{margin: 0;padding: 0;}
  .father{position: relative;}
  .father div{position: absolute;width: 100px;height: 100px;border-radius: 10px;text-align: center;line-height: 100px;font-size: 30px;cursor: pointer;}
  </style>
</head>
<body>
 <div class="father"></div>
 <script>
  // 3*3 循環(huán)生成子元素div,并給他們設(shè)置定位值
  // 設(shè)定固定的margin值
  var mT = 15;
  var mL = 15;
  var asc = 65;//ASCII碼值
  var oFather = document.querySelector('.father');
  for(var i = 0; i < 3; i++){
   for(var j = 0; j < 3; j++){
    var oDiv = document.createElement('div');//創(chuàng)建子元素
    oFather.appendChild(oDiv);
    oDiv.style.left = j * (oDiv.offsetWidth + mL) +'px';
    oDiv.style.top = i * (oDiv.offsetHeight + mT) +'px';
    // 隨機顏色設(shè)置
    oDiv.style.background = 'rgb('+parseInt(Math.random()*256) + "," +parseInt(Math.random()*256) + ","+parseInt(Math.random()*256)+')';
    // 加上字母
    oDiv.innerText = String.fromCharCode(asc++);
   }
  }
  // 為了方便理解,將事件寫到了外面,這里可以生成標簽循環(huán)內(nèi)部
  /* var oItem = document.querySelectorAll('.father>div');
  這種方式獲取的是靜態(tài)集合,只會獲取到初次頁面加載的內(nèi)容,用這種辦法獲取子元素會出BUG */
  var oItem = oFather.children;
  for(var k = 0 ;k<oItem.length; k++){
   oItem[k].onmousedown = function(e){
    var evt = e || event;
    // 獲取鼠標到目標邊框內(nèi)的距離
    var x = e.offsetX;
    var y = e.offsetY;
    var tagNode = this;
    // 克隆目標標簽
    var cloneNode = tagNode.cloneNode();
    cloneNode.style.border = '1px dashed #fff';
    oFather.appendChild(cloneNode);
    tagNode.style.zIndex = 1;
    // 在思路里提到過,這里存在一個BUG需要將克隆的和被拖拽換位置
    oFather.replaceChild(cloneNode, tagNode);
    oFather.appendChild(tagNode);
    document.onmousemove = function(e){
     var evt = e || event ;
     var l = evt.clientX - x;
     var t = evt.clientY - y;
     tagNode.style.left = l + 'px';
     tagNode.style.top = t + 'px';
     // 阻止默認事件,防止bug
     return false;
    }
    document.onmouseup = function(){
     // 抬起鼠標后,要判斷離那個最近,然后交換
     
     var oldArr = [];
     var newArr = [];
     for(var l = 0; l<oItem.length - 1;l++){
      var disX = tagNode.offsetLeft - oItem[l].offsetLeft;
      var disY = tagNode.offsetTop - oItem[l].offsetTop;
      // 勾股定理
      var dis = Math.sqrt( Math.pow(disX,2) + Math.pow(disY,2) );
      oldArr.push(dis);
      newArr.push(dis);
     }
     // 將oldArr從小到大排序
     oldArr.sort(function(a,b){return a-b});
     var minIndex = newArr.indexOf(oldArr[0]);
 
     console.log('oldArr' , oldArr, 'newArr' ,newArr);
 
     // 將距離最近的元素的定位給移動的目標
     tagNode.style.top = oItem[minIndex].style.top;
     tagNode.style.left = oItem[minIndex].style.left;
     // 把克隆的定位給距離最近的
     oItem[minIndex].style.top = cloneNode.style.top;
     oItem[minIndex].style.left = cloneNode.style.left;
 
     //把克隆節(jié)點移除
     oFather.removeChild(cloneNode);
 
     document.onmousemove = null;
     document.onmouseup = null;
    }
    return false;
   }
  }
 </script>
</body>
</html>

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/m0_46387873/article/details/106955195

延伸 · 閱讀

精彩推薦
  • js教程Selenium執(zhí)行JavaScript腳本的方法示例

    Selenium執(zhí)行JavaScript腳本的方法示例

    這篇文章主要介紹了Selenium執(zhí)行JavaScript腳本的方法示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友...

    測試開發(fā)小記6302021-12-23
  • js教程全面解析js中的原型,原型對象,原型鏈

    全面解析js中的原型,原型對象,原型鏈

    這篇文章主要介紹了圖解js中的原型,原型對象,原型鏈,幫助大家更好的理解和使用JavaScript,感興趣的朋友可以了解下...

    菜小牛4932022-01-07
  • js教程在JavaScript中查找字符串中最長單詞的三種方法(推薦)

    在JavaScript中查找字符串中最長單詞的三種方法(推薦)

    這篇文章主要介紹了在JavaScript中查找字符串中最長單詞的三種方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋...

    Hunter網(wǎng)絡安全7292022-01-04
  • js教程js刪除對象中的某一個字段的方法實現(xiàn)

    js刪除對象中的某一個字段的方法實現(xiàn)

    這篇文章主要介紹了js刪除對象中的某一個字段的方法實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的...

    兔子零847332021-12-29
  • js教程如何使用原生Js實現(xiàn)隨機點名詳解

    如何使用原生Js實現(xiàn)隨機點名詳解

    這篇文章主要給大家介紹了關(guān)于如何使用原生Js實現(xiàn)隨機點名的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習...

    CV_Di8112021-12-27
  • js教程JavaScript canvas實現(xiàn)文字時鐘

    JavaScript canvas實現(xiàn)文字時鐘

    這篇文章主要為大家詳細介紹了JavaScript canvas實現(xiàn)文字時鐘,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    _Adoph6142021-12-29
  • js教程原生JS實現(xiàn)pc端輪播圖效果

    原生JS實現(xiàn)pc端輪播圖效果

    這篇文章主要為大家詳細介紹了原生JS實現(xiàn)pc端輪播圖效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    qq_1519846510092021-12-15
  • js教程一文搞懂JavaScript中的Typeof用法

    一文搞懂JavaScript中的Typeof用法

    typeof 運算符是 JavaScript 的基礎(chǔ)知識點,盡管它存在一定的局限性(見下文),但在前端js的實際編碼過程中,仍然是使用比較多的類型判斷方式。...

    鋒享前端8162021-12-29
主站蜘蛛池模板: 美女在线看永久免费网址 | 国产成人精品一区二区 | 视频久久精品 | 好看的亚洲视频 | 亚洲国产精品线在线观看 | 香蕉97超级碰碰碰免费公 | 5x社区在线观看直接进入 | 国产精品男人的天堂 | 农村妇女野外牲交一级毛片 | 逼水真多 | 成人在线视频国产 | 国产精品久久久久久久久齐齐 | 国内自拍2019 | 美女张开腿让男人桶的 视频 | 日本一区二区精品88 | 日本黄色高清视频网站 | 美女撒尿部位无遮挡 | 精品视频在线免费看 | 成人动漫影院 | 黑人草 | 国产极品精频在线观看 | 美女机机对机机的视频(免费) | 四虎影院在线免费播放 | 亚洲国产午夜 | 91赵邦贺 | 99久久99久久久精品齐齐鬼色 | 女人特黄大aaaaaa大片 | 亚洲国产精品久久网午夜小说 | 17个农民工婉莹第一部 | 日韩大片免费看 | 色综合网天天综合色中文男男 | 欧美激烈精交gif动态图18p | 色色色色网站 | 男人与雌性宠物交啪啪小说 | 91香蕉在线| 偷拍综合网 | 久九九精品免费视频 | 国产成人a v在线影院 | 丰满大乳欲妇三级k8 | 亚洲国产精品久久久久 | 免费人成在线观看视频播放 |