回答編集履歴

1

動的計算のコードを追記

2017/11/26 17:08

投稿

think49
think49

スコア18162

test CHANGED
@@ -1,3 +1,7 @@
1
+ ### calc()
2
+
3
+
4
+
1
5
  `calc()` で計算してやれば、**内容の最小幅に反しない範囲で**なら実現可能な気がします。
2
6
 
3
7
  動的に要素ノードを追加するなら、`width` プロパティ値も動的に算出してやる必要はあります。
@@ -74,4 +78,346 @@
74
78
 
75
79
 
76
80
 
81
+ ### 動的計算のコード
82
+
83
+
84
+
85
+ tableは自動的に等間隔の幅に合わせる為、アスペクト比だけ合わせれば、期待通りに動作するようです。
86
+
87
+
88
+
89
+ 下記コードは `width`, `height` 以外のプロパティ値(`border`, `font-size`等)は元の値を維持します。
90
+
91
+ 必要であれば、`setStyleRule()` の適用範囲を広げて下さい。
92
+
93
+
94
+
95
+ - [動的に表セルの幅/高さを算出する - JSFiddle](https://jsfiddle.net/dsk701fn/)
96
+
97
+
98
+
99
+ ```HTML
100
+
101
+ <style>
102
+
103
+ html, body {
104
+
105
+ margin: 0;
106
+
107
+ padding: 0;
108
+
109
+ width: 100%;
110
+
111
+ }
112
+
113
+
114
+
115
+ #sample {
116
+
117
+ margin: 0;
118
+
119
+ padding: 0;
120
+
121
+ width: calc(100% - 2px);
122
+
123
+ border: 1px black solid;
124
+
125
+ border-collapse: separate;
126
+
127
+ border-spacing: 1px;
128
+
129
+ }
130
+
131
+
132
+
133
+ #sample td {
134
+
135
+ background-color: #eef;
136
+
137
+ border: 1px black solid;
138
+
139
+ text-align: center;
140
+
141
+ vertical-align: middle;
142
+
143
+ }
144
+
145
+ </style>
146
+
147
+ </head>
148
+
149
+ <body>
150
+
151
+ <form id="table-setting">
152
+
153
+ <p><label>縦横比(縦/横) <input type="number" name="aspect-ratio" value="1"></label></p>
154
+
155
+ <p><label>列数 <input type="number" name="cells-length" value="5"></label></p>
156
+
157
+ <p><label>行数 <input type="number" name="rows-length" value="5"></label></p>
158
+
159
+ </form>
160
+
161
+ <table id="sample">
162
+
163
+ <tbody>
164
+
165
+ <tr><td></td></tr>
166
+
167
+ </tbody>
168
+
169
+ </table>
170
+
171
+ <script>
172
+
173
+ 'use strict';
174
+
175
+ (function () {
176
+
177
+ function setStyleRule (doc, selectorText, property, value) {
178
+
179
+ var styleSheets = doc.styleSheets,
180
+
181
+ styleSheetslength = styleSheets.length,
182
+
183
+ i = 0,
184
+
185
+ cssRules, cssStyleRule, cssRulesLength, j;
186
+
187
+
188
+
189
+ while (i < styleSheetslength) {
190
+
191
+ cssRules = styleSheets[i++].cssRules;
192
+
193
+ cssRulesLength = cssRules.length;
194
+
195
+ j = 0;
196
+
197
+
198
+
199
+ while (j < cssRulesLength) {
200
+
201
+ cssStyleRule = cssRules[j++];
202
+
203
+
204
+
205
+ if (cssStyleRule.selectorText === selectorText) {
206
+
207
+ cssStyleRule.style[property] = value;
208
+
209
+ return;
210
+
211
+ }
212
+
213
+ }
214
+
215
+ }
216
+
217
+ }
218
+
219
+
220
+
221
+ function handleInputAspectRatio (event) {
222
+
223
+ var input = event.target,
224
+
225
+ aspectRatio = input.valueAsNumber,
226
+
227
+ doc = input.ownerDocument,
228
+
229
+ td = doc.getElementById('sample').tBodies[0].rows[0].cells[0],
230
+
231
+ width = doc.defaultView.getComputedStyle(td, '').width;
232
+
233
+
234
+
235
+ setStyleRule(doc, '#sample td', 'height', parseFloat(width) * aspectRatio + 'px');
236
+
237
+ }
238
+
239
+
240
+
241
+ function handleInputRowsLength (event) {
242
+
243
+ var input = event.target,
244
+
245
+ length = input.valueAsNumber,
246
+
247
+ tbody = input.ownerDocument.getElementById('sample').tBodies[0],
248
+
249
+ rows = tbody.rows,
250
+
251
+ rowsLength = rows.length,
252
+
253
+ tr;
254
+
255
+
256
+
257
+ if (length === rowsLength) {
258
+
259
+ return;
260
+
261
+ }
262
+
263
+
264
+
265
+ if (length > rowsLength) {
266
+
267
+ tr = rows[0];
268
+
269
+
270
+
271
+ while (rowsLength++ < length) {
272
+
273
+ tbody.appendChild(tr.cloneNode(true));
274
+
275
+ }
276
+
277
+ } else {
278
+
279
+ while (rowsLength > length) {
280
+
281
+ tbody.removeChild(rows[--rowsLength]);
282
+
283
+ }
284
+
285
+ }
286
+
287
+
288
+
289
+ handleInputAspectRatio({target: input.form.elements['aspect-ratio']});
290
+
291
+ }
292
+
293
+
294
+
295
+ function handleInputCellsLength (event) {
296
+
297
+ var input = event.target,
298
+
299
+ length = input.valueAsNumber,
300
+
301
+ doc = input.ownerDocument,
302
+
303
+ tbody = doc.getElementById('sample').tBodies[0],
304
+
305
+ rows = tbody.rows,
306
+
307
+ rowsLength = rows.length,
308
+
309
+ tr = rows[0],
310
+
311
+ cells = tr.cells,
312
+
313
+ cellsLength = cells.length,
314
+
315
+ td, df, i;
316
+
317
+
318
+
319
+ if (length === cellsLength) {
320
+
321
+ return;
322
+
323
+ }
324
+
325
+
326
+
327
+ if (length > cellsLength) {
328
+
329
+ td = cells[0];
330
+
331
+ df = doc.createDocumentFragment();
332
+
333
+
334
+
335
+ while (cellsLength++ < length) {
336
+
337
+ df.appendChild(td.cloneNode(true));
338
+
339
+ }
340
+
341
+
342
+
343
+ i = 0;
344
+
345
+
346
+
347
+ while (i < rowsLength) {
348
+
349
+ rows[i++].appendChild(df.cloneNode(true));
350
+
351
+ }
352
+
353
+ } else {
354
+
355
+ while (rowsLength) {
356
+
357
+ tr = rows[--rowsLength];
358
+
359
+ i = cellsLength;
360
+
361
+
362
+
363
+ while (length < i) {
364
+
365
+ tr.deleteCell(--i);
366
+
367
+ }
368
+
369
+ }
370
+
371
+ }
372
+
373
+
374
+
375
+ handleInputAspectRatio({target: input.form.elements['aspect-ratio']});
376
+
377
+ }
378
+
379
+
380
+
381
+
382
+
383
+ function main () {
384
+
385
+ var elements = this.document.getElementById('table-setting').elements,
386
+
387
+ aspectRatio = elements['aspect-ratio'],
388
+
389
+ rowsLength = elements['rows-length'],
390
+
391
+ cellsLength = elements['cells-length'];
392
+
393
+
394
+
395
+ aspectRatio.addEventListener('input', handleInputAspectRatio, false);
396
+
397
+ rowsLength.addEventListener('input', handleInputRowsLength, false);
398
+
399
+ cellsLength.addEventListener('input', handleInputCellsLength, false);
400
+
401
+
402
+
403
+ handleInputAspectRatio({target: aspectRatio});
404
+
405
+ handleInputRowsLength({target: rowsLength});
406
+
407
+ handleInputCellsLength({target: cellsLength});
408
+
409
+ }
410
+
411
+
412
+
413
+ main.call(this);
414
+
415
+ }.call(this));
416
+
417
+ </script>
418
+
419
+ ```
420
+
421
+
422
+
77
423
  Re: nnahito さん