<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>readyState &#8211; Mach3.laBlog</title>
	<atom:link href="https://blog.mach3.jp/tag/readystate/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.mach3.jp</link>
	<description></description>
	<lastBuildDate>Tue, 17 Dec 2013 01:25:37 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>
	<item>
		<title>&#034;readyState&#034; &#8211; Alphabetical Advent Calendar 2013</title>
		<link>https://blog.mach3.jp/2013/12/17/jaac2013-r-readystate.html</link>
		
		<dc:creator><![CDATA[mach3]]></dc:creator>
		<pubDate>Tue, 17 Dec 2013 01:25:37 +0000</pubDate>
				<category><![CDATA[Laboratory]]></category>
		<category><![CDATA[Advent Calendar 2013]]></category>
		<category><![CDATA[async]]></category>
		<category><![CDATA[DOMContentLoaded]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[readyState]]></category>
		<guid isPermaLink="false">http://blog.mach3.jp/?p=3749</guid>

					<description><![CDATA[&#8220;R&#8221; は readyState の &#8220;R&#8221;。 readyState document.readyState は、HTMLのダウンロード・パース状況を取得できるAPIです。 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>&#8220;R&#8221; は readyState の &#8220;R&#8221;。</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh5.googleusercontent.com/-gbMxSuEuhoc/UqR4k8DxMOI/AAAAAAAACYg/j4SKZcO5ldo/s400/ac2013-r.png" alt="R"/></figure>



<p></p>



<span id="more-3749"></span>



<h2 class="wp-block-heading">readyState</h2>



<p><strong>document.readyState</strong> は、HTMLのダウンロード・パース状況を取得できるAPIです。 値は &#8220;loading&#8221; / &#8220;interactive&#8221; / &#8220;complete&#8221; などが返され、 それぞれ以下のような状態を表します。</p>



<ul class="wp-block-list">
<li>loading: ダウンロード中</li>



<li>interactive: HTMLのダウンロードとパースが完了</li>



<li>complete: サブリソースのダウンロードが完了</li>
</ul>



<p>また、readyState の状態が移り変わる毎に、<strong>readystatechange</strong> イベントが発火されます。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">"readystatechange"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">document</span>.readyState); <span class="hljs-comment">// "loading", "interactive", "complete" など</span>
}, <span class="hljs-literal">false</span>);
</code></span></pre>


<h3 class="wp-block-heading">DOMContentLoaded</h3>



<p>readystatechange と似た働きをもつ物に <strong>DOMContentLoaded</strong> イベントがありますが、 DOMContentLoaded をサポートしていないブラウザ、例えばIE8以下向けのフォールバックとして readystatechange が使用されたりします。</p>



<p>ごくシンプルに書くと、このような処理をする事になります。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">var</span> initialize = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"ready"</span>);
    <span class="hljs-comment">// アプリケーションの初期化...</span>
};

<span class="hljs-keyword">var</span> domReadyHandler = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>)</span>{
    <span class="hljs-keyword">if</span>(e.type === <span class="hljs-string">"DOMContentLoaded"</span>){
        <span class="hljs-built_in">document</span>.removeEventListener(<span class="hljs-string">"DOMContentLoaded"</span>, domReadyHandler);
    } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">if</span>(<span class="hljs-built_in">document</span>.readyState !== <span class="hljs-string">"complete"</span>){ <span class="hljs-keyword">return</span>; }
        <span class="hljs-built_in">document</span>.detachEvent(<span class="hljs-string">"onreadystatechange"</span>, domReadyHandler);
        <span class="hljs-built_in">window</span>.detachEvent(<span class="hljs-string">"onload"</span>, domReadyHandler);
    }
    initialize();
};

