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

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

ただいまの
回答率

87.80%

onclickの登録に関して。

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 507

score 153

前提・実現したいこと

こちらのサイトを参考に、
HTMLタグにonclick属性を付与するようなクリックイベントの登録処理を行いたいのですが、
試してみると、タグにonclick属性が付与されず、クリックイベントも反応せず、実装方法がわかりません。
ご教示お願いします。

試したこと

<body>
    <ul>
        <li id="list1">リスト1</li>
        <li id="list2">リスト2</li>
        <li id="list3">リスト3</li>
    </ul>
</body>
$(function() {
    $("#list1").onclick = something();

    function something(){
        console.log("test");        
    }
});


実行すると、なぜかロード時に「test」の出力がされました。
リスト1を何度クリックしても、出力がされませんでした。
HTMLを見てみると、当該listタグにonclick属性も付与されていませんでした。

ちなみに、クリックイベントの登録で下記の書き方は知っています。
質問冒頭に提示した参考サイトのように、
タグにonclick属性を付与するようなonclickでの書き方を教えていただきたいです。

    $("#list1").on('click', function() {
        console.log("test");
    });

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

Google Chrome,
jquery 1.11.2

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

+4

onclickプロパティにメソッドを渡してもonclickイベントの登録にはなりません。
この記事の趣旨は既に登録されているonlickプロパティを変数に代入しておけば、
再登録する時に再度onclickプロパティに設定することでそのまま使えるということだと思います。

試しにいくらか作ってみましたが別なidにコピーすることはできますね。

<body>
    <ul>
        <li id="list1" onclick="something()">リスト1</li>
        <li id="list2">リスト2</li>
        <li id="list3">リスト3</li>
        <button onclick="eventdelete()">削除</button>
        <button onclick="reregistration()">再登録</button>
        <button onclick="copy()">コピー</button>
    </ul>
</body>
function something(){
    console.log("test");        
}

var event;
function eventdelete(){
    event = $("#list1").get(0).onclick;
    $("#list1").get(0).onclick = "";
}

function reregistration(){
    $("#list1").get(0).onclick = event;
}

function copy(){
    $("#list2").get(0).onclick = event;
}

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/01/21 13:34

    ご回答ありがとうございます。
    勉強になりました。
    ありがとうございます。

    キャンセル

+3

タグにonclick属性を付与するようなonclickでの書き方を教えていただきたい

なんの役にもたたないので覚えないほうがよいでしょう。

$(function(){
  $('#list1').attr('onclick',"console.log('test')");
});

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/01/21 09:37

    clickの属性への書き出しはは競合するので一つしか登録できません

    キャンセル

  • 2020/01/21 13:33

    ご回答ありがとうございます。
    なるほど、attr属性が使えるのですね。しかし、非推奨ということを教えていただきありがとうございます。
    ありがとうございます。

    キャンセル

checkベストアンサー

+2

実行すると、なぜかロード時に「test」の出力がされました。
リスト1を何度クリックしても、出力がされませんでした。
HTMLを見てみると、当該listタグにonclick属性も付与されていませんでした。

jQuery オブジェクトの プロパティ や メソッド(返り値)を考慮してください。

  1. jQuery では {HTML*Element} オブジェクト を参照するために get(0) の結果を使っている。
  2. 関数に () を付けると実行構文。代入するのは 結果なのか、関数そのものなのかを考える。

ご質問の $("#list1").onclick = something(); は
リンク先に倣うなら、$("#list1").get(0).onclick = something; と書かれているはずです。

追記)

コメント欄の質問より

$("#list1")と$("#list1").get(0)で取得されるものの違い(中略)下記の認識で合っていますか?

その認識で合っています。

手っ取り早くjQueryの実装を確認する方法:

  1. console.log($("#list1"))
  2. console.log($("#list1").get(0))

引数付きで関数を呼び出すような処理を付与する

HTMLでの属性記述とは異なり、JavaScriptでは DOM を介することになります。
全ての DOM要素の基底オブジェクトとなる EventTarget の実装に従います。
(イベントハンドラの第一引数 に渡されるのが event オブジェクト)

$(function() {

  // 1. イベント伝搬するので 要素に引数に変わる値を設定しておく例
  $("#list1").get(0).onclick = something;
  let elm1 = $("#list1").get(0);
  elm1.setAttribute("my-arg","hogehoge");
  function something( event ) {
    console.log("test", event )
    console.log( event.target === elm1 ); // true
    console.log( event.target.getAttribute("my-arg") ); // "hogehoge"
  }
/* イベントハンドラから参照できるスコープ内で引数に変わる値を保持する方法も
  let params = { "list1": "hogehoge" }
  $("#list1").get(0).onclick = something;
  function something( event ) {
    let elmId = event.target.id;
    console.log("test", params[elmId] ); // "test", "hogehoge"
  }
 */

  // enclosure で引数を受け、 closure をイベントハンドラとして返却する
  $("#list2").get(0).onclick = enclosure("hogehoge", 1, true);
  function enclosure( ...args ){
    return function closure(event) {
      console.log( event );
      console.log("test", args); // "test",["hogehoge", 1, true]
    }
  }

  // jQuery の data API を使う
  let argData = { hoge:"HOGE",num:123 };
  $("#list3")
    .data( "myArg", argData ) // 伝搬する要素に値を設定
    .on("click", function(){
      // クリック時に取り出して確認
      console.log( $(this).data("myArg") ); // { hoge:"HOGE",num:123 }
    });

});


jQuery では、JavaScript オブジェクトを渡せる data API が最もスマートと言えます。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/01/20 22:21

    ご回答ありがとうございます。
    すみません、2点質問があります。

    ・質問1。
     まず、$("#list1")と$("#list1").get(0)で取得されるものの違いを理解していなかったので調べました。
     下記の認識で合っていますか?

     $("#list1"):jQueryオブジェクト。
     $("#list1").get(0):DOMオブジェクト。

     DOMオブジェクトを掴むと、
     「DOMオブジェクト.属性名」の書式で、指定した属性にアクセスできる。

    ・質問2。
     下記のように引数付きで関数を呼び出すような処理を付与するには、どういった書き方をすればよいですか?
     <li onclick="Gmap.setCenter('21.3','-158.1');">リスト</li>
     ご回答いただいた内容について考えると、関数そのものというより、結果になるのでしょうか。
     ただ、()を付けた時点で関数呼び出しされてしまうので、
     意図としては、クリック時に引数を指定して読み込むようにしたい形です。
     ちなみに引数は動的に埋め込みます。
     イメージ的には、下記のようなことをしたいです(下記では意図した処理にならないですが)。
    var latitude = "21.3"; //動的に生成。
    var longitude = "-158.1"; //動的に生成。
    $("#list1").get(0).onclick = INTLDP_Gmap.setCenter(latitude, longitude);

    キャンセル

  • 2020/01/21 00:49

    すみません、質問2に関しては、だいぶまだ自分が理解していない点が多いので、質問1だけでも教えていただけたらと思います。

    キャンセル

  • 2020/01/21 06:13 編集

    追記しました。
    2. については「引数でなくとも、引数に与えたい内容をイベントハンドラ内で使えればいい。」という考えで実装します。

    キャンセル

  • 2020/01/21 13:34

    ご回答ありがとうございます。
    質問1,2のご回答ありがとうございます。
    data APIを使う方法があるのですね。
    とても勉強になりました。
    ありがとうございました。

    キャンセル

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

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

関連した質問

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