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

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

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

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

2回答

954閲覧

jsからhtmlにscriptタグを書き込む方法でremodalとdatatablesを読み込みたいが、うまくいかない

rsrsrs

総合スコア1

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

1グッド

2クリップ

投稿2022/10/06 09:28

編集2022/10/06 09:45

前提、実現したいこと

htmlのhead内で自分の使いたいremodalとdatatableというライブラリを読み込んでいたところから、js/script.js内でこれら2つを読み込むようにしたいのですが、そうすると下記のようにエラーが出ます。ライブラリが読めなくなったのだと思います。

$(...).DataTable is not a function

具体的にはこの正常に動くHTML、JSを…

html

1<head> 2 <link rel="stylesheet" href="css/remodal.css" /> 3 <link rel="stylesheet" href="css/remodal-default-theme.css" /> 4 <script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script> 5 <script src="./js/remodal.js"></script> 6 <script src="./js/datatables.min.js"></script> 7 <script src="./js/script.js"></script> 8 <meta charset="UTF-8" /> 9 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 10 <meta http-equiv="X-UA-Compatible" content="ie=edge" /> 11 <title>Document</title> 12</head> 13 14<body> 15 <a id="remodalOn" href="#modal">Call the modal with data-remodal-id="modal"</a> 16 <div class="remodal" data-remodal-id="modal"> 17 <button data-remodal-action="close" class="remodal-close"></button> 18 <h1>Remodal</h1> 19 <table id="example" class="display" style="width:100%"> 20 <thead> 21 <tr> 22 <th>Name</th> 23 <th>Position</th> 24 <th>Office</th> 25 <th>Age</th> 26 <th>Start date</th> 27 <th>Salary</th> 28 </tr> 29 </thead> 30 <tbody> 31 <tr> 32 <td>Herrod Chandler</td> 33 <td>Sales Assistant</td> 34 <td>San Francisco</td> 35 <td>59</td> 36 <td>2012-08-06</td> 37 <td>$137,500</td> 38 </tr> 39 <tr> 40 <td>Rhona Davidson</td> 41 <td>Integration Specialist</td> 42 <td>Tokyo</td> 43 <td>55</td> 44 <td>2010-10-14</td> 45 <td>$327,900</td> 46 </tr> 47 </tbody> 48 <tfoot> 49 <tr> 50 <th>Name</th> 51 <th>Position</th> 52 <th>Office</th> 53 <th>Age</th> 54 <th>Start date</th> 55 <th>Salary</th> 56 </tr> 57 </tfoot> 58 </table> 59 </div> 60</body>

javascript

1$(document).ready(function () { 2 $('#example').DataTable(); 3});

イメージ説明

下記のように変更します。
headタグ内のremodal,datatableのscriptタグは取り払いました。
このおかげで、HTML内の<script src="./js/script.js"></script>の下の行に

<script src="./js/remodal.js"></script>と <script src="./js/datatables.min.js"></script>を追加できます。

コンソールを見てもしっかりheadタグ内にscriptタグが追加されていますが、何故dataTableが使えないのか分かりません。

javascript

