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

回答編集履歴

5

DOM API版のjsfiddleサンプルを追加

2017/06/22 13:02

投稿

think49
think49

スコア18194

answer CHANGED
@@ -67,6 +67,7 @@
67
67
  swap-node.js の使い方、制約はGitHubにまとめたのでそちらを参照して下さい。
68
68
 
69
69
  - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/5/)
70
+ - [要素ノードを入れ替える (DOM API ver) - JSFiddle](https://jsfiddle.net/t6ds8Ljg/6/)
70
71
  - [swap-node.js: 2つのノードの位置を入れ替えます - GitHub](https://gist.github.com/think49/4cd2cfc82f308c7b5d696dc2a50af3d4)
71
72
 
72
73
  ```HTML
@@ -131,5 +132,6 @@
131
132
  - 2017/06/19 12:49 2回目のクリックで1回目にクリックした次の要素を選択すると要素ご消失する不具合修正
132
133
  - 2017/06/20 16:40 「コード1の問題点」「コード2 (汎用型)」を追記
133
134
  - 2017/06/21 10:48 swap-node.js を更新(jsfiddleのリンク先を更新)
135
+ - 2017/06/22 22:02 DOM API版のjsfiddleサンプルを追加
134
136
 
135
137
  Re: gomatan1258 さん

4

swap-node\.js を更新\(jsfiddleのリンク先を更新\)

2017/06/22 13:02

投稿

think49
think49

スコア18194

answer CHANGED
@@ -66,7 +66,7 @@
66
66
  swap-node.js は下記リンク先(GitHub)からDLして下さい。
67
67
  swap-node.js の使い方、制約はGitHubにまとめたのでそちらを参照して下さい。
68
68
 
69
- - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/4/)
69
+ - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/5/)
70
70
  - [swap-node.js: 2つのノードの位置を入れ替えます - GitHub](https://gist.github.com/think49/4cd2cfc82f308c7b5d696dc2a50af3d4)
71
71
 
72
72
  ```HTML
@@ -104,7 +104,7 @@
104
104
  <li class="change">2d</li>
105
105
  </ul>
106
106
 
107
- <script src="swap-node-1.0.1.js"></script>
107
+ <script src="swap-node-1.0.2.js"></script>
108
108
  <script>
109
109
  'use strict';
110
110
  jQuery('.change').on('click', function (event) {
@@ -130,5 +130,6 @@
130
130
 
131
131
  - 2017/06/19 12:49 2回目のクリックで1回目にクリックした次の要素を選択すると要素ご消失する不具合修正
132
132
  - 2017/06/20 16:40 「コード1の問題点」「コード2 (汎用型)」を追記
133
+ - 2017/06/21 10:48 swap-node.js を更新(jsfiddleのリンク先を更新)
133
134
 
134
135
  Re: gomatan1258 さん

3

「コード1の問題点」「コード2 \(汎用型\)」を追記

2017/06/21 01:48

投稿

think49
think49

スコア18194

answer CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  `.replaceWith()` を使うと、`jQuery('.change').on('click')` すると同じ要素に続けてクリックしても発火しなくなりました。
9
9
 
10
- ### コード
10
+ ### コード1 (jQuery+DOM混合型)
11
11
 
12
12
  - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/1/)
13
13
 
@@ -48,8 +48,87 @@
48
48
  </script>
49
49
  ```
50
50
 
51
+ ### コード1の問題点
52
+
53
+ コード1にはli要素間のホワイトスペースノードを保持しないという問題がありました。
54
+ li要素のdisplayプロパティを変更していなければ問題になりませんが、 `display: inline` や `display: inline-block` を適用していた場合、ホワイトスペースノードによって開けられていた余白がつめられてしまう不具合を誘発させる事になります。
55
+
56
+ - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/2/)
57
+
58
+ 上記リンク先で要素を入れ替える事で余白がつめられる事象を確認できます。
59
+ これは jQuery API が基本的にテキストノードを読み飛ばして要素ノードのみを対象に取っている事に原因があります。
60
+ 対処療法的には `.next()[0]` を `nextSibling` に修正してやれば回避できる問題ですが、**jQuery API が要素ノードのみを扱う事を基本**としている事にも問題があると思います。
61
+ 例えば、`.next()`, `.before()`, `.after()` を使うだけでこの問題が発生し、jQuery ではテキストノードとテキストノードの間に要素ノードを挿入することが出来ません。
62
+ 従って、「ノードの入れ替え処理は DOM のみで書いた方が良い」という結論に落ち着きます。
63
+
64
+ ### コード2 (汎用型)
65
+
66
+ swap-node.js は下記リンク先(GitHub)からDLして下さい。
67
+ swap-node.js の使い方、制約はGitHubにまとめたのでそちらを参照して下さい。
68
+
69
+ - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/4/)
70
+ - [swap-node.js: 2つのノードの位置を入れ替えます - GitHub](https://gist.github.com/think49/4cd2cfc82f308c7b5d696dc2a50af3d4)
71
+
72
+ ```HTML
73
+ <style>
74
+ .change[aria-selected="true"] {
75
+ color: black;
76
+ background-color: #efe;
77
+ border: solid 1px #3a3;
78
+ }
79
+
80
+ .change {
81
+ margin: 0.3em 0;
82
+ color: black;
83
+ background-color: #ddd;
84
+ border: solid 1px #999;
85
+ padding: 0.2em 0.8em;
86
+ }
87
+
88
+ #test2 .change {
89
+ display: inline-block;
90
+ }
91
+ </style>
92
+ <body>
93
+ <ul id="test1">
94
+ <li class="change">1a</li>
95
+ <li class="change">1b</li>
96
+ <li class="change">1c</li>
97
+ <li class="change">1d</li>
98
+ </ul>
99
+
100
+ <ul id="test2">
101
+ <li class="change">2a</li>
102
+ <li class="change">2b</li>
103
+ <li class="change">2c</li>
104
+ <li class="change">2d</li>
105
+ </ul>
106
+
107
+ <script src="swap-node-1.0.1.js"></script>
108
+ <script>
109
+ 'use strict';
110
+ jQuery('.change').on('click', function (event) {
111
+ var currentTarget = event.currentTarget;
112
+
113
+ if (currentTarget.getAttribute('aria-selected') === 'true') {
114
+ currentTarget.setAttribute('aria-selected', 'false');
115
+ } else {
116
+ var li = currentTarget.ownerDocument.querySelector('.change[aria-selected="true"]');
117
+
118
+ if (li) {
119
+ swapNode(currentTarget, li);
120
+ li.setAttribute('aria-selected', 'false');
121
+ } else {
122
+ currentTarget.setAttribute('aria-selected', 'true');
123
+ }
124
+ }
125
+ });
126
+ </script>
127
+ ```
128
+
51
129
  ### 更新履歴
52
130
 
53
131
  - 2017/06/19 12:49 2回目のクリックで1回目にクリックした次の要素を選択すると要素ご消失する不具合修正
132
+ - 2017/06/20 16:40 「コード1の問題点」「コード2 (汎用型)」を追記
54
133
 
55
134
  Re: gomatan1258 さん

2

2回目のクリックで1回目にクリックした次の要素を選択すると要素ご消失する不具合修正

2017/06/20 07:40

投稿

think49
think49

スコア18194

answer CHANGED
@@ -1,13 +1,16 @@
1
+ ### ノードの参照を保持する
2
+
1
3
  私の知識不足かもしれませんが、jQuery API でやろうとするといろいろと上手くいかないですね。
2
4
  次の点に注意してコードを書いてみました。
3
5
 
4
6
  - DOMノードの参照を保持する(`.replaceWith()` や `.clone()` で新しい参照に入れ替えない)
5
7
 
6
8
  `.replaceWith()` を使うと、`jQuery('.change').on('click')` すると同じ要素に続けてクリックしても発火しなくなりました。
7
- サンプルコードは下記参照。
8
9
 
9
- - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/)
10
+ ### ード
10
11
 
12
+ - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/1/)
13
+
11
14
  ```HTML
12
15
  <ul id="test">
13
16
  <li class="change">aaa</li>
@@ -28,8 +31,14 @@
28
31
 
29
32
  if (li.length) {
30
33
  var next = li.next()[0];
34
+
35
+ if (next === currentTarget[0]) {
36
+ ul.insertBefore(currentTarget[0], li[0]);
37
+ } else {
31
- ul.replaceChild(li[0], currentTarget[0]);
38
+ ul.replaceChild(li[0], currentTarget[0]);
32
- next ? ul.insertBefore(currentTarget[0], next) : ul.appendChild(currentTarget[0]);
39
+ next ? ul.insertBefore(currentTarget[0], next) : ul.appendChild(currentTarget[0]);
40
+ }
41
+
33
42
  li.attr('aria-selected', 'false');
34
43
  } else {
35
44
  currentTarget.attr('aria-selected', 'true');
@@ -39,4 +48,8 @@
39
48
  </script>
40
49
  ```
41
50
 
51
+ ### 更新履歴
52
+
53
+ - 2017/06/19 12:49 2回目のクリックで1回目にクリックした次の要素を選択すると要素ご消失する不具合修正
54
+
42
55
  Re: gomatan1258 さん

1

typo修正

2017/06/19 03:49

投稿

think49
think49

スコア18194

answer CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  - DOMノードの参照を保持する(`.replaceWith()` や `.clone()` で新しい参照に入れ替えない)
5
5
 
6
- `.replaceWith()` を使うと、`jQuery('.change').on('click')` すると同じ要素に続けてクリしても発火しなくなりました。
6
+ `.replaceWith()` を使うと、`jQuery('.change').on('click')` すると同じ要素に続けてクリックしても発火しなくなりました。
7
7
  サンプルコードは下記参照。
8
8
 
9
9
  - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/)