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

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

ただいまの
回答率

88.81%

【JavaScript】関数が定義されているのに、定義されてないといわれる

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,256

WeilSpinor

score -34

以下のphpコード(tangen_top.php)で、
2つ目のscriptタグ内(bodyの中)に、
関数「sendRequestToEdit(hikisuu)」が定義したのですが、
これをそれよりも下にあるbutton 「編集」をクリックしたときに呼び出すようにした、
onclick="sendRequestToEdit(this.value)"
のですが、
クリックするとなぜか、 Chromeのデベロッパーツールが以下のようなエラー、

Uncaught ReferenceError: sendRequestToEdit is not defined
at HTMLButtonElement.onclick (tangen_top.php:1)

を吐きます。

不可解な点は、以下に貼るtangen_top.phpは、一行目にはhtml開始タグ以外何も書いていないのに、そこがエラーの場所だと言ってくることです。

しかも、デベロッパーツールのsourcesタブを開きながらボタン「編集」を押すとわかるのですが、なぜかボタンを押すと、横に表示されているマシンのディレクトリに、中身に「sendRequestToEdit(this.value)」とだけ書いてある同じファイル名のファイルtangen_top.phpが突如作成され、表示されるのです

以下にコードを張りますので、どこが間違っているかご指摘頂けると幸いです。

ただし、これはソースコードではなく、
ページ内での操作によってデータベース処理や、Ajaxによる別のphpプログラムとの連携処理などが行われ、
HTMLが最初の状態から色々変化した後の状態でデベロッパーツールのElementタブに表示されたものコピペしたものです。
このシステムの全容を説明しようsとするとややこしくなるので、一問一答の形で質問させて頂きます。

【ファイル:tangen_top.phpのなれの果て(もはやただのHTML)】

<html lang="ja" dir="ltr"><head>
    <meta charset="utf-8">
    <title>プロジェクトマネージャー</title>

    <script type="text/javascript">
    function sendRequest(subject_name){
        if (subject_name =="") {
        document.getElementById("disp_rec").innerHTML = "";
        return;
    }else{ 
        if (window.XMLHttpRequest) {
            // code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
        } else {
            // code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        xmlhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                document.getElementById("disp_rec").innerHTML = this.responseText;
            }
        };
        xmlhttp.open("GET","tangen_get.php?subject_name="+subject_name,true);
        xmlhttp.send();
    }
    }


   </script>

  </head>
  <body>


    <select name="subject_name" onchange="sendRequest(this.value)">
       <option value="">Select a subject</option>
       <option value="量子力学">量子力学</option><option value="統計力学">統計力学</option><option value="線形代数">線形代数</option><option value="複素関数">複素関数</option><option value="微分積分">微分積分</option><option value="熱力学">熱力学</option><option value="古典力学">古典力学</option><option value="電磁気学">電磁気学</option><option value="物性">物性</option>    </select>
    <div id="disp_rec">


    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script>
    function sendRequestToEdit(hikisuu){

        //クリックした編集ボタンに該当する単元の単元コード、科目名、単元の取得
        const code_tangen = hikisuu;
        const subject_name = document.querySelector('tr#'+code_tangen+' input[name="subject_name"]').value;
        const tangen = document.querySelector('tr#'+code_tangen+' input[name="tangen"]').value;

        //for debug
        console.log("current selection:"+tangen);

        if (window.XMLHttpRequest) {
            // code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
        } else {
            // code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        xmlhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                document.getElementById("add_rec").innerHTML = this.responseText;
            }
        };
        xmlhttp.open("GET","tangen_edit.php?code_tangen="+code_tangen+"&subject_name="+subject_name+"&tangen="+tangen,true);
        xmlhttp.send();
    }
    alert("W");
    alert(typeof sendRequestToEdit);
    </script>


