回答編集履歴

5

追記

2017/06/20 11:46

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -1,3 +1,15 @@
1
+ 追記2: 自分のコードは修正すべき点があると思いますが、本来どう修正すべきかすぐに確信がもてない(難しい)ため、申し訳ありませんが「よい実装でない点があると思う」とのみコメントさせていただきます。
2
+
3
+
4
+
5
+ 一例を挙げると、自分の実装で子ノードのindexを求めていますが、他の方の回答にあるようにDOMのnextSibling相当の機能を用いた方がより直接的で確実なコードではないかと思いました。
6
+
7
+
8
+
9
+ ---
10
+
11
+
12
+
1
13
  訂正:エレメントを入れ替えるようなコードに訂正してみました。
2
14
 
3
15
 
@@ -168,7 +180,7 @@
168
180
 
169
181
 
170
182
 
171
- 追記:自分のコードはDOM操作初心者のものと言えると思います。
183
+ 追記1:自分のコードはDOM操作初心者のものと言えると思います。
172
184
 
173
185
  yambejpさんのようなシンプルなコードと比べるとかなりどんくさい論理ですね。
174
186
 

4

誤記訂正

2017/06/20 11:46

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -178,7 +178,7 @@
178
178
 
179
179
  自分の論理には「選択状態」とする配慮は入ってません。
180
180
 
181
- yambejpさんのようにclose()を使っておらず、ノードをまともに入れ替えているため末尾のノードかどうか場合分けしてappendChild, insertBeforeを使い分けるようにしています。
181
+ yambejpさんのようにclone()を使っておらず、ノードをまともに入れ替えているため末尾のノードかどうか場合分けしてappendChild, insertBeforeを使い分けるようにしています。
182
182
 
183
183
  また親が同じか違うかで論理を切り替えており、親が違う場合、入れ替えようとするノードが親子関係にあったときは入れ替えないようにしています。
184
184
 

3

敬称漏れ訂正、コードコメント修正

2017/06/20 03:10

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -60,11 +60,11 @@
60
60
 
