アプリ版:「スタンプのみでお礼する」機能のリリースについて

javascript初心者で質問自身が僕が解決したい問題の原因かどうかも解らずに質問しています。

<script type="text/javascript">
<!--
function hoge_1() {
~処理1~
}
function hoge_2(hiki_suu) {
~処理2~
}
window.onload = function() {
document.getElementById("button_1").onclock = hoge_1;
document.getElementById("button_2").onclock = hoge_2("watasu");
}
// -->
</script>

上記のようにページheadにscriptを配置したとします。ページ上のbutton_1がクリックされると処理1が実行されるのですが、hoge_2のように引数を使ってしまうと、onload時に処理2を実行してしまい、button_2は有効に動作しません。
functionの引数の問題なのか、window.onloadの作法なのか、なにが悪いのか全く解らず質問しています。

ご指導のほどよろしくお願いいたします。

A 回答 (4件)

onload時に実行したい内容は、「各ボタンに関数を代入する」ことと思われますが、button_2の箇所では代入ではなく関数の実行がなされています。

onloadの作法云々は関係ありませんね。基本的なことで、hoge_2は変数扱いですが、hoge_2()と書くと実行扱いになってしまいます。

もちろん、hoge_2()という書き方にしているのは、「引数があるから」というのがすごく分かります。
たとえばこの場合の解決策として、No.3さんのように、エレメントに直接書く方法が一番手っ取り早いです。
ただし、htmlとjsを分離して効率を上げるという意味では、htmlに直接書くことになるため、最善の方法ではないかもしれませんね。

次に、関数を使いまわさなくてもよい(引数の必要ない形)のであれば、以下のように直接関数定義することができます。

window.onload = function() {
 document.getElementById("button_1").onclick = function(){
  処理1
 };
 document.getElementById("button_2").onclick = function(){
  var hiki_suu = "watasu";
  処理2
 }
}

もちろん、処理2で引数を与えているぐらいですから、上記の例は現実的でない解決策です。
上記の例は、引数を固定できる場合の例です。
では、引数を与えつつ、buttonに関数を定義するにはどうすればいいか。
そこで、必要になってくるのがNo.1さんの回答です。
いってみれば、私の回答はNo.1さんの補足です。
    • good
    • 0
この回答へのお礼

大変参考になりました。ありがとうございます。

お礼日時:2011/05/23 15:20

質問者様がやりたいことが「ページ上のbutton_1がクリックされると処理1が実行され、button_2がクリックされると処理2が実行される。


と言うことで良ければ、下のように書いた方がよいのでは・・・?。

<form>
<input type="button" value="button_1" onClick="hoge_1()">
</form>

<form>
<input type="button" value="button_2" onClick="hoge_2("watasu)">
</form>
    • good
    • 0

訂正。

hoge_2("watasu")はclickの方でした。

function onClick (e) {
 hoge_2("watasu");
}
document.getElementById("button_2").addEventListener("click", onClick, false);

しかし、個々の要素にいちいちイベントリスナを取り付けるべきでないことは繰り返し主張いたします。innerHTML などの書き換えであっさり消滅してしまいます。
    • good
    • 0

根本的な話として、イベントリスナ(イベントハンドラ)というのは「第一引数にイベントオブジェクトをとる関数」なのです。

これはこういう定義ですので、何だかんだ言っても始まりません。

function onLoad (e /*イベントオブジェクト*/) {
 ;
}

であれば、そもそも「イベントハンドラに引数を渡したい」という要望自体が成り立たないことにお気付きでしょう。引数を渡したい関数があるなら、イベントハンドラの中で呼び出すのです。

function onLoad (e) {
 hoge_2("watasu");
}
addEventListener("load", onLoad, false);

window.onload でも同様ですが、この古いイベントプロパティを使うのは最後の手段にして下さい。

---
ついでに、click はバブリングしますので、いちいち load を待って個々の要素にハンドラを取り付ける必要などありません。

document.addEventListener("click", function (e) {
 var t = e.target;
 var c;
 for (c = t; c; c = c.parentNode) {
  switch (c.id) {
  case 'button_1' : return hoge_1();
  case 'button_2' : return hoge_2("watasu");
  }
 }
}, false);

これだけで十分です。IE8 以下なら addEventListener の代わりに attachEvent、e.target の代わりに e.srcElement でも使って下さい。

イベント周りは、知らなければどうしようもないことが多いので、試行錯誤する前に仕様・解説書を一通り眺めた方が良いです。
    • good
    • 0
この回答へのお礼

document.addEventListenerの部分を利用したところ、期待した結果を得られました。
そもそもイベントリスナが理解できてなく、勉強してみたいと思います。
ありがとうございました。

お礼日時:2011/05/23 15:24

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!