<table border="1" id=""><tbody><tr><td>科目</td><td>単元</td><td></td><td>済or未</td></tr><tr id="1"><input type="hidden" name="code_tangen" value="1"><input type="hidden" name="subject_name" value="量子力学"><input type="hidden" name="tangen" value="一次元系の基本(イギ、オガワ等)"><td>量子力学</td><td>一次元系の基本(イギ、オガワ等)</td><td><button type="button" value="1" onclick="sendRequestToEdit(this.value)">編集</button></td><td><input type="checkbox" class="sumi"></td></tr><tr id="3"><input type="hidden" name="code_tangen" value="3"><input type="hidden" name="subject_name" value="量子力学"><input type="hidden" name="tangen" value="井戸型ポテンシャルをちゃんと理解"><td>量子力学</td><td>井戸型ポテンシャルをちゃんと理解</td><td><button type="button" value="3" onclick="sendRequestToEdit(this.value)">編集</button></td><td><input type="checkbox" class="sumi"></td></tr><tr id="8"><input type="hidden" name="code_tangen" value="8"><input type="hidden" name="subject_name" value="量子力学"><input type="hidden" name="tangen" value="角運動量の摂動(ゼーマン、スピン軌道など)"><td>量子力学</td><td>角運動量の摂動(ゼーマン、スピン軌道など)</td><td><button type="button" value="8" onclick="sendRequestToEdit(this.value)">編集</button></td><td><input type="checkbox" class="sumi"></td></tr><tr id="9"><input type="hidden" name="code_tangen" value="9"><input type="hidden" name="subject_name" value="量子力学"><input type="hidden" name="tangen" value="縮退ありの摂動論の形式論の理解"><td>量子力学</td><td>縮退ありの摂動論の形式論の理解</td><td><button type="button" value="9" onclick="sendRequestToEdit(this.value)">編集</button></td><td><input type="checkbox" class="sumi"></td></tr></tbody></table><br><br> <div id="add_rec">addrec</div>

</div>


</body></html>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2019/05/24 21:11

    実際のソースコードでないなら全く意味がないので。

    キャンセル

  • m.ts10806

    2019/05/24 21:15

    デベロッパーツールは制作者の醜いコードをなんとかまともに動かすべくブラウザ側の補正がかかりますし。
    質問者が実際に組んだコード以外、提示されても回答しようがないのです。

    キャンセル

  • Lhankor_Mhy

    2019/05/27 17:07

    問題が再現しませんでした。
    ご提示のコードを当方で試したところ、以下のエラーを得ました。

    DOMException: Failed to execute 'querySelector' on 'Document': 'tr#1 input[name="subject_name"]' is not a valid selector.

    おそらく、ご提示いただいていない部分のコードに問題があるのか、環境の問題だと思います。

    キャンセル

回答 3

+2

JavaScriptによるエラーですね。質問コードをhtmlとして開き、「編集ボタン」をクリック→

SyntaxError: The string did not match the expected pattern.

コンソールに表示されました。

↓該当箇所↓

const code_tangen = hikisuu;
const subject_name = document.querySelector('tr#' + code_tangen + ' input[name="subject_name"]').value; //  <-- SyntaxError: The string did not match the expected pattern.

const tangen = document.querySelector('tr#' + code_tangen + ' input[name="tangen"]').value;

