回答編集履歴

5

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

2017/06/22 13:02

投稿

think49
think49

スコア18162

test CHANGED
@@ -136,6 +136,8 @@
136
136
 
137
137
  - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/5/)
138
138
 
139
+ - [要素ノードを入れ替える (DOM API ver) - JSFiddle](https://jsfiddle.net/t6ds8Ljg/6/)
140
+
139
141
  - [swap-node.js: 2つのノードの位置を入れ替えます - GitHub](https://gist.github.com/think49/4cd2cfc82f308c7b5d696dc2a50af3d4)
140
142
 
141
143
 
@@ -264,6 +266,8 @@
264
266
 
265
267
  - 2017/06/21 10:48 swap-node.js を更新(jsfiddleのリンク先を更新)
266
268
 
269
+ - 2017/06/22 22:02 DOM API版のjsfiddleサンプルを追加
270
+
267
271
 
268
272
 
269
273
  Re: gomatan1258 さん

4

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

2017/06/22 13:02

投稿

think49
think49

スコア18162

test CHANGED
@@ -134,7 +134,7 @@
134
134
 
135
135
 
136
136
 
137
- - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/4/)
137
+ - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/5/)
138
138
 
139
139
  - [swap-node.js: 2つのノードの位置を入れ替えます - GitHub](https://gist.github.com/think49/4cd2cfc82f308c7b5d696dc2a50af3d4)
140
140
 
@@ -210,7 +210,7 @@
210
210
 
211
211
 
212
212
 
213
- <script src="swap-node-1.0.1.js"></script>
213
+ <script src="swap-node-1.0.2.js"></script>
214
214
 
215
215
  <script>
216
216
 
@@ -262,6 +262,8 @@
262
262
 
263
263
  - 2017/06/20 16:40 「コード1の問題点」「コード2 (汎用型)」を追記
264
264
 
265
+ - 2017/06/21 10:48 swap-node.js を更新(jsfiddleのリンク先を更新)
266
+
265
267
 
266
268
 
267
269
  Re: gomatan1258 さん

3

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

2017/06/21 01:48

投稿

think49
think49

スコア18162

test CHANGED
@@ -16,7 +16,7 @@
16
16
 
17
17
 
18
18
 
19
- ### コード
19
+ ### コード1 (jQuery+DOM混合型)
20
20
 
21
21
 
22
22
 
@@ -98,12 +98,170 @@
98
98
 
99
99
 
100
100
 
101
+ ### コード1の問題点
102
+
103
+
104
+
105
+ コード1にはli要素間のホワイトスペースノードを保持しないという問題がありました。
106
+
107
+ li要素のdisplayプロパティを変更していなければ問題になりませんが、 `display: inline` や `display: inline-block` を適用していた場合、ホワイトスペースノードによって開けられていた余白がつめられてしまう不具合を誘発させる事になります。
108
+
109
+
110
+
111
+ - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/2/)
112
+
113
+
114
+
115
+ 上記リンク先で要素を入れ替える事で余白がつめられる事象を確認できます。
116
+
117
+ これは jQuery API が基本的にテキストノードを読み飛ばして要素ノードのみを対象に取っている事に原因があります。
118
+
119
+ 対処療法的には `.next()[0]` を `nextSibling` に修正してやれば回避できる問題ですが、**jQuery API が要素ノードのみを扱う事を基本**としている事にも問題があると思います。
120
+
121
+ 例えば、`.next()`, `.before()`, `.after()` を使うだけでこの問題が発生し、jQuery ではテキストノードとテキストノードの間に要素ノードを挿入することが出来ません。
122
+
123
+ 従って、「ノードの入れ替え処理は DOM のみで書いた方が良い」という結論に落ち着きます。
124
+
125
+
126
+
127
+ ### コード2 (汎用型)
128
+
129
+
130
+
131
+ swap-node.js は下記リンク先(GitHub)からDLして下さい。
132
+
133
+ swap-node.js の使い方、制約はGitHubにまとめたのでそちらを参照して下さい。
134
+
135
+
136
+
137
+ - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/4/)
138
+
139
+ - [swap-node.js: 2つのノードの位置を入れ替えます - GitHub](https://gist.github.com/think49/4cd2cfc82f308c7b5d696dc2a50af3d4)
140
+
141
+
142
+
143
+ ```HTML
144
+
145
+ <style>
146
+
147
+ .change[aria-selected="true"] {
148
+
149
+ color: black;
150
+
151
+ background-color: #efe;
152
+
153
+ border: solid 1px #3a3;
154
+
155
+ }
156
+
157
+
158
+
159
+ .change {
160
+
161
+ margin: 0.3em 0;
162
+
163
+ color: black;
164
+
165
+ background-color: #ddd;
166
+
167
+ border: solid 1px #999;
168
+
169
+ padding: 0.2em 0.8em;
170
+
171
+ }
172
+
173
+
174
+
175
+ #test2 .change {
176
+
177
+ display: inline-block;
178
+
179
+ }
180
+
181
+ </style>
182
+
183
+ <body>
184
+
185
+ <ul id="test1">
186
+
187
+ <li class="change">1a</li>
188
+
189
+ <li class="change">1b</li>
190
+
191
+ <li class="change">1c</li>
192
+
193
+ <li class="change">1d</li>
194
+
195
+ </ul>
196
+
197
+
198
+
199
+ <ul id="test2">
200
+
201
+ <li class="change">2a</li>
202
+
203
+ <li class="change">2b</li>
204
+
205
+ <li class="change">2c</li>
206
+
207
+ <li class="change">2d</li>
208
+
209
+ </ul>
210
+
211
+
212
+
213
+ <script src="swap-node-1.0.1.js"></script>
214
+
215
+ <script>
216
+
217
+ 'use strict';
218
+
219
+ jQuery('.change').on('click', function (event) {
220
+
221
+ var currentTarget = event.currentTarget;
222
+
223
+
224
+
225
+ if (currentTarget.getAttribute('aria-selected') === 'true') {
226
+
227
+ currentTarget.setAttribute('aria-selected', 'false');
228
+
229
+ } else {
230
+
231
+ var li = currentTarget.ownerDocument.querySelector('.change[aria-selected="true"]');
232
+
233
+
234
+
235
+ if (li) {
236
+
237
+ swapNode(currentTarget, li);
238
+
239
+ li.setAttribute('aria-selected', 'false');
240
+
241
+ } else {
242
+
243
+ currentTarget.setAttribute('aria-selected', 'true');
244
+
245
+ }
246
+
247
+ }
248
+
249
+ });
250
+
251
+ </script>
252
+
253
+ ```
254
+
255
+
256
+
101
257
  ### 更新履歴
102
258
 
103
259
 
104
260
 
105
261
  - 2017/06/19 12:49 2回目のクリックで1回目にクリックした次の要素を選択すると要素ご消失する不具合修正
106
262
 
263
+ - 2017/06/20 16:40 「コード1の問題点」「コード2 (汎用型)」を追記
264
+
107
265
 
108
266
 
109
267
  Re: gomatan1258 さん

2

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

2017/06/20 07:40

投稿

think49
think49

スコア18162

test CHANGED
@@ -1,3 +1,7 @@
1
+ ### ノードの参照を保持する
2
+
3
+
4
+
1
5
  私の知識不足かもしれませんが、jQuery API でやろうとするといろいろと上手くいかないですね。
2
6
 
3
7
  次の点に注意してコードを書いてみました。
@@ -10,11 +14,13 @@
10
14
 
11
15
  `.replaceWith()` を使うと、`jQuery('.change').on('click')` すると同じ要素に続けてクリックしても発火しなくなりました。
12
16
 
17
+
18
+
13
- サンプルコードは下記参照。
19
+ ### コード
14
20
 
15
21
 
16
22
 
17
- - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/)
23
+ - [要素ノードを入れ替える - JSFiddle](https://jsfiddle.net/t6ds8Ljg/1/)
18
24
 
19
25
 
20
26
 
@@ -58,9 +64,21 @@
58
64
 
59
65
  var next = li.next()[0];
60
66
 
61
- ul.replaceChild(li[0], currentTarget[0]);
62
67
 
68
+
69
+ if (next === currentTarget[0]) {
70
+
71
+ ul.insertBefore(currentTarget[0], li[0]);
72
+
73
+ } else {
74
+
75
+ ul.replaceChild(li[0], currentTarget[0]);
76
+
63
- next ? ul.insertBefore(currentTarget[0], next) : ul.appendChild(currentTarget[0]);
77
+ next ? ul.insertBefore(currentTarget[0], next) : ul.appendChild(currentTarget[0]);
78
+
79
+ }
80
+
81
+
64
82
 
65
83
  li.attr('aria-selected', 'false');
66
84
 
@@ -80,4 +98,12 @@
80
98
 
81
99
 
82
100
 
101
+ ### 更新履歴
102
+
103
+
104
+
105
+ - 2017/06/19 12:49 2回目のクリックで1回目にクリックした次の要素を選択すると要素ご消失する不具合修正
106
+
107
+
108
+
83
109
  Re: gomatan1258 さん

1

typo修正

2017/06/19 03:49

投稿

think49
think49

スコア18162

test CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
 
10
10
 
11
- `.replaceWith()` を使うと、`jQuery('.change').on('click')` すると同じ要素に続けてクリしても発火しなくなりました。
11
+ `.replaceWith()` を使うと、`jQuery('.change').on('click')` すると同じ要素に続けてクリックしても発火しなくなりました。
12
12
 
13
13
  サンプルコードは下記参照。
14
14