teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

5

追記

2017/06/20 11:46

投稿

KSwordOfHaste
KSwordOfHaste

スコア18404

answer CHANGED
@@ -1,3 +1,9 @@
1
+ 追記2: 自分のコードは修正すべき点があると思いますが、本来どう修正すべきかすぐに確信がもてない(難しい)ため、申し訳ありませんが「よい実装でない点があると思う」とのみコメントさせていただきます。
2
+
3
+ 一例を挙げると、自分の実装で子ノードのindexを求めていますが、他の方の回答にあるようにDOMのnextSibling相当の機能を用いた方がより直接的で確実なコードではないかと思いました。
4
+
5
+ ---
6
+
1
7
  訂正:エレメントを入れ替えるようなコードに訂正してみました。
2
8
 
3
9
  ---
@@ -83,7 +89,7 @@
83
89
 
84
90
  ---
85
91
 
86
- 追記:自分のコードはDOM操作初心者のものと言えると思います。
92
+ 追記1:自分のコードはDOM操作初心者のものと言えると思います。
87
93
  yambejpさんのようなシンプルなコードと比べるとかなりどんくさい論理ですね。
88
94
 
89
95
  蛇足ですが・・・

4

誤記訂正

2017/06/20 11:46

投稿

KSwordOfHaste
KSwordOfHaste

スコア18404

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

3

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

2017/06/20 03:10

投稿

KSwordOfHaste
KSwordOfHaste

スコア18404

answer CHANGED
@@ -29,9 +29,9 @@
29
29
  if (e1p === e2p) {
30
30
  swapUnderSameParent(e1p, e1, e2);
31
31
  } else if (isAncester(e1, e2) || isAncester(e2, e1)) {
32
- // 一方が他方のった
32
+ // e1p,e2pに子(直接・間接)があった
33
33
  } else {
34
- // 親が違う場合
34
+ // e1p,e2pに子(直接・間接)ない
35
35
  swapUnderDifferentParent(e1p, e1, e2p, e2);
36
36
  }
37
37
  }
@@ -88,5 +88,5 @@
88
88
 
89
89
  蛇足ですが・・・
90
90
  自分の論理には「選択状態」とする配慮は入ってません。
91
- yambejpのようにclose()を使っておらず、ノードをまともに入れ替えているため末尾のノードかどうか場合分けしてappendChild, insertBeforeを使い分けるようにしています。
91
+ yambejpさんのようにclose()を使っておらず、ノードをまともに入れ替えているため末尾のノードかどうか場合分けしてappendChild, insertBeforeを使い分けるようにしています。
92
- また親が同じか違うかで論理を切り替えており、親が違う場合、入れ替えようとするノードが親子関係にあったときは入れ替えないようにしています。
92
+ また親が同じか違うかで論理を切り替えており、親が違う場合、入れ替えようとするノードが親子関係にあったときは入れ替えないようにしています。

2

追記

2017/06/19 02:42

投稿

KSwordOfHaste
KSwordOfHaste

スコア18404

answer CHANGED
@@ -79,4 +79,14 @@
79
79
  });
80
80
  ```
81
81
 
82
- 一応Chromeで動きましたが、かなり分かりにくい論理かもです。
82
+ 一応Chromeで動きましたが、かなり分かりにくい論理かもです。
83
+
84
+ ---
85
+
86
+ 追記:自分のコードはDOM操作初心者のものと言えると思います。
87
+ yambejpさんのようなシンプルなコードと比べるとかなりどんくさい論理ですね。
88
+
89
+ 蛇足ですが・・・
90
+ 自分の論理には「選択状態」とする配慮は入ってません。
91
+ yambejpのようにclose()を使っておらず、ノードをまともに入れ替えているため末尾のノードかどうか場合分けしてappendChild, insertBeforeを使い分けるようにしています。
92
+ また親が同じか違うかで論理を切り替えており、親が違う場合、入れ替えようとするノードが親子関係にあったときは入れ替えないようにしています。

1

変更

2017/06/19 01:03

投稿

KSwordOfHaste
KSwordOfHaste

スコア18404

answer CHANGED
@@ -1,26 +1,82 @@
1
+ 訂正:エレメントを入れ替えるようなコードに訂正してみました。
2
+
3
+ ---
4
+
1
5
  1回目にクリックされたエレメントをe1、2回目をe2として
2
6
 
3
7
  - 1回目はe1を覚えておく
4
- - 2回目e1とe2のinnerTextを入れ替える
8
+ - 2回目e1とe2を入れ替える
5
9
 
6
10
  といったアプローチではいかがでしょう?
7
11
 
8
12
  ```javascript
9
13
  $(function() {
10
- var firstClick = false;
14
+ var firstClick = false,
11
- var e1 = null;
15
+ e1 = null;
12
16
  $('.change').on('click', function() {
13
17
  firstClick = !firstClick;
14
18
  if (firstClick) {
15
19
  e1 = this;
16
20
  } else {
17
- e2 = this;
21
+ swap(e1, this);
18
- var e1text = e1.innerText;
19
- e1.innerText = e2.innerText;
20
- e2.innerText = e1text;
21
22
  }
22
23
  });
24
+
25
+ function swap(e1, e2) {
26
+ if (e1 === e2) return;
27
+ var e1p = e1.parentNode,
28
+ e2p = e2.parentNode;
29
+ if (e1p === e2p) {
30
+ swapUnderSameParent(e1p, e1, e2);
31
+ } else if (isAncester(e1, e2) || isAncester(e2, e1)) {
32
+ // 一方が他方の親だった
33
+ } else {
34
+ // 親が違う場合
35
+ swapUnderDifferentParent(e1p, e1, e2p, e2);
36
+ }
37
+ }
38
+
39
+ function swapUnderSameParent(p, e1, e2) {
40
+ var i1 = elementIndex(p, e1),
41
+ i2 = elementIndex(p, e2),
42
+ tmp;
43
+ if (i1 > i2) {
44
+ // e1がe2の前のノードであるようにする
45
+ tmp = e1, e1 = e2, e2 = tmp;
46
+ i1 = i2;
47
+ }
48
+ p.replaceChild(e1, e2);
49
+ p.insertBefore(e2, p.childNodes[i1])
50
+ }
51
+
52
+ function swapUnderDifferentParent(e1p, e1, e2p, e2) {
53
+ var i2 = elementIndex(e2p, e2),
54
+ children;
55
+ e1p.replaceChild(e2, e1);
56
+ children = e2p.childNodes;
57
+ if (i2 < children.length) {
58
+ e2p.insertBefore(e1, children[i2]);
59
+ } else {
60
+ e2p.appendChild(e1);
61
+ }
62
+ }
63
+
64
+ function elementIndex(p, c) {
65
+ var children = p.childNodes;
66
+ for (var i in children) {
67
+ if (children[i] === c)
68
+ return +i;
69
+ }
70
+ }
71
+
72
+ function isAncester(p, c) {
73
+ do {
74
+ if (p === c) return true;
75
+ c = c.parentNode;
76
+ } while (c);
77
+ return false;
78
+ }
23
79
  });
24
80
  ```
25
81
 
26
- 一応Chromeで動きましたが、innerTextの参照・更新のしたがおかし感じするのそこは適宜直していただければと思います。(本当はどう書くべきなのでしょう?...)
82
+ 一応Chromeで動きましたが、かなり分かりにくい論理かもです。