id名を数字で始めるのがNGで、例えば、各<tr>を’<tr id="t1">`のようにアルファベットから始まるid名にすると、エラーは出ませんでした🙆‍♀️

理由

問題箇所は、yasutomiさんが指摘されている点でした。 ただし、x_xさんが仰っる通り、HTML5ではid名が数字から始まっていてもOKです。

ところがです。CSSでは、識別子(タグ名・id名・クラス名)が数字で始まるのはNGでした。

[リンク辿った順序] Selectors Level3 => 4 Selector syntax => ID Selector => identifiers => 4.1.3 Characters and case (CSS2.1)

4.1.3 Characters and case | CSS2.1 -W3C-

(日本語訳)
CSSでは、識別子(要素名、クラス、セレクタ内のIDを含む)に使用できる文字は[a-zA-Z0-9]とISO 10646のU + 00A0以上の文字、およびハイフン( - )とアンダースコア( _); 数字、2つのハイフン、またはハイフンとそれに続く数字で始めることはできません。 ...

(original)
In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [a-zA-Z0-9] and ISO 10646 characters U+00A0 and higher, plus the hyphen (-) and the underscore (_); they cannot start with a digit, two hyphens, or a hyphen followed by a digit. ...

そして、それに伴い、JavaScript

document.querySelector(SELECTOR);
document.querySelectorAll(SELECTOR);

に渡すSELECTORの文字列も、CSSのセレクターの構文規則に準じているようです。

ややこしいですね😅💦

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/27 22:26

    CSSで識別子(タグ名・id名・クラス名)が数字で始まるのがNGなら
    実質的にはHTML5も誤爆防止のためにNGですね。

    キャンセル

  • 2019/05/27 22:31

    ちなみにどうしても数字で使用したい場合は
    CSS側でエスケープした文字列で書き直せば有効になるそうです。
    (もちろん非推奨ですが)
    https://qiita.com/ka-ko/items/feacb4d3ff22666d51b1

    キャンセル

  • 2019/05/28 00:36

    なんとマニアックな素敵記事!?(′ʘ⌄ʘ‵)✨✨ ありがとうございます🌟 この質問ページは、id,class,セレクター周りについて、かなり充実しましたね☺️✨♪♪

    というわけで☜ こちらも追加で置いておきます😅w
    ‪• ‬Using character escapes in markup and CSS -W3C-
     https://www.w3.org/International/questions/qa-escapes

    (CSS構文のエスケープ方法が、例を交えて分かりやすく解説されている記事。仕様書より緩い文体で読みやすい)

    キャンセル

  • 2019/05/30 00:16

    ご回答ありがとうございます。セレクタに関しては、私の環境では先頭が数字でも問題なく動きましたが、本来的にはルール違反だということなので、アルファベットを追加しておきました。今後気を付けていこうと思います。

    ただ残念ながらメインのエラーは解決ならずでした…。

    キャンセル

check解決した方法

-1

自己解決しました。

問題は、使おうとしたけど存在しないと言われた関数「sendRequestToEdit」の定義をこのファイルtangen_top.php内のスクリプトではしておらず、ajax先のファイルのスクリプトで定義していた、というところでした。
ajax先のファイルに定義しておいて、そのスクリプトを送り返してくれれば、と期待していたんですが…
もしかして、responseTextとやっていたので、あくまでrequest先のテキストデータ(htmlなど)を返すだけで、中に描かれたスクリプトは送られてこなかったんですかね?
もしかしたら、それの代わりにresponseHtmlみたいなコマンドがあって、それをやればよかったのか…。まだまだ勉強が必要ですね。
とりあえず解決してよかったです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/30 07:52

    ajaxでもコードは返されますよ。テキストとして。
    responseTextが純粋なjsコードならevalすれはコードを評価することはできます。
    ajaxでhtmlだけと書いておられますが、htmlからjsだけを取り除くのがどれほど難しいか。

    キャンセル

-1

<tr id="1"> となっていますが、 
id属性の先頭はアルファベットでなければならないという決まりがあるため
idに数字だけを指定しているコードは正常に動作しないです。

アルファベットで始めなければなりません。(数字や記号で始めてはならない)

https://www.tagindex.com/html_tag/attribute/id.html

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/27 15:08

    それは HTML4 の話です。質問の提示コードは内容から HTML5 と考えられます。
    なぜそんなところを参照したのかわかりませんが、あえて TAG index 中から探すというのならここでしょう。
    https://www.tagindex.com/html5/attribute/id.html

    仕様から
    https://momdo.github.io/html/dom.html#global-attributes
    > id属性はその要素の固有識別子(ID)を指定する。
    IDを取ることができる形式に制限は存在しない。具体的に、IDは数字のみまたは句読点のみで構成することができ、数字やアンダースコアで開始できる、などである。

    キャンセル

  • 2019/05/27 16:30 編集

    HTML5ではidは数字やアンダースコアで開始できるが正しいですね。
    訂正します。

    キャンセル

  • 2019/05/30 00:16

    ご回答ありがとうございます。セレクタに関しては、私の環境では先頭が数字でも問題なく動きましたが、本来的にはルール違反だということなので、アルファベットを追加しておきました。今後気を付けていこうと思います。

    ただ残念ながらメインのエラーは解決ならずでした…

    キャンセル

  • 2019/05/30 09:45

    全然コメント読んでいないようですね。
    コメントを信用しなくても構いませんが、リンク先を見るくらいはしてみたらどうでしょうか?

    キャンセル

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

  • ただいまの回答率 88.81%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る