/
151.txt
678 lines (526 loc) · 33.7 KB
/
151.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
[82] [DFN[[CODE(JS)@en[document.write]]]] は、
動作中の[[構文解析器]]の[[入力ストリーム]]に[[文字列]]を挿入する [[JavaScript]]
[[メソッド]]です。
[83] [[DOM0]] 時代には、 [CODE(JS)@en[document.write]] は[[文書]]の内容を任意に書き換える唯一の方法でした。
その後の [[DOM]] [[API]] の整備により、[[構文解析器]]の動作中に限らず[[文書]]の任意の部分を書き換えられるようになったため、
[CODE(JS)@en[document.write]] は徐々に使われなくなりました。
[84] [[構文解析器]]が[[構文解析]]の進行中に [CODE(HTMLe)@en[script]]
[[要素]]の[[スクリプト]]を実行し、そこから [CODE(JS)@en[document.write]]
によって[[入力ストリーム]]に[[スクリプト]]が介入できるため、
[[構文解析器]]の動作が複雑になる要因の1つとなっています。
;; [CODE(JS)@en[document.write]] によって新たに [CODE(HTMLe)@en[script]]
[[要素]]を注入することも可能です。
* 仕様書
[REFS[
- [10] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2015-05-06 10:42:35 +09:00]] 版) <https://html.spec.whatwg.org/#dom-document-write>
]REFS]
* 処理
[62] [CODE(DOMi)@en[[[Document]]]] [[インターフェイス]]の
[DFN[[CODE(DOMm)@en[write][document.write]]]] [[メソッド]]は、
次のようにしなければ[MUST[なりません]] [SRC[>>10]]。
[FIG(steps)[
= [64] [VAR[引数群]]を、指定されたすべての[[引数]]を [CODE(IDL)@en[[[DOMString]]]] として解釈した結果に設定します [SRC[>>10]]。
= [76] [VAR[入力]]を、[[空文字列]]に設定します。
= [100] [VAR[引数群]]の各[VAR[引数]]について、順に、
== [101] [VAR[入力]]の末尾に[VAR[引数]]を追加します。
= [97] [[文脈オブジェクト]]と[VAR[入力]]について、
[[document write steps]] を実行します。
[[例外]]が[[投げ]]られたら、[[再び投げ]]ます。
]FIG]
[73] [CODE(DOMi)@en[[[Document]]]] [[インターフェイス]]の
[DFN[[CODE(DOMm)@en[writeln]]]] [[メソッド]]は、
次のようにしなければ[MUST[なりません]] [SRC[>>10]]。
[FIG(steps)[
= [102] [VAR[引数群]]を、指定されたすべての[[引数]]を [CODE(IDL)@en[[[DOMString]]]] として解釈した結果に設定します [SRC[>>10]]。
= [103] [VAR[入力]]を、[[空文字列]]に設定します。
= [104] [VAR[引数群]]の各[VAR[引数]]について、順に、
== [105] [VAR[入力]]の末尾に[VAR[引数]]を追加します。
= [106] [VAR[入力]]の末尾に [CODE[U+000A]] を追加します。
= [107] [[文脈オブジェクト]]と[VAR[入力]]について、
[[document write steps]] を実行します。
[[例外]]が[[投げ]]られたら、[[再び投げ]]ます。
]FIG]
[96] [DFN[document write steps]] は、[VAR[文書]]と[VAR[入力]]を次のようにします。
[FIG(steps)[
= [65]
[FIG(list)[
- [88] [VAR[文書]]の[F[型][文書の型]]が [[XML文書]]
- [89] [VAR[文書]]の [F[throw-on-dynamic-markup-insertion counter]] が[[正]]
]FIG]
... のいずれかの場合、
== [90] [CODE(DOMe)@en[InvalidStateError]] [[例外]]を投げ、ここで停止します [SRC[>>10]]。
= [66] [VAR[文書]]の[F[活性文書]]が[[偽]]の場合、
== [91] ここで停止します [SRC[>>10]]。
= [67]
[FIG(list)[
- [92] [VAR[文書]]の[F[構文解析器]]が [CODE[null]]
- [93] [VAR[文書]]の[F[構文解析器]]の[F[挿入点]]が[[未定義]]
]FIG]
... のいずれかの場合、
== [68] [VAR[文書]]の [[ignore-opens-during-unload counter]] が[[正]]か、
[VAR[文書]]の [[ignore-destructive-writes counter]] が[[正]]の場合、
=== [99] ここで停止します [SRC[>>10]]。
== [69] [VAR[結果]]を、[VAR[文書]]について、[[文書を開く手順群]]を実行した結果に設定します
[SRC[>>10]]。
== [70] [VAR[結果]]が [[refused to allow the document to be unloaded]] の場合、
=== [98] ここで停止します [SRC[>>10]]。
== [71] [VAR[文書]]の[F[構文解析器]]の[F[挿入点]]を、
[VAR[文書]]の[F[構文解析器]]の[F[入力ストリーム]]の末尾に設定します [SRC[>>10]]。
= [72] [VAR[文書]]の[F[構文解析器]]の[F[入力ストリーム]]に対し、
[VAR[文書]]の[F[構文解析器]]の[F[挿入点]]の直前に、
[VAR[入力]]を挿入します [SRC[>>10]]。
= [74] [VAR[文書]]の [F[reload override flag]] が[[真]]の場合、
== [75] [VAR[文書]]の [F[reload override buffer]] の末尾に、[VAR[入力]]に挿入します
[SRC[>>10]]。
= [77] [VAR[文書]]に [[pending parsing-blocking script]] がない場合、
== [78] [VAR[文書]]の[F[構文解析器]]について、
[[字句化器]]が[F[挿入点]]に達するか、[[木構築段階]]が[[構文解析器]]を [[abort]]
するまで、[[構文解析器]]を動作させます。
([CODE(HTMLe)@en[[[script]]]] [[終了タグ]]があると、 [[abort]] することがあります。)
[SRC[>>10]]
]FIG]
;; [63] [VAR[文書]]が[[構文解析]]中なら、ここで[[構文解析器]]が再帰的に動作させられることがあります。
[9] [[文書]]は [DFN[[[ignore-destructive-writes counter]]]] を持ちます。
その初期値は0です。 [SRC[>>10]]
;; [79] 実際の [[Webブラウザー]]は、 [[script nesting level]] が[[正]]なら
([[スクリプト]]内からの [CODE(JS)@en[[[document.write]]]] 呼び出しなら)
[[reload override buffer]] に追記しないようです。
(そうしないと[[再読込]]後に [CODE(JS)@en[[[document.write]]]] された部分が二重になってしまいます。)
[TIME[2015-05-07T03:21:43.200Z]]
* 歴史
** HTML 4
[1] 仕様書:
- [[HTML 4]]
-- [CITE[18.2.4 Dynamic modification of documents]]
<IW:HTML4:"interact/scripts.html#idx-document">
-- [CITE[18.2.3 Intrinsic events]]
<IW:HTML4:"interact/scripts.html#idx-control">
[2] HTML 4 の 18.2.4 は文書読込み時に実行される[[スクリプト]]による文書内容の動的な編集について触れています。
そこでは [CODE(JS)[[[document]].write]]
はその実現手段の一例として挙げられていますが、
実用的なレベルで存在したもので該当するのは他になかったでしょうし、
[[DOM]] が整理される以前の規定ですから、
[CODE(JS)[document.write]] と HTML 文書・UA の関係に関する規定と捉えてよいでしょう。
また、一般の DOM による操作等は想定範囲外でしょうから、
拡大して解釈することには慎重であるべきと考えられます。
さて、 18.2.4 によれば、文書の動的な編集は次の通りモデル化できるそうです。
= すべての [CODE(HTMLe)[[[script]]]] が、
文書の読込まれる順序で評価されます。
= [[SGML]] [CODE(SGML)[[[CDATA]]]] を生成する [CODE(HTMLe)[[[script]]]]
要素中のスクリプト構造がすべて評価されます。
その生成文を結合したものが文書中の [CODE(HTMLe)[[[script]]]]
要素の場所に挿入されます。
= 生成された [CODE(SGML)[CDATA]] が再評価されます。
このモデルは、 SGML 構文解析器で HTML 文書から木構造を抽出し、
それを HTML 仕様書の規定する意味と表現によってレンダリングするという
SGML 的に本来あるべき UA の処理方法ではなく、 HTML
文書を適当に読込みながら適当に解析しつつ適当にレンダリングし続けるという
WWW ブラウザの伝統的な処理方法に依拠しているように思えます。
[18]
HTML 4 仕様書に示された例によれば、
[PRE(HTML example code)[
<TITLE>Test Document</TITLE>
<SCRIPT type="text/javascript">
document.write("<p><b>Hello World!<\/b>")
</SCRIPT>
]PRE]
は
[PRE(HTML example code)[
<TITLE>Test Document</TITLE>
<P><B>Hello World!</B>
]PRE]
という HTML マークと同じ効果を持ちます。[Q[効果]]という曖昧な言葉を使っているため、
何を指しているのか (レンダリング結果? 出来上がる構造?) はっきりとはしませんが、
ともかくある意味においてこの2例は HTML 的に等価です。
ところが、 SGML 的には、前者は
[PRE(HTML invalid example code)[
<HTML><HEAD> <TITLE>Test Document</TITLE>
<SCRIPT type="text/javascript">
document.write("<p><b>Hello World!<\/b>")
</SCRIPT>
</HEAD></HTML>
]PRE]
と等価 (完全に交換可能) であり、
;; 注: これだけでは [CODE(HTMLe)@en[[[body]]]] [[要素]]がないので、
[[非妥当]]です。
後者は
[PRE(HTML example code)[
<HTML><HEAD> <TITLE>Test Document</TITLE>
</HEAD><BODY><P><B>Hello World!</B>
</BODY></HTML>
]PRE]
と等価ですから、両者は異なる構造を持っています。そして、
[CODE(JS)[document.write]] の結果は常に [CODE(HTMLe)[[[body]]]]
内に書込まれるとか (これは先のモデルと矛盾します。)、
[CODE(HTMLe)[[[head]]]] 内にも [CODE(HTMLe)[[[p]]]] 要素が含められるとか
(これは HTML DTD と矛盾します。) の仮定を置かない限り、
適切な結果が得られません。
[3] HTML 4 は、次のようにも述べています。
> HTML 文書は、 [CODE(HTMLe)[script]] 要素の処理の前後いずれにおいても
HTML DTD に適合するよう制約されます。
[CODE(HTMLe)[script]] の出力であるからといって
[CODE(HTMLe)[[[ul]]]] 要素の子供に [CODE(HTMLe)[[[td]]]]
要素があっても困りますから、これは当然の規定といえましょう。
しかし、ここで、 >>2 とも関係しますが、
処理後の適合性は何について判断するのかという疑問が生じます。
[PRE(HTML)[
<TITLE>Test Document</TITLE>
<SCRIPT type="text/javascript">
document.write("<p><b>Hello World!<\/b>")
</SCRIPT>
]PRE]
が >>2 の SGML 的解釈のように
[PRE(HTML invalid example code)[
<HTML><HEAD> <TITLE>Test Document</TITLE>
<p><b>Hello World!</b>
</HEAD></HTML>
]PRE]
となるなら、 ([CODE(HTMLe)@en[[[body]]]] [[要素]]がないことには目をつぶっても)
[CODE(HTMLe)@en[[[head]]]] [[要素]]内に [CODE(HTMLe)@en[[[p]]]]
[[要素]]を入れることはできないので、[[非妥当]]です。しかし、
一旦
[PRE(HTML example code)[
<TITLE>Test Document</TITLE>
<p><b>Hello World!</b>
]PRE]
となり、更に
[PRE(HTML example code)[
<HTML><HEAD> <TITLE>Test Document</TITLE>
</HEAD><BODY><p><b>Hello World!</b>
</BODY></HTML>
]PRE]
と解釈されるなら、この文書片は[[妥当]]です。
また、
[PRE(HTML)[
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
[INS[...]]
<script type="text/javascript">
document.write ('<p>');
</script>
A paragraph.
[INS[...]]
]PRE]
は、果たして
[PRE(HTML)[
<p>
A paragraph?
</p>
]PRE]
でしょうか、
[PRE(HTML)[
<p></p>
A paragraph?
]PRE]
でしょうか。 (この例はどちらの解釈でも結果は[[妥当]]です。)
[4] '''スクリプト実行結果の静的妥当性検証''':
>>2-3 のような仕様の解釈に関する問題があるとはいえ、
ある解釈を選べば、ある文書がスクリプト実行後に DTD
妥当であるか否かはスクリプトを実際に実行してみれば容易に判断できます。
一方で、スクリプトを実行せずとも出力が妥当であるかどうかを検証できれば、
([CODE(JS)[document.write]] はもう使われなくなっていますが、
[[CGIスクリプト]]などにも応用できますから) 便利かもしれません。
実際にその方法を研究していた人もいたようですが、
良い方法は見つかっていません。
[5] '''スクリプト実行後の文書構造''':
現代の UA などは文書をその構造によって保持しています。 HTML
文書は読込まれると構文解析されて [[DOM]]
などのモデルによる木として記憶上で持っているか、
持っているかのように操作できるようになっています。
そうすると、 >>2 の規定を忠実に解釈すると、結果の文書木に
[CODE(HTMLe)[script]] 要素は含まれないことになってしまいます。
?? WinIE や Gecko はどうしている ??
また、 [CODE(JS)[document]] 物体は DOM の [CODE(DOMi)[[[Document]]]]
界面の物体 ([[文書要素]]に対応する物体) として再定義されてしまったので、
文書木が完成する前には存在しない虞があります (解析しながら木を作っているなら、
あるかもしれません)。
[6] [[内在事象取扱器]]で [CODE(JS)[document.write]] すると、
新しい文書が作られてそこに書かれるそうです [SRC[18.2.3 Note]]。
それもまたおかしな話です。
** DOM2 HTML
@@ TBW
[[#comment]]
** XHTML1 との関係
[8]
[CITE@ja[空繰再繰 - application/xhtml+xmlなページでdocument.writeを動作させる #2]] ([CODE[2007-05-01 11:21:43 +09:00]] 版) <http://nyarla.net/blog/javascript-tips6>
([[名無しさん]] [WEAK[2007-05-01 02:24:18 +00:00]])
[50] [CITE@ja[document.writeを完全にDOM仕様にする - 空繰再繰]] ([TIME[2009-01-10 14:15:20 +09:00]] 版) <http://blog.nyarla.net/2007/11/17/1>
** メモ
[7]
[CITE[d:id:quaa]] ([CODE[2006-11-28 10:39:05 +09:00]] 版) <http://d.hatena.ne.jp/quaa/20061227#p1>
([[名無しさん]] [WEAK[2006-12-28 01:52:17 +00:00]])
[11]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0Adocument.write%20('%3Cstyle%3E%20p%20%7Bcolor%3A%20green%20%7D%20%3C%2Fst')%3B%0A%3C%2Fscript%3Eyle%3E%0A%3Cp%3EPASS%20iff%20green%3C%2Fp%3E>
[[Firefox]] 2 も [[WinIE]] 7 も PASS。
[12]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0Adocument.write%20('%3Cstyle%3E%20p%20%7Bcolor%3A%20gr')%3B%0A%3C%2Fscript%3Eeen%20%7D%20%3C%2Fstyle%3E%0A%3Cp%3EPASS%20iff%20green%3C%2Fp%3E>
[[Firefox]] 2 も [[WinIE]] 7 も PASS。
[13]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cp%3EFAIL%3C%2Fp%3E%0A%3Cscript%20defer%3E%0A%20%20document.write%20('%3Cstyle%3Ep%20%7Bcolor%3A%20green%7D%3C%2Fstyle%3E')%3B%0A%3C%2Fscript%3E%0A%3Cscript%20defer%3E%0A%20%20document.write%20('%3Cp%3EPASS%20iff%20green%3C%2Fp%3E')%3B%0A%3C%2Fscript%3E%20%0A%3Cstyle%3E%0Ap%20%7B%20color%3A%20red%20%7D%0A%3C%2Fstyle%3E>
[[WinIE 7]] は DOM view はただしいが、なぜか Rendered view
には何もレンダリングされない。
[[Firefox]] 2 は FAIL ([CODE(HTMLa)@en[[[defer]]]] 未対応)。
[14]
>>13 の [[WinIE 7]] で[[レンダリング]]されないのは
[CODE(HTMLe)@en[[[script]]]] が2つあるかららしく、
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cp%3EFAIL%3C%2Fp%3E%0D%0A%3Cscript%20defer%3E%0D%0A%20%20document.write%20('%3Cstyle%3Ep%20%7Bcolor%3A%20green%7D%3C%2Fstyle%3E')%3B%0D%0A%20%20document.write%20('%3Cp%3EPASS%20iff%20green%3C%2Fp%3E')%3B%0D%0A%3C%2Fscript%3E%20%0D%0A%3Cstyle%3E%0D%0Ap%20%7B%20color%3A%20red%20%7D%0D%0A%3C%2Fstyle%3E>
なら[[レンダリング]]される。
[15]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cp%3EFAIL%3C%2Fp%3E%0D%0A%3Cscript%20defer%3E%0D%0A%20%20document.write%20('%3Cstyle%3Ep%20%7Bcolor%3A%20green%7D%3C%2Fstyle%3E')%3B%0D%0A%20%20document.write%20('%3Cp%3EPASS%20iff%20green%3C%2Fp%3E')%3B%0D%0A%3C%2Fscript%3E%20%0D%0A%3Cscript%3E%0D%0A%20%20document.write%20('%3Cstyle%3Ep%20%7B%20color%3A%20red%20%7D%3C%2Fstyle%3E')%3B%0D%0A%20%20document.write%20('%3Cp%3EFAIL%3C%2Fp%3E')%3B%0D%0A%3C%2Fscript%3E>
「CODE(JS)@円「「「document]].[[write]]]] というより
[CODE(HTMLa)@en[[[defer]]]] のテスト。
[[WinIE 7]] は PASS。
後の [CODE(HTMLe)@en[[[script]]]] 内に 「CODE(DOMm)@en[[[alert]]()]] を入れれば、
ちゃんと後の [CODE(HTMLe)@en[[[script]]]] も実行されていることが確認できる。
[16]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.write%20('%3Cscript%3E%20document.write%20(%22aa%22)%3B%20%3C%2Fsc')%3B%0A%20%20document.write%20('ript%3E')%3B%0A%3C%2Fscript%3E>
[[Firefox]] 2 でも [[WinIE 7]] でも、 [CODE(HTMLe)@en[[[script]]]]
内の [CODE(HTMLe)@en[[[script]]]] が実行され、[Q[aa]] と[[レンダリング」」されます。]]
[[HTML 5]] の[[構文解析算法]]でも、ややこしいですがおそらく、
[Q[aa]] と「「レンダリング]]されるのが正しい動作です。
(1つ目の [CODE(JS)@en[[[[document]].[[write]]]]
によって行われる[[構文解析]]で、与えられた「「引数]]の末尾に到達したところで、
[[挿入点]]に到着したということで[[字句化器]]が停止します。
[[木構築段階]]は [CODE(HTMLe)@en[[[script]]]]
[[開始タグ]]が現れると[[文字字句]]を集め続けますが、
それは[[字句化器]]が停止したところで一旦終わるので、
[CODE(HTMLe)@en[</[[script]]]] [[終了タグ」」の直前までいきます。ここで、 [CODE(JS)@en[[[document]].[[write]]]] は[[返る]]のですが、]]
それによって外側の[[構文解析]]が再開されます。そして、
次の[[字句]]が [CODE(HTMLe)@en[[[script]]]] の[[終了タグ]]になるので、
[[木構築段階]]の [CODE(HTMLe)@en[[[script]]]] [[開始タグ]]の処理の続きで、[[スクリプト]]が実行されます。)
[17]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.write%20('%3Cstyle%3E%20p%20%7B')%3B%0Aw(document.documentElement.innerHTML)%3B%0A%20%20document.write%20('color%3A%20gree')%3B%0Aw(document.documentElement.innerHTML)%3B%20%0A%20%20document.write%20('n%20%7D')%3B%0A%3C%2Fscript%3E%3C%2Fstyle%3E%3Cp%3Exxxx>
[[WinIE 7]] でも [[Firefox]] 2 でも、緑の[Q[xxxx]]が[[レンダリング]]されます。
[19]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.write%20('%3Cstyle%3E')%3B%0Aw%20(document.documentElement.innerHTML)%3B%0A%20%20document.write%20('color%3A%20gree')%3B%0Aw%20(document.documentElement.innerHTML)%3B%20%0A%20%20document.write%20('n%20%7D')%3B%0A%3C%2Fscript%3E%3C%2Fstyle%3E%3Cp%3Exxxx%0A%3Cscript%3E%0Aw%20(document.documentElement.innerHTML)%3B%20%0A%3C%2Fscript%3E%0A%3Cpre%3E%0Axxxx>
[CODE(JS)@en[[[document]].[[write]]]] による追加分が [[DOM]] [[木]]に反映されるのはいつか?
(ここでは [CODE(DOMa)@en[[[innerHTML]]]] を使用。)
- 通常の[[要素]]なら、直前の [CODE(JS)@en[[[document]].[[write]]]]
で与えられたものすべてが既に反映済み
- [CODE(HTMLe)@en[[[style]]]] [[要素]]の場合、
-- [[WinIE 7]] では [CODE(HTMLe)@en[[[style]]]] [[要素]]自体は追加されるが、
その[[内容]]は[[終了タグ]]を処理するまで[[空]]のまま
-- [[Firefox]] 2 では[[終了タグ]]が処理されるまで
[CODE(HTMLe)@en[[[style]]]] [[要素]]自体が追加されない
([[名無しさん]])
[20]
>>19 [[WinIE 7]] で [CODE(HTMLe)@en[[[style]]]]
[[要素]]の [CODE(DOMa)@en[[[sheet]]]]
[[属性]]は [CODE(DOM)@en[[[null]]]] になっているようです。
([[名無しさん]])
[21]
>>20 訂正: [CODE(DOMa)@en[[[styleSheet]]]] [[属性]]。
([[名無しさん]])
[22]
>>19 [[Opera]] 9.27、[[Safari]] 3.1.1 では、
[[WinIE 7]] 同様、[[終了タグ]]を処理するまでは空のままのようです。
[CODE(DOMa)@en[[[sheet]]]] [[属性]]は空の[[スタイル・シート]]になっているようです。
([[名無しさん]])
[23]
>>22 [CODE(DOMa)@en[[[sheet]]]] [[属性]]の指す[[スタイル・シート]]は[[終了タグ]]が処理されるまでずっと空のままのようです。
;; <http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0D%0A%20%20document.write%20('%3Cstyle%3E')%3B%0D%0A%20%20document.write%20('p%20%7B%20color%3A%20green%20%7D')%3B%0D%0A%20%20w%20(document.getElementsByTagName%20('style')%5B0%5D.sheet.cssRules.length)%3B%0D%0A%3C%2Fscript%3E%3C%2Fstyle%3E>
([[名無しさん]])
[24]
[CODE(JS)@en[[[document]].[[write]] ('<pre>\na</pre>')]]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0D%0A%20%20document.write%20('%3Cpre%3E%5Cna%3C%2Fpre%3E')%3B%0D%0A%3C%2Fscript%3E>
[[WinIE 7]], [[Firefox]] 2, [[Opera]] 9.27, [[Safari]] 3.1.1 のいずれも、
[[開始タグ]]直後の[[改行]]を無視。
([[名無しさん]])
[25]
[CODE(JS)@en[[[document]].[[write]] ('<pre>'); [[document]].[[write]] ('\na</pre>')]]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.write%20('%3Cpre%3E')%3B%0A%20%20document.write%20('%5Cna%3C%2Fpre%3E')%3B%0A%3C%2Fscript%3E>
>>24 の4ブラウザ中、[[Firefox]] 2 だけは[[改行]]を無視''せず''。
([[名無しさん]])
[26]
[CODE(JS)@en[[[document]].[[write]] ('<pre>', '\na</pre>');]]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.write%20('%3Cpre%3E'%2C%20'%5Cna%3C%2Fpre%3E')%3B%0A%3C%2Fscript%3E>
これなら [[Firefox]] 2 も[[改行]]を無視する。
([[名無しさん]])
[27]
[CODE(JS)@en[[[document]].[[writeln]] ('<pre>'); [[document]].[[write]] ('a</pre>');]]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.writeln%20('%3Cpre%3E')%3B%0A%20%20document.write%20('a%3C%2Fpre%3E')%3B%0A%3C%2Fscript%3E>
だけどこっちは [[Firefox]] 2 が[[改行]]を[[無視]]しない。
([[名無しさん]])
[28]
[[Opera]] 9.27 と [[Safari]] 3.1.1 の結果
>>11、>>12 PASS
>>13、>>15 FAIL ([CODE(HTMLa)@en[[[defer]]]] 未対応)
>>16 同じ (実行される)
([[名無しさん]])
[29]
>>19 みたいなことを [CODE(HTMLe)@en[[[script]]]]
[[要素]]を書き出す場合でやってみた
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0Aw%20(document.documentElement.innerHTML)%3B%0A%20%20document.write%20('%3Cscript%3E%20document.')%3B%0Aw%20(document.documentElement.innerHTML)%3B%0A%20%20document.write%20('write%20(%22a%22)%3B%20%3C%2F'%20%2B%20'script%3E')%3B%0Aw%20(document.documentElement.innerHTML)%3B%0A%3C%2Fscript%3E>
4ブラウザとも、 [CODE(HTMLe)@en[[[script]]]] [[要素]]が
[CODE(DOMa)@en[[[innerHTML]]]] に現れるのは[[終了タグ]]が処理されたあとのようです。
この例だと [[Safari]] だけは3番目の [CODE[w]] で生成された
[CODE(HTMLe)@en[[[script]]]] [[要素]]によって書き込まれた
[CODE[a]] が反映されていないのですが、
これはその [CODE(HTMLe)@en[[[script]]]] [[要素]]が実行されていないわけではなく、
[[文字データ]]を書いても次の[[タグ]]などが現れるまで
[[DOM]] に追加されないという ([[Safari]] だけの) 動作のためのようです。
([[名無しさん]])
[30]
>>29
書き出される [CODE(HTMLe)@en[[[script]]]] [[要素]]が実行される時点での
[CODE(DOMa)@en[[[innerHTML]]]] は?
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0D%0A%20%20document.write%20('%3Cscript%3E%20w%20(document.documentElement.innerHTML)%3B%20document.')%3B%0D%0A%20%20document.write%20('write%20(%22a%22)%3B%20%3C%2F'%20%2B%20'script%3E')%3B%0D%0A%3C%2Fscript%3E>
書き出された [CODE(HTMLe)@en[[[script]]]] [[要素]]が [[DOM]]
に追加された状態の [CODE(DOMa)@en[[[innerHTML]]]] が出てくるようです。
([[名無しさん]])
[31]
>>30 は4ブラウザとも。
([[名無しさん]])
[32]
[CODE(HTMLe)@en[[[script]]]] の途中からが外側の
[CODE(HTMLe)@en[[[script]]]] [[要素]]の後にいっていてもよいのか?
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.write%20('%3Cscript%3E%20w%20(document.documentElement.innerHTML)%3B%20document.')%3B%0A%20%20document.write%20('write%20(%22a')%3B%0A%3C%2Fscript%3E%22)%3B%20%3C%2Fscript%3E>
4ブラウザともおk ([CODE(HTMLe)@en[[[script]]]]
[[要素]]の続きとみなす) のようです。
([[名無しさん]])
[33]
わけがわからないくらい複雑な例 with [CODE(HTMLe)@en[[[script]]]] [CODE(HTMLa)@en[[[src]]]]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%20src%3D%22javascript%3A'%20document.write%20(%26quot%3Baaaaa%26quot%3B)%3B%20'%22%3E%3C%2Fscript%3E%0A%3Cscript%3E%0A%20%20document.write%20(%22%3Cscript%3Edocument.write%20('%3Cscript%20src%3Djavascript%3A%26apos%3Bdocument.write(%26quot%3Baaaaa%26quot%3B)%3B%26apos%3B%3E%3C%2F'%2C%20'script%3E%3Cscript%3E%20document.wri')%3B%3C%2F%22%2C%20%22script%3E%22)%3B%0A%3C%2Fscript%3Ete%20('ccc')%3B%20%3C%2Fscript%3E>
[[Firefox]] 2 では、最初の
[CODE(HTMLe)@en[[[script]]]] [[要素]]があるかないか
([CODE(URI)@en[[[javascript]]:]] [[URI]] を使っていることに起因している模様)、
[[Live DOM Viewer]] 内で見るかどうか、
[[Live DOM Viewer]] でも直接入力か permalink 使用かによって結果が変わってくる
(2つ目の [CODE(HTMLe)@en[[[script]]]] による書き込みが反映されたりされなかったりする、というか [CODE(HTMLe)@en[[[script]]]] が [[DOM]]
に現れなかったり、 [CODE(HTMLe)@en[[[body]]]] が2つでてきたり、よくわからん。) ようです。
;; [[Live DOM Viewer]] かどうかで結果が変わるのは、
[[Live DOM Viewer]] 自体が [CODE(JS)@en[[[document]].[[write]]]] を使っているせいでしょう。
([[名無しさん]])
[34]
>>33 他の3ブラウザはいずれも [Q[ccc]] とだけでてきます。
[[Safari]] と [[WinIE]] は、
[CODE(HTMLa)@en[[[src]]]] 内の [CODE(URI)@en[[[javascript]]:]]
[[URI]] を実行していないようです。 [[Opera]] は外部スクリプト内の
[CODE(JS)@en[[[document]].[[write]]]] を実行していないようです。
([[名無しさん]])
[35]
>>34 [[Opera]] は [CODE(JS)@en[[[document]].[[write]]]] を実行しないのではなく、
[CODE(HTMLa)@en[[[javascript]]:]] [[URI]] を実行はするのですが、
最後に得られた[[文字列]]を外部スクリプトとみなすのではないようで、
[[エラーコンソール]]に
[Q[リンク先のスクリプトを読み込むことができません]]とでてきます。
([[名無しさん]])
[36]
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%20src%3D%22javascript%3A%20document.write%20('x')%3B%20%22%3E%3C%2Fscript%3E%20%20%20>
[[Opera]] では [Q[x]] が [CODE(HTMLe)@en[[[body]]]] [[要素]]中にでてきます。
[[Firefox]] の [CODE(HTMLa)@en[[[src]]]] 内の [CODE(URI)@en[[[javascripot]]:]]
[[URI]] の実行される文脈では文書本体の [CODE(JS)@en[[[Global]]]]
[[物体]]とは違うものを使っているようで、
[CODE(JS)@en[[[window]]]] にも [CODE(JS)@en[[[document]]]]
にもその他[[大域変数]]にもアクセスできません
([CODE(JS)@en[[[ReferenceError]]]] になります)。
([[名無しさん]])
[37]
[CITE@en[Hixie's Natural Log: Tag Soup: Blocks-in-inlines]] ([CODE[2008-04-25 22:46:42 +09:00]] 版) <http://ln.hixie.ch/?start=1138169545&count=1>
([[名無しさん]])
[38]
[CITE@en[Hixie's Natural Log: Why document.write() doesn't work in XML]] ([CODE[2008-04-25 22:48:57 +09:00]] 版) <http://ln.hixie.ch/?start=1091626816&count=1>
([[名無しさん]])
[39]
[CITE@en[Hixie's Natural Log: Tag Soup: appendChild() of a script that calls document.write()]] ([CODE[2008-04-25 22:49:24 +09:00]] 版) <http://ln.hixie.ch/?start=1155195074&count=1>
([[名無しさん]])
[40]
[CITE[Index of /tests/adhoc/dom/level0/write]] ([CODE[2008-04-25 23:07:32 +09:00]] 版) <http://hixie.ch/tests/adhoc/dom/level0/write/>
([[名無しさん]])
[41]
んー、カオス。
([[名無しさん]])
[42]
[CODE(JS)@en[[[document]].[[write]]]] で始まった
[CODE@en[[[CDATA]]]] [[内容モデル旗]]とその[[スクリプト]]の[[終了タグ]]の関係は?
<http://software.hixie.ch/utilities/js/live-dom-viewer/?%3Cscript%3E%0A%20%20document.write%20(%22%3Cstyle%3E%20p%20%7B%22)%3B%0A%20%20w%20(document.documentElement.innerHTML)%3B%0A%3C%2Fscript%3E%20color%3A%20green%3B%0A%3Cscript%3E%0A%20%20document.write%20('%7D%20%3C%2Fstyle%3E')%3B%0A%3C%2Fscript%3E%3Cp%3Exxxx%0A>
4ブラウザとも、[CODE(HTML)@en[</[[script]]>]] 以後も[[内容モデル旗]]は
[CODE@en[[[CDATA]]]] にしたまま処理を続行するようで、
次の [CODE(HTML)@en[<[[script]]>]] [[開始タグ]]は[[開始タグ]]ではなく、
[[文字データ]]として処理します。
([[名無しさん]])
[43]
[CITE@en[Live Scripting HTML Parser]] ([CODE[2008-04-27 20:27:04 +09:00]] 版) <http://suika.fam.cx/www/markup/html/scripting-parser/parser>
([[名無しさん]])
[44]
[CITE[Bug 95487 – JavaScript-generated table never completes]] ([CODE[2008-06-18 09:05:55 +09:00]] 版) <https://bugzilla.mozilla.org/show_bug.cgi?id=95487>
([[名無しさん]])
[45]
[CITE@ja[document.write()の実行タイミングをずらす方法]] ([CODE[2008-06-22 15:16:43 +09:00]] 版) <http://p2b.jp/index.php?UID=1153728573>
([[名無しさん]])
[46]
[CITE[最速インターフェース研究会 :: ページレンダリングを妨げないdocument.writeの実装]] ([CODE[2008-06-22 15:21:04 +09:00]] 版) <http://la.ma.la/blog/diary_200612061928.htm>
([[名無しさん]])
[47]
[CITE[Fenrir's BLog: Ajaxでdocument.writeするJavaScriptへの対策]] ([CODE[2008-06-02 14:24:53 +09:00]] 版) <http://fenrir.naruoka.org/archives/000555.html>
([[名無しさん]])
[48]
[CITE@ja-JP[野ログはノロキュアMaxHeart - document.writeをバッファリングするJavaScript]] ([[nog]] 著, [CODE[2008-04-18 09:41:41 +09:00]] 版) <http://cureblack.com/20080418.html#p01>
([[名無しさん]])
[49]
[CITE[Javascriptの外部ファイル内でdocument.writeしたら文字化け(Mac IE 4.5編)]] ([TIME[2007-02-19 06:57:31 +09:00]] 版) <http://www.shtml.jp/mojibake/macie45.html>
[51] [CITE@en[Web Applications 1.0 r5616 Change how document.write() is ignored.Fixing http://www.w3.org/Bugs/Public/show_bug.cgi?id=9767]]
( ([TIME[2010-10-13 06:20:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=5615&to=5616>
[52] [CITE[IRC logs: freenode / #whatwg / 20101013]]
( ([TIME[2010-10-23 23:42:03 +09:00]] 版))
<http://krijnhoetmer.nl/irc-logs/whatwg/20101013>
[53] [CITE@en[Web Applications 1.0 r6924 More tweaks to the text (including a comment that describes one of the situations in question).Fixing https://www.w3.org/Bugs/Public/show_bug.cgi?id=14275]]
( ([TIME[2012-01-27 09:30:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=6923&to=6924>
[54] [CITE[''''''[''''''whatwg'''''']'''''' HTMLLinkElement.disabled and HTMLLinkElement.sheet behavior]]
( ([TIME[2012-08-28 04:46:43 +09:00]] 版))
<http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2012-August/037001.html>
[55] [CITE@en[Web Applications 1.0 r7290 Change how <script> is handled in re-entrant parser situations when there's a blocking style sheet.]]
( ([TIME[2012-08-28 13:48:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=7289&to=7290>
[56] [CITE@en[Web Applications 1.0 r7757 Try to define when document.open() doesn't work more precisely.]]
( ([TIME[2013-03-16 07:41:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=7756&to=7757>
[57] [CITE@en[Web Applications 1.0 r7869 Make document.write() a no-op on non-active documents.]]
( ([TIME[2013-05-29 05:47:00 +09:00]] 版))
<http://html5.org/tools/web-apps-tracker?from=7868&to=7869>
[FIG[
[FIGCAPTION[
[58]
[CITE[新暦と旧暦の変換計算(長期)]] ([TIME[2006-05-28 08:57:13 +09:00]] 版) <http://koyomi8.com/9reki/9rekicgi.htm>
;; [59] [CODE(HTMLa)@en[[[action]]]] を可変にするために [CODE(JS)@en[[[document.write]]]]
が使われています。なお[[終了タグ]]は直接 [[HTML]] として記述されています。
]FIGCAPTION]
[PRE(HTML code)[
<SCRIPT Language="JavaScript">
<!--
document.writeln('<form NAME="9reki" method="POST" action="' + CGISERVER + 'cgi/9reki_f.cgi">');
// -->
</SCRIPT>
]PRE]
]FIG]
[60] [CITE@en[bug 5562 – 無限にdocument.write()を繰り返してメモリを食いつぶしていくと再パース処理でクラッシュする]]
( ([TIME[2014-12-19 18:15:57 +09:00]] 版))
<http://bugzilla.mozilla.gr.jp/show_bug.cgi?id=5562>
[61] [CITE@en[430574 – Infinite document.write() loop hangs, fills memory, and crashes]]
( ([TIME[2014-12-19 18:16:32 +09:00]] 版))
<https://bugzilla.mozilla.org/show_bug.cgi?id=430574>
[80] [CITE[IRC logs: freenode / #whatwg / 20150528]]
([TIME[2015-05-29 16:21:13 +09:00]] 版)
<http://krijnhoetmer.nl/irc-logs/whatwg/20150528>
[81] [CITE@en[Formalize custom element reactions · whatwg/html@27aa7bc]]
([TIME[2016-04-26 18:51:55 +09:00]] 版)
<https://github.com/whatwg/html/commit/27aa7bc4fa6f168654a8c858f0773e611f679b39>
[FIG(amazon)[
JavaScript
]FIG]
[85] [CITE@en[Clarify the note about reentrant parsing in document.write()]]
([[domenic]]著, [TIME[2016-08-15 17:30:21 +09:00]])
<https://github.com/whatwg/html/commit/d6630fe808e48898108dc671025c0bcad5048cc3>
[86] [CITE@en[Make document.write etc. throw during parsing custom elements]]
([[domenic]]著, [TIME[2016-08-17 15:44:39 +09:00]])
<https://github.com/whatwg/html/commit/00c6fa07bdb9f0d08a28f6c6e1ababca7d08618c>
[87] [CITE@en[Make document.write etc. throw during parsing custom elements]]
([[domenic]]著, [TIME[2016-08-17 15:44:39 +09:00]])
<https://github.com/whatwg/html/commit/00c6fa07bdb9f0d08a28f6c6e1ababca7d08618c>
[94] [CITE@en[For users on very slow connections, block document.written scripts · Issue #17 · WICG/interventions]]
([TIME[2016-10-25 13:13:39 +09:00]])
<https://github.com/WICG/interventions/issues/17>
[95] [CITE@en[Editorial: refactor document.open()/write()/writeln()]]
([[annevk]]著, [TIME[2017-05-16 14:12:59 +09:00]])
<https://github.com/whatwg/html/commit/d43b7050b4fe83ebce7724ea005e4707f06a86f7>