激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

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

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

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

原生js實現九宮格拖拽換位

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

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

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

效果演示

原生js實現九宮格拖拽換位

具體思路分析和代碼:

圖解1:

原生js實現九宮格拖拽換位

代碼:

?
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,樣式設置:在樣式里最好使用定位來布局,不然以后拖拽代碼會麻煩點兒。
    (這里沒有設置父容器的具體位置,如果設置了父容器的具體位置,則在移動
    時top和left的值需要根據情況計算位置)
   2,父容器盒子里的內容最好使用js代碼來生成,方便使用和添加樣式
    2-1:(循環生成子元素)
     我們子元素使用的定位布局,不難發現:每行的top值一樣,每列的left值一樣,因此循環生
     成子元素我們可以使用3*3的循環嵌套來寫,這樣就可以講每行的樣式設置了。
    2-2:(給循環生成的標簽添加隨機顏色和文字)
     隨機顏色我是用的時rgb()來實現的,文字可以使用ASCII碼來生成,也可以使用字符串拼接
     來生成,我這里使用ASCII碼生成。
    PS:這樣我們的基本樣式就設置完畢了,接下來就是設置拖拽的事件
   3,給每一個元素添加事件,這里我們需要三個事件: onmousedown - onmousemove - onmouseup
    3-1:(首先是按下事件 onmousedown)
     當我們在對應子元素按下時,我們要獲取鼠標到按下目標邊框線內的距離,并且克隆這個元素,
     將這個元素扔到父容器里面充當占位,(這里注意,克隆的這個節點在HTML結構里是放到最后
     的,如果不處理后面會出BUG!!!)。
    3-2:(然后處理移動事件 onmousemove)
     在按下子元素塊兒并且移動時,我們要給目標設置他的top和left值,來實現跟隨移動,所以
     我們需要獲取鼠標到可視窗口的距離,目標的top和left值 = 鼠標到可視窗口的距離 - 鼠標
     到目標邊緣的距離(這里無邊框,如果有需要額外減去邊框寬度)。
     PS:
      這里存在一個BUG!!!!在拖拽時,存在一個默認事件--選中文字,當你松開之后,目
      標還會跟著走,就算你關閉了onmousemove這個事件。所以這里需要阻止一下默認事件。
    3-3:(最后處理抬起事件 onmouseup)這里也是最重要的一步!!!!
     核心思想:
       當鼠標抬起時,我們要計算當前移動目標的中心點和每一個子元素中心點的距離,
       哪一個離得最近,和哪個交換位置(注意,這里存在一個BUG,這里的BUG就是
        3-1 里提到的BUG,需要提前處理)。
     具體過程:
      3-3-1:
       首先我們要進行循環,計算拖拽目標的中心點與每一個子元素的中心點的距離,具體
       參照 圖解1 。 (拖拽目標距離可視窗口的左邊距 - 子元素距離可視窗口的左邊
       距)平方 + (拖拽目標距離可視窗口的上邊距 - 子元素距離可視窗口的上邊距)
       平方。最后在開方,得到中心點的距離(注意3-1的BUG要處理掉,把,要把移動的
       標簽放到結構的最后,然后循環的時候將他排除掉,不然每次距離最近的都是它本身)。
      3-3-2:
       我們循環會得到我們想要的每一個距離,然后將這些距離放到一個數組里,并且再定
       義一個數組備份一下,方便對照具體是哪個標簽。
       將其中一個數組進行排序,然后再備份數組中查一下最小的值在備份數組中的索引下
       標,這個索引下標也就是對應的子元素了。
      3-3-3:
       然后將距離最近的子元素的 left和top值給 目標元素
       然后將克隆的標簽的 left和top值給 距離最近的子元素
       最后在將克隆的標簽移除掉
 
       這里還是會有一個BUG!!!如果不在標簽上按 直接抬起鼠標的話,會報錯,這是因
       為直接執行了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 循環生成子元素div,并給他們設置定位值
  // 設定固定的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');//創建子元素
    oFather.appendChild(oDiv);
    oDiv.style.left = j * (oDiv.offsetWidth + mL) +'px';
    oDiv.style.top = i * (oDiv.offsetHeight + mT) +'px';
    // 隨機顏色設置
    oDiv.style.background = 'rgb('+parseInt(Math.random()*256) + "," +parseInt(Math.random()*256) + ","+parseInt(Math.random()*256)+')';
    // 加上字母
    oDiv.innerText = String.fromCharCode(asc++);
   }
  }
  // 為了方便理解,將事件寫到了外面,這里可以生成標簽循環內部
  /* var oItem = document.querySelectorAll('.father>div');
  這種方式獲取的是靜態集合,只會獲取到初次頁面加載的內容,用這種辦法獲取子元素會出BUG */
  var oItem = oFather.children;
  for(var k = 0 ;k<oItem.length; k++){
   oItem[k].onmousedown = function(e){
    var evt = e || event;
    // 獲取鼠標到目標邊框內的距離
    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;
 
     //把克隆節點移除
     oFather.removeChild(cloneNode);
 
     document.onmousemove = null;
     document.onmouseup = null;
    }
    return false;
   }
  }
 </script>
</body>
</html>

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

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

延伸 · 閱讀

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

    Selenium執行JavaScript腳本的方法示例

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

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

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

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

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

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

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

    Hunter網絡安全7292022-01-04
  • js教程js刪除對象中的某一個字段的方法實現

    js刪除對象中的某一個字段的方法實現

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

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

    如何使用原生Js實現隨機點名詳解

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

    CV_Di8112021-12-27
  • js教程JavaScript canvas實現文字時鐘

    JavaScript canvas實現文字時鐘

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

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

    原生JS實現pc端輪播圖效果

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

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

    一文搞懂JavaScript中的Typeof用法

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

    鋒享前端8162021-12-29
主站蜘蛛池模板: 被啪羞羞视频在线观看 | 成人一级毛片 | 欧美精品一区自拍a毛片在线视频 | 制服丝袜成人动漫 | 久久久久久久久成人 | 干色视频 | 国产91九色视频 | 中文字幕在线免费看 | 热@国产 | 久久久久久久久久美女 | 56av国产精品久久久久久久 | 黄色免费在线网站 | 一区二区三区视频在线播放 | 午夜视频成人 | 久久精品国产一区二区 | 亚洲欧美一区二区三区在线观看 | 久久精品99国产国产精 | 久久91亚洲精品久久91综合 | 国产91免费看 | 国产精品一区二区在线 | av在线播放免费观看 | 久久精品男人 | 欧美一级网站 | 国产精品视频在线观看免费 | 久久亚洲精选 | 桥本有菜免费av一区二区三区 | 日本一区二区三区四区高清视频 | 欧美性生交xxxxx久久久 | 在线观看国产一区二区三区 | 国产精品99久久99久久久二 | 7777网站| 欧美色性| 国产外围在线 | h色在线观看 | 日韩美香港a一级毛片免费 欧美一级淫片007 | 国产在线精品区 | 成人三级黄色片 | 黄色av网站在线观看 | av成人在线播放 | 美女亚洲综合 | 欧美一级特黄特色大片免费 |