1$(function(){ 2 var scripts = ["js/datatables.min.js", "js/remodal.js"]; 3 for (let index = 0; index < scripts.length; ++index) { 4 var script = document.createElement("script"); 5 script.src = scripts[index]; 6 // htmlの<script src="./js/script.js"></script>より前にscriptタグを書き込む 7 document.querySelector("head > script:nth-child(4)").after(script, document.querySelector('head > script:nth-child(4)')) 8 } 9}); 10 11$(document).ready(function () { 12 $('#example').DataTable(); 13});

イメージ説明

試したこと

script.jsで、配列の中をremodal.jsのみにすると、エラーなく動いてくれます。
datatableは動かせませんがモーダルは出せます。
どうすれば良いのでしょう?

補足情報(FW/ツールのバージョンなど)

datatablesの入手元:
https://datatables.net/download/

Cocode👏を押しています

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

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

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

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

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

guest

回答2

0

ベストアンサー

DOM操作で<script>を生成してドキュメントに追加したとき、そのスクリプトが即時に実行されるわけではありません。ドキュメントに追加した時点から非同期のリソースロードが始まって、それが終わった時点で実行されます。

HTMLソース中に<script>を書いた場合はリソースロードが終わってスクリプトの実行が終わるまでHTMLパーザの動作が止まりますが、DOM操作で追加した場合にはJavaScriptコードが止まったりはしないわけです。

よって、js/datatables.min.js<script>loadイベントよりも後で $('#example').DataTable(); を実行する必要があります。例:

js

1 script.src = scripts[index]; 2 if (scripts[index].includes('datatables')) 3 script.addEventListener('load', () => { $('#example').DataTable(); }); 4 // ドキュメント中のどこに挿入しても同じ 5 document.head.appendChild(script);

投稿2022/10/07 00:33

編集2022/10/07 00:38
int32_t

総合スコア20929

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

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

rsrsrs

2022/10/07 05:05

ありがとうございます。これで上手く行きました。 解説分かりやすく助かります。 Cocode様も原因と解決法を詳しく書いていただいておりとても嬉しかったのですが、 シンプルさではint32_t様のほうがベターかと思ったのでこちらにベストアンサーを差し上げます。
guest

0

今回、知識不足の私にとって実装方法が分からないご質問だったのですが、原因は分かっていので、コードを調べてなんとかできました。
有識者様からのご指摘大歓迎です。

質問者様の質問の意図としては、「head内に手動で何個もscriptタグを書きたくない」ということだと思います。
それを実現するためにscript.jsでscriptタグを生成するのではなく、script.jsで他のJSファイルを読み込むような処理にしてみました。

コード例

javascript

1$(function () { 2 $.ajax( 3 { // remodal.js読み込み 4 url: './js/remodal.js', 5 dataType: 'script' 6 }, 7 { // datatables.min.js読み込み 8 url: './js/datatables.min.js', 9 dataType: 'script', 10 success: function () { $('#example').DataTable(); } // datatables.min.js読み込み成功時に実行 11 } 12 ); 13}); 14 15// または、 16 17$(function () { 18 // remodal.js読み込み 19 $.ajax( 20 { 21 url: './js/remodal.js', 22 dataType: 'script' 23 }, 24 ); 25 26 // datatables.min.js読み込み 27 $.ajax( 28 { 29 url: './js/datatables.min.js', 30 dataType: 'script', 31 } 32 ).done(function () { // datatables.min.js読み込み成功で実行 33 $('#example').DataTable(); 34 }) 35});

不具合の原因

コードやファイルは基本的に上から順番に読み込まれ実行されていきます。
質問者様の不具合コードの処理内容を見ますと、

  • 1)jQueryを読み込み、実行する
  • 2)script.jsを読み込み、実行する
    • 2−1)headにremodal.jsとdatatables.min.jsのスクリプトタグを生成 ※生成しただけで読み込んではいない
    • 2−2)$('#example').DataTable()を実行 ←エラー!
  • 3)生成されたremodal.jsとdatatables.min.jsが読み込まれ、実行される

2−1の段階ではまだこれら外部ファイルは読み込まれておらず、2−2の段階でDataTables()なんてしりませんなにそれ!というエラーがでています。

ですので順番を、2−1→ 3 → 2−2に変更しなければなりません。

※remodalがエラーにならないのは、remodal.jsが読み込み完了してから、クリックボタンをおしているためです。

対策

「外部ファイルが読み込まれてから実行する」ことができるのが非同期処理のajax()だそうです。

javascript

1$(function () { 2 $.ajax( 3 { 4 url: 読み込みたいファイルのパス, 5 dataType: ファイルの種類, 6 success: 読み込み成功時に実行する処理 7 } 8 ); 9}); 10 11// または 12 13$(function () { 14 $.ajax( 15 { 16 url: 読み込みたいファイルのパス, 17 dataType: ファイルの種類, 18 } 19 ).done(function () { 20 // 読み込み成功時に実行する処理 21 }) 22});

↑のようにかくことで、読み込んだ後に処理ができるようです。

投稿2022/10/06 13:57

編集2022/10/06 14:51
Cocode

総合スコア2314

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

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

rsrsrs

2022/10/07 05:08

コード例の「または」以降のコードで上手くremodalもdatatablesも使えるようになりました。 解説も丁寧で勉強になりました。 int32_t様の方がシンプルにまとまっていたのでベストアンサーは譲ってしまいましたが、とても助かっています。 回答いただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問