<span class="hljs-keyword">if</span>(<span class="hljs-string">"addEventListener"</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">document</span>){
    <span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">"DOMContentLoaded"</span>, domReadyHandler, <span class="hljs-literal">false</span>);
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(<span class="hljs-string">"attachEvent"</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">document</span>){
    <span class="hljs-built_in">document</span>.attachEvent(<span class="hljs-string">"onreadystatechange"</span>, domReadyHandler);
    <span class="hljs-built_in">window</span>.attachEvent(<span class="hljs-string">"onload"</span>, domReadyHandler);
}
</code></span></pre>


<p>DOMContentLoaded の代替として readystatechange の &#8220;complete&#8221; のタイミングで処理を行います。 環境の判別に &#8220;addEventListener&#8221; の有無を使用していますが、 これはたまたま DOMContentLoaded のサポート環境と被っていた為です。 （DOMContentLoaded は document.ondomcontentloaded として参照できない為、イベントのサポートの有無で判別しようとすると冗長になってしまいます）</p>



<p>フレーム内コンテンツなどを考慮するとさらに長いコードになりますが、 下記リンクにて詳細に説明されています。</p>



<ul class="wp-block-list">
<li><a href="https://github.com/addyosmani/jquery.parts/blob/master/jquery.documentReady.js">https://github.com/addyosmani/jquery.parts/blob/master/jquery.documentReady.js</a></li>
</ul>



<h2 class="wp-block-heading">document 以外での readyState</h2>



<p>IE10以下に限っては document 以外にも、img要素やscript要素で readyState が使えます。 従来のIEでは script 要素の onload イベントが使用出来なかった為、 スクリプトローダー等ではこれをフォールバックとして使用していたりします。</p>



<p>例えば、複数のスクリプトを動的・同期的に読み込んで実行したいケースでは、 script 要素の async を false にすれば想定する動きをしてくれます。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script">https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script</a></strong><br />
  Set this Boolean attribute to indicate that the browser should, if possible, execute the script asynchronously&#8230;</p>
</blockquote>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">var</span> loadSync = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">resources</span>)</span>{
    resources.forEach(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">name</span>)</span>{
        <span class="hljs-keyword">var</span> script = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"script"</span>);
        script.async = <span class="hljs-literal">false</span>;
        script.src = name;
        <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">"head"</span>)&#91;<span class="hljs-number">0</span>].appendChild(script);
    });
};

loadSync(&#91;<span class="hljs-string">"jquery.js"</span>, <span class="hljs-string">"underscore.js"</span>, <span class="hljs-string">"backbone.js"</span>, <span class="hljs-string">"main.js"</span>]);
</code></span></pre>


<p>しかし async 属性はIE8以下ではサポートされていない為、 readystatechange イベントでスクリプトのロード状況を監視し、 読み込みが完了した時点でDOMに挿入する事で再現してみます。</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-comment">// async がサポートしているかを確認</span>
<span class="hljs-keyword">var</span> supportAsync = <span class="hljs-string">"async"</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"script"</span>);

<span class="hljs-keyword">var</span> loadSync = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">resources</span>)</span>{
    <span class="hljs-keyword">var</span> nodes = &#91;];
    <span class="hljs-keyword">var</span> count = resources.length;
    <span class="hljs-keyword">var</span> head = <span class="hljs-built_in">document</span>.getElementsByTagName(<span class="hljs-string">"head"</span>)&#91;<span class="hljs-number">0</span>];

    <span class="hljs-keyword">var</span> process = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{
        <span class="hljs-keyword">if</span>(<span class="hljs-keyword">this</span>.readyState === <span class="hljs-string">"loaded"</span>){ count--; }
        <span class="hljs-keyword">if</span>(! count){
            nodes.forEach(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">node</span>)</span>{
                node.onreadystatechange = <span class="hljs-literal">null</span>;
                head.appendChild(node);
            });
        }
    };

    <span class="hljs-keyword">var</span> createNode = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">src</span>)</span>{
        <span class="hljs-keyword">var</span> node = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"script"</span>);
        <span class="hljs-keyword">if</span>(supportAsync){
            node.async = <span class="hljs-literal">false</span>;
            node.src = src;
            head.appendChild(node);
        } <span class="hljs-keyword">else</span> {
            node.onreadystatechange = process;
            node.src = src;
        }
        <span class="hljs-keyword">return</span> node;
    };

    <span class="hljs-comment">// forEach が polyfill で定義されている前提</span>
    resources.forEach(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">name</span>)</span>{
        nodes.push(createNode(name));
    });
};

loadSync(&#91;<span class="hljs-string">"jquery.js"</span>, <span class="hljs-string">"underscore.js"</span>, <span class="hljs-string">"backbone.js"</span>, <span class="hljs-string">"main.js"</span>]);
</code></span></pre>


<p>IE11からは script要素の readyState は使えなくなり、load イベントの使用が推奨されています。</p>



<h2 class="wp-block-heading">参考資料</h2>



<ul class="wp-block-list">
<li><a href="https://developer.mozilla.org/ja/docs/DOM/document.readyState">document.readyState &#8211; DOM | MDN</a></li>



<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script">script &#8211; HTML | MDN</a></li>



<li><a href="http://msdn.microsoft.com/en-us/library/ie/ms534359(v=vs.85).aspx">readyState property (Internet Explorer)</a></li>



<li><a href="http://msdn.microsoft.com/en-us/library/ie/bg182625(v=vs.85).aspx">Compatibility changes in IE11 (Windows)</a></li>



<li><a href="https://github.com/addyosmani/jquery.parts/blob/master/jquery.documentReady.js">jquery.parts/jquery.documentReady.js at master · addyosmani/jquery.parts</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