61
61
  } else if (isAncester(e1, e2) || isAncester(e2, e1)) {
62
62
 
63
- // 一方他方の親だった
63
+ // e1p,e2pに親子(直接・間接)った
64
64
 
65
65
  } else {
66
66
 
67
- // 親が違う場合
67
+ // e1p,e2pに子(直接・間接)ない
68
68
 
69
69
  swapUnderDifferentParent(e1p, e1, e2p, e2);
70
70
 
@@ -178,6 +178,8 @@
178
178
 
179
179
  自分の論理には「選択状態」とする配慮は入ってません。
180
180
 
181
- yambejpのようにclose()を使っておらず、ノードをまともに入れ替えているため末尾のノードかどうか場合分けしてappendChild, insertBeforeを使い分けるようにしています。
181
+ yambejpさんのようにclose()を使っておらず、ノードをまともに入れ替えているため末尾のノードかどうか場合分けしてappendChild, insertBeforeを使い分けるようにしています。
182
182
 
183
183
  また親が同じか違うかで論理を切り替えており、親が違う場合、入れ替えようとするノードが親子関係にあったときは入れ替えないようにしています。
184
+
185
+

2

追記

2017/06/19 02:42

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -161,3 +161,23 @@
161
161
 
162
162
 
163
163
  一応Chromeで動きましたが、かなり分かりにくい論理かもです。
164
+
165
+
166
+
167
+ ---
168
+
169
+
170
+
171
+ 追記:自分のコードはDOM操作初心者のものと言えると思います。
172
+
173
+ yambejpさんのようなシンプルなコードと比べるとかなりどんくさい論理ですね。
174
+
175
+
176
+
177
+ 蛇足ですが・・・
178
+
179
+ 自分の論理には「選択状態」とする配慮は入ってません。
180
+
181
+ yambejpのようにclose()を使っておらず、ノードをまともに入れ替えているため末尾のノードかどうか場合分けしてappendChild, insertBeforeを使い分けるようにしています。
182
+
183
+ また親が同じか違うかで論理を切り替えており、親が違う場合、入れ替えようとするノードが親子関係にあったときは入れ替えないようにしています。

1

変更

2017/06/19 01:03

投稿

KSwordOfHaste
KSwordOfHaste

スコア18394

test CHANGED
@@ -1,10 +1,18 @@
1
+ 訂正:エレメントを入れ替えるようなコードに訂正してみました。
2
+
3
+
4
+
5
+ ---
6
+
7
+
8
+
1
9
  1回目にクリックされたエレメントをe1、2回目をe2として
2
10
 
3
11
 
4
12
 
5
13
  - 1回目はe1を覚えておく
6
14
 
7
- - 2回目e1とe2のinnerTextを入れ替える
15
+ - 2回目e1とe2を入れ替える
8
16
 
9
17
 
10
18
 
@@ -16,9 +24,9 @@
16
24
 
17
25
  $(function() {
18
26
 
19
- var firstClick = false;
27
+ var firstClick = false,
20
28
 
21
- var e1 = null;
29
+ e1 = null;
22
30
 
23
31
  $('.change').on('click', function() {
24
32
 
@@ -30,17 +38,121 @@
30
38
 
31
39
  } else {
32
40
 
33
- e2 = this;
41
+ swap(e1, this);
34
-
35
- var e1text = e1.innerText;
36
-
37
- e1.innerText = e2.innerText;
38
-
39
- e2.innerText = e1text;
40
42
 
41
43
  }
42
44
 
43
45
  });
46
+
47
+
48
+
49
+ function swap(e1, e2) {
50
+
51
+ if (e1 === e2) return;
52
+
53
+ var e1p = e1.parentNode,
54
+
55
+ e2p = e2.parentNode;
56
+
57
+ if (e1p === e2p) {
58
+
59
+ swapUnderSameParent(e1p, e1, e2);
60
+
61
+ } else if (isAncester(e1, e2) || isAncester(e2, e1)) {
62
+
63
+ // 一方が他方の親だった
64
+
65
+ } else {
66
+
67
+ // 親が違う場合
68
+
69
+ swapUnderDifferentParent(e1p, e1, e2p, e2);
70
+
71
+ }
72
+
73
+ }
74
+
75
+
76
+
77
+ function swapUnderSameParent(p, e1, e2) {
78
+
79
+ var i1 = elementIndex(p, e1),
80
+
81
+ i2 = elementIndex(p, e2),
82
+
83
+ tmp;
84
+
85
+ if (i1 > i2) {
86
+
87
+ // e1がe2の前のノードであるようにする
88
+
89
+ tmp = e1, e1 = e2, e2 = tmp;
90
+
91
+ i1 = i2;
92
+
93
+ }
94
+
95
+ p.replaceChild(e1, e2);
96
+
97
+ p.insertBefore(e2, p.childNodes[i1])
98
+
99
+ }
100
+
101
+
102
+
103
+ function swapUnderDifferentParent(e1p, e1, e2p, e2) {
104
+
105
+ var i2 = elementIndex(e2p, e2),
106
+
107
+ children;
108
+
109
+ e1p.replaceChild(e2, e1);
110
+
111
+ children = e2p.childNodes;
112
+
113
+ if (i2 < children.length) {
114
+
115
+ e2p.insertBefore(e1, children[i2]);
116
+
117
+ } else {
118
+
119
+ e2p.appendChild(e1);
120
+
121
+ }
122
+
123
+ }
124
+
125
+
126
+
127
+ function elementIndex(p, c) {
128
+
129
+ var children = p.childNodes;
130
+
131
+ for (var i in children) {
132
+
133
+ if (children[i] === c)
134
+
135
+ return +i;
136
+
137
+ }
138
+
139
+ }
140
+
141
+
142
+
143
+ function isAncester(p, c) {
144
+
145
+ do {
146
+
147
+ if (p === c) return true;
148
+
149
+ c = c.parentNode;
150
+
151
+ } while (c);
152
+
153
+ return false;
154
+
155
+ }
44
156
 
45
157
  });
46
158
 
@@ -48,4 +160,4 @@
48
160
 
49
161
 
50
162
 
51
- 一応Chromeで動きましたが、innerTextの参照・更新のしたがおしな感じするのそこは適宜直していただければと思います。(本当はどう書くべきなのでしょう?...)
163
+ 一応Chromeで動きましたが、かなり分りにくい論理かもです。