質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

2回答

1646閲覧

JavaScript得意な方教えて下さい!スコープについて

js_benkyou_now

総合スコア6

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2018/01/27 09:03

編集2022/01/12 10:55

プログラミングでjavascriptを勉強していて理解できているようなできていないような感じで困っています。

例えば以下の様なコードがあったとします

HTML

(略) <body id ="test"> (略)

JavaScript

const _d = document; const Hoge = function(){ (略) alert(_d.~); //アクセスできてdocumentオブジェクトのメソッドが使える (略) } Hoge.prototype = { testdesuyo : function(){ alert(_d.URL); //ここもdocumentオブジェクトのメソッドが使える _d.getElementById("test").insertAdjacentHTML('afterbegin', '<p>testes</p>'); //何故かinsertAdjacentHTMLが使えない     //insertAdjacentHTMLなんてないよとGoogleChromeのコンソールが言ってくる // ↑これが何故か分からない } }; 以下略

スコープの問題かな(?)と思いましたが、ドキュメントにも普通にアクセスできているようですし、
insertAdjacentHTMLの仕様かな(?)とも思い、MDNの仕様ページを見ましたが全てのエレメントで使えるようなのでそれもない

となると何がなんだか訳が分かりません

上級者の方教えて下さい

=========================================================================

追記

実行してみたソースとその時に出てきたコンソールのログです

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8" /> <script> const _d = document; const Hoge = function () { alert("実験成功 : 最終更新日時は" + _d.lastModified); } Hoge.prototype = { testdesuyo: function () { alert("実験成功 : 最終更新日時は" + _d.lastModified); _d.getElementById("test").insertAdjacentHTML('afterbegin', '<p>testes</p>'); } }; let hoge = new Hoge(); hoge.testdesuyo(); </script> </head> <body id="test"> </body> </html>

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lhankor_Mhy

2018/01/27 09:12

試してみましたが、問題なく動作しました。もしかして、id="test" の要素がないとか?
namnium1125

2018/01/27 09:14

loadイベントの後でもエラーになるのでしょうか?追記いただけると幸いです。
js_benkyou_now

2018/01/27 09:17

お早いご回答ありがとうございます! id="test"の要素はあります loadした後でのエラーです 宜しくお願いします
Lhankor_Mhy

2018/01/27 09:25

それでは、問題なく動作しました。環境の問題か、ここに書かれていないコードの問題かと思います。
jun68ykt

2018/01/27 09:28

HTMLとJSを追加して、https://jsfiddle.net/f87t0r1z/1/ を作りましたが、Mac用Chrome v.63 では「insertAdjacentHTMLなんてないよ」のエラーはconsoleに出ませんでした。
js_benkyou_now

2018/01/27 09:54

ご回答ありがとうございます ご指摘を受けて、実行したソースを載せたのせましたので宜しくお願いします
Lhankor_Mhy

2018/01/27 10:01

namnium1125 さんのご推測が正しかったようですね。
guest

回答2

0

こんにちは。

追記で掲載されたソースですと、 <body id="test"></body> が解析されてDOMに展開される前に
<script>・・・</script> タグの中にある JSが評価されるので、
_d.getElementById("test")null になるものと思われます。
つまり、 id が "test" のDOM要素がまだ生成されていないうちに、 <script>の中のJSが
実行されてしまっているのです。

MDNでの DOMContentLoaded の説明にも

註: 同期的に実行される Javascript は DOM の解析を一時停止させます。

との注記が書かれています。
これについては、以下の mamo@Qiita さんの記事が周辺情報ふくめ、分かりやすいです。

ご質問のコードに戻りますと、とりあえずの対応として、<script>・・・</script>
</body>(bodyの閉じタグ) の直後あたりに移動すると、
ご質問にあるエラーは出なくなると思います。

以上参考になれば幸いです。


追記

1.修正案

上記に書いた、「とりあえずの対応」ではなく、当該のHTMLに書かれているDOMの生成が
完了してから、 <script>の中を実行するという意図の明確なコードを書くのであれば、
以下のように、DOMContentLoaded イベントのハンドラとして実行するよう修正すればよいと思います。

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="utf-8" /> 5 <script> 6 document.addEventListener("DOMContentLoaded", function(event) { 7 const _d = document; 8 9 const Hoge = function () { 10 alert("実験成功 : 最終更新日時は" + _d.lastModified); 11 } 12 13 Hoge.prototype = { 14 testdesuyo: function () { 15 alert("実験成功 : 最終更新日時は" + _d.lastModified); 16 _d.getElementById("test").insertAdjacentHTML('afterbegin', '<p>testes</p>'); 17 } 18 }; 19 20 let hoge = new Hoge(); 21 hoge.testdesuyo(); 22 }); 23 </script> 24</head> 25<body id="test"> 26</body> 27</html>

 
2.参考図書

蛇足ですが、DOMの生成と script が実行される順番を把握して最適化するという趣旨だと、
以下の本

超速! Webページ速度改善ガイド

のレンダリングの章が詳しいです。

投稿2018/01/27 10:14

編集2018/01/27 14:49
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

x_x

2018/01/29 02:36

直後ではなく、直前かと
guest

0

できました。
以下のものをそのまま試してみてください。
もしこれができるなら問題は別のところにあります。

HTML

1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="utf-8" /> 6 <title>試作</title> 7</head> 8 9<body id="test"> 10 <p>Hello World</p> 11 <script> 12 const _d = document; 13 14 const Hoge = function () { 15 alert(_d.getElementById("test").innerText); 16 } 17 18 Hoge.prototype = { 19 testdesuyo: function () { 20 alert(_d.URL); 21 _d.getElementById("test").insertAdjacentHTML('afterbegin', '<p>testes</p>'); 22 } 23 }; 24 25 var hoge = new Hoge(); 26 hoge.testdesuyo(); 27 </script> 28</body> 29 30</html>

なお [JavaScript] prototypeに直接代入しちゃうのってダメじゃなかったっけ?

追記

このようにしたらできました。
スクリプトが実行される時点でまだ body が読み込まれていなかったからでしょう。
なお、上記リンクを読んでおいてください。

JavaScript

1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="utf-8" /> 6 <title>試行</title> 7</head> 8 9<body id="test"> 10 <script> 11 const _d = document; 12 13 const Hoge = function () { 14 alert("実験成功 : 最終更新日時は" + _d.lastModified); 15 } 16 17 Hoge.prototype = { 18 testdesuyo: function () { 19 alert("実験成功 : 最終更新日時は" + _d.lastModified); 20 _d.getElementById("test").insertAdjacentHTML('afterbegin', '<p>testes</p>'); 21 } 22 }; 23 24 let hoge = new Hoge(); 25 hoge.testdesuyo(); 26 </script> 27</body> 28 29</html>

投稿2018/01/27 09:35

編集2018/01/27 10:03
Zuishin

総合スコア28656

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2018/01/27 09:39

質問をするときには適当なところを適当に略すのではなく、このように誰でも同じ条件で試せる完全かつ最小のソースを作ってください。
Zuishin

2018/01/27 09:40

そうでないと、略したところをこちらで補わなければなりません。 つまり、問題のある場所が問題のないコードで上書きされるということです。
js_benkyou_now

2018/01/27 09:53

ご指摘ありがとうございます 申し訳ないです 追記で実行したソースを載せましたので宜しくお願いします
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問