[JS] eventListenerで要素の表示非表示を切り替える

このQ&Aのポイント
  • GMのスクリプトで、ボタンクリックにより、任意のテキストの非表示を切り替える機能に取り組んでいます。
  • クリックにより eventListener で関数を呼び出して、そのときの引数で style.display = "block" と "none" を切り替えたいのですが、クリックにてイベントがトリガされず、ページロード時に関数が呼ばれてしまい、非表示の状態でロードが完了してしまいます。
  • クリックによるイベントのトリガについて、初期ロード時に無駄な関数 call をおこさない方法について、ご指摘いただけないでしょうか。
回答を見る
  • ベストアンサー

[JS] eventListener

GMのスクリプトで、ボタンクリックにより、任意の テキストの非表示を切り替える機能に取り組んでいます。 クリックにより eventListener で関数を呼び出して、そのときの 引数で style.display = "block" と "none" を切り替えたいのですが、 クリックにてイベントがトリガされません。また、後述のとおり ページロード時に関数が呼ばれてしまって、非表示の状態でロードが完了してしまいます。 ====================== <省略> // 表示・非表示ボタン var addForm = document.createElement('form'); // 表示ボタン var addInput1 = document.createElement('input'); var addType1 = document.createAttribute('type'); addType1.nodeValue = 'button'; var addValue1 = document.createAttribute('value'); addValue1.nodeValue = 'Display'; var addOnclick1 = document.createAttribute('onclick'); addOnclick1.nodeValue = "hyoji(0)"; addInput1.setAttributeNode(addType1); addInput1.setAttributeNode(addValue1); addInput1.setAttributeNode(addOnclick1); // 非表示ボタン var addInput2 = document.createElement('input'); var addType2 = document.createAttribute('type'); addType2.nodeValue = 'button'; var addValue2 = document.createAttribute('value'); addValue2.nodeValue = 'UnDisplay'; var addOnclick2 = document.createAttribute('onclick'); addOnclick2.nodeValue = "hyoji(1)"; addInput2.setAttributeNode(addType2); addInput2.setAttributeNode(addValue2); addInput2.setAttributeNode(addOnclick2); // ボタンをフォームに追加 newNode.parentNode.insertBefore(addForm, newNode); addForm.appendChild(addInput1); addForm.appendChild(addInput2); // Display <-> UnDisplay switch addInput1.addEventListener("click",hyoji(0), false); addInput2.addEventListener("click",hyoji(1), false); // 関数部分 function hyoji(num) { if (num == 0) { document.getElementById('disp').style.display = "block"; } else { document.getElementById('disp').style.display = "none"; } } ====================== <form> <input type="button" value="Display" onclick="hyoji(0)"> <input type="button" value="UnDisplay" onclick="hyoji(1)"> </form> <div id="disp" style="display: none;"> <pre> 文字列 </pre> </div> ======================= ブレークポイントで動作を追ってみると、ページ読み込み時に addInput1.addEventListener("click",hyoji(0), false); から関数に飛び、戻って来て、 addInput2.addEventListener("click",hyoji(1), false); でまた関数に飛び、 結果的に非表示の状態でページロードが完了します。 その後にボタンをクリックしてもイベントが発生しません。 クリックによるイベントのトリガについて、 初期ロード時に上述の無駄な関数 call をおこさない方法について、 何かご指摘を頂けないでしょうか。 eventListener と style.display については下記を 参考させていただきました。 http://www.vividcode.info/js/event/eventListener.xhtml http://js.studio-kingdom.com/javascript/element/addeventlistener http://www.pori2.net/js/DOM/7.html 宜しくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • Ogre7077
  • ベストアンサー率65% (170/258)
回答No.2

JavaScript には「関数オブジェクト」なる存在があります。 addEventListener の第二引数は、このオブジェクトを指定しなければいけません。 関数オブジェクトの書き方 var funcObject = function(){ 処理内容 }; ゆえに 誤) addInput1.addEventListener("click",hyoji(0), false); 正) addInput1.addEventListener("click", function(event){ hyoji(0) }, false); 個人的には、この様に書けば理解しやすいのでお勧めします var funcObject = function(event){ hyoji(0) }; addInput1.addEventListener("click", funcObject, false); 余談ではありますが、以下の処理は addEventListener と被っていますので削除すべきかと var addOnclick1 = document.createAttribute('onclick'); addOnclick1.nodeValue = "hyoji(0)"; addInput1.setAttributeNode(addOnclick1); 余談の余談ですが、onclick ならもっと良い書き方があります addInput1.onclick = function(){ hyoji(0) };

jussmen_1979
質問者

お礼

有り難うございました。 余談についても、参考にさせていただきました。

その他の回答 (1)

  • Picosoft
  • ベストアンサー率70% (274/391)
回答No.1

 addInput1.addEventListener("click",hyoji(0), false); とすると、リスナー登録時にhyoji(0)が呼ばれてしまいます。  addInput1.addEventListener("click", function(){hyoji(0);}, false); としてください。

jussmen_1979
質問者

お礼

有り難うございました。

関連するQ&A

  • EventListener による関数呼び出し

    GMのスクリプトで、ボタンクリックにより、任意の テキストの非表示を切り替える機能に取り組んでいます。 端的な質問内容は下記の『問題点』に記していますが、 根本的な実装方法が適当でないという可能性もあると 思いますので、すべてのコードと、目的の機能について 順に説明させていただきます。 『目的の機能』 GMのスクリプトで、ボタンクリックにより、任意の テキストの非表示を切り替える 『実装方法』 具体的な方法としては以下のような内容です。 ・ページ内にランダム数ある <pre> タグ数を xpath の snapshotLengh で得る ・ループで各 <pre> タグの直前に、<form> を追記する ・ループで各 <pre> タグを <div id="dispX"> で囲む // タグ追記後の HTML // <form> <input type="button" value="Display"> <input type="button" value="UnDisplay"> </form> <div id="disp1"> <pre> テキスト </pre> </div> ...... <form> <input type="button" value="Display"> <input type="button" value="UnDisplay"> </form> <div id="disp2"> <pre> テキスト </pre> </div> ・クリックにより eventListener で関数を呼び出して、そのときの 引数が 0 と 1 で style.display = "block" と "none" を切り替える ・切り替える対象は document.getElementById("dispX") で得る  ※ここが問題 『現在期待通りに動作している部分』 タグの追加は期待通りに動作している。 EventListener の引数は、Dispaly クリック時に 0 Undispaly クリック時に 1 が関数 hyoji() に渡されており、期待通り。 『問題点』 以下のEventListener において、 i = 1 のとき、document.getElementById にて disp1 を対象として得たい。 同様に、i = 2 のときは disp2 を対象として得たい。 しかしながら、現在のコードでは(当然ですが。。)  i の値に寄らず、getElementById で得られる対象は disp に固定されてしまっている。 eval("addInputUndisplay"+i+".addEventListener('click',function(){hyoji(1);}, false);"); function hyoji(num) { if (num == 0) { document.getElementById("disp").style.display = "block"; } else { document.getElementById("disp").style.display = "none"; } } 上記問題点を解決できるような EventListener の使い方や、別の実装方法のヒントなどが ありましたらご教示いただけないでしょうか。 宜しくお願い致します。 ==================== GM の全ソースコード ==================== var i, num; var allObj = document.evaluate("//pre", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); for (i = 0; i < allObj.snapshotLength; i++){ // Adding <div id="disp"> before target <pre> tag var range = document.createRange(); var newNode = document.createElement("div"); eval("var addId"+i+"= document.createAttribute('id');"); eval("addId"+i+".nodeValue = 'disp"+i+"';"); eval("newNode.setAttributeNode(addId"+i+");"); var thisObj = allObj.snapshotItem(i); range.selectNode(thisObj); range.surroundContents(newNode); var addForm = document.createElement("form"); // Display Button eval("var addInputDisplay"+i+"= document.createElement('input');"); var addTypeDisplay = document.createAttribute("type"); addTypeDisplay.nodeValue = "button"; var addValueDisplay = document.createAttribute("value"); addValueDisplay.nodeValue = "Display"; eval("addInputDisplay"+i+".setAttributeNode(addTypeDisplay);"); eval("addInputDisplay"+i+".setAttributeNode(addValueDisplay);"); eval("addInputDisplay"+i+".addEventListener('click',function(){hyoji(0);}, false);"); // Undisplay Button eval("var addInputUndisplay"+i+" = document.createElement('input');"); var addTypeUndisplay = document.createAttribute("type"); addTypeUndisplay.nodeValue = "button"; var addValueUndisplay = document.createAttribute("value"); addValueUndisplay.nodeValue = "UnDisplay"; eval("addInputUndisplay"+i+".setAttributeNode(addTypeUndisplay);"); eval("addInputUndisplay"+i+".setAttributeNode(addValueUndisplay);"); eval("addInputUndisplay"+i+".addEventListener('click',function(){hyoji(1);}, false);"); // Adding buttons newNode.parentNode.insertBefore(addForm, newNode); eval("addForm.appendChild(addInputDisplay"+i+");"); eval("addForm.appendChild(addInputUndisplay"+i+");"); } function hyoji(num) { if (num == 0) { document.getElementById("disp").style.display = "block"; } else { document.getElementById("disp").style.display = "none"; } } ==========================

  • JavaScriptでテキストを表示・非表示・・・

    こんばんは。お世話になります。 JavaScriptでテキストがボタンを押すと表示/非表示と切り替わるようにしたいです。 サイトを参考に試してみましたが一か所しか表示/非表示となりませんでした。 1行おきに表示/非表示としたいのでブロック単位では指定出来ません。 display構文を使って作りました。 div idがそれぞれの部分に必要かと思い、div id="○○a"、div id="○○b"という風に付けましたがうまくいきませんでした。    ↓このような形にしたいです  あいうえおかきくけこ   サシスセソタチツテト ←この行を表示/非表示  なにぬねのはひふへほ   マミムメモヤユヨ ←この行を表示/非表示 こういう風なように打ちました。 あいうえおかきくけこ<br> <div id="disp">サシスセソタチツテト</div><br>         なにぬねのはひふへほ<br>  <div id="disp">マミムメモヤユヨ</div><br> <form> <input type="button" value="表示" onclick="Hyoji1(0)"> <input type="button" value="非表示" onclick="Hyoji1(1)"> </form> <script type="text/javascript"> <!-- function Hyoji1(num) { if (num == 0) { document.getElementById("disp").style.display="block"; } else { document.getElementById("disp").style.display="none"; } } // --> </script> どの辺りを間違っているでしょうか?宜しくお願い致します。

  • 下の様にjavaScriptでボタンを追加したいのですが、

    下の様にjavaScriptでボタンを追加したいのですが、 onclickイベントがHTMLにかかれません。 どうすればよろしいでしょうか。 よろしくお願いします。 var ele = document.createElement('input'); ele.type = 'button'; ele.value = 'ご意見へ'; ele.name = 'fNext'; ele.onclick = "sendRequest('FE0041')"; objct[0].parentNode.appendChild(ele);

  • onclick属性に外部jsと外部cssの記載方法

    表題の通りclickイベントを付与したいのですが、記載方法が分からなくて困っています。 例) <div id="sample1"> <a href="javascript:void(0);" onclick="document.getElementById('sample2').style.display='block'; document.getElementById('sample1').style.display='none'">ぴーしー</a> <link rel="stylesheet" type="text/css" href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css" /> <script src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js"></script> </div> <div id="sample2" style="display:none"> <a href="javascript:void(0);" onclick="document.getElementById('sample2').style.display='none'; document.getElementById('sample1').style.display='block'">もばいる</a> </div> 上記のままだと更新ボタンを押さないと反映されなかったので、onclick属性にjquery.mobileを付与したいと思いまして。toggle,appendToなども試しましたが、挙動がおかしかったので、有志の方、代換え方法や助言をお願いします。

  • イベントリスナーがうまくいかない

    delBtnがない場合にイベントリスナーを読み込むとエラーが出てその後の処理が行われないため 下記のようにあった場合のみ予約するようにしたところ今度はクリックしても実行されない問題が起きました。 読み込み時は、エラーにならないようにし、かつボタンを押したときに要素を削除するようにするにはどうしたらよいでしょうか? var Result = document.getElementsByClassName('Result')[0].innerHTML = '<span class="u-mr-1rem">あああああ</span><input id="DelBtn" type="button" value="削除">; var Result = document.createElement('p'); BtnWrap.appendChild(Result); Result.classList.add('Result u-mtb-1rem'); var delBtn = document.getElementById('DelBtn'); if(delBtn !== null) { delBtn.addEventListener('click', function() { document.getElementsByClassName('Result')[0].remove(); }); }

  • javascriptのonclickに関数を追加?

    現在、javascriptでinput要素に新しくonclick='hoge()'などの関数を追加したいのですができません。 色々調べたのですが、結局わからなかったので質問させていただきます。 何卒、ご教授宜しくお願いします。 ■やろうとしていること 下記ソースのボタンをどれかクリックしたら、 新しく、<input type="button" value="次へ" onclick="next()" />というのを<span>に 生成したいのですが、onclickが追加されずに困っております。 どのようにしたらよいのでしょうか?ちなみにtypeとvalueは生成されています。 <form name="test"> <input type="button" value="" id="answer_0" onclick="test(0)" /> <input type="button" value="" id="answer_1" onclick="test(1)" /> <input type="button" value="" id="answer_2" onclick="test(2)" /> </form> <span id="test2"></span> <script> function test(n) { ・・・ 中略 var nq = document.createElement('input'); nq.type = "button"; nq.value = '次へ'; nq.onclick = "next()"; document.getElementById('test2').appendChild(nq); } </script> 以上、宜しくお願い申し上げます。

  • jQueryでの、引数を取るJS関数の呼出方法

    jQueryの学習をしています。 HTML & JavaScriptで下記のように書かれているコード <input type=button id=button1 onclick=func_a() /> <script> function func1(){ //処理いろいろ } </script> は、jQueryを使って書くと、 $('#button1').live('click', func_a); このように書けます。 <input type=button id=button1 onclick=func_b(arg1, arg2) /> <script> function func_b(argument1, argument2){ //処理いろいろ } のように引数を取る関数は jQueryではどのように書けばよいのでしょうか? $('#button1').live('click', func_b(arg1, arg2)); とは書けなかったので、今は、 if (arg1 == xxx){ $('#button1').live('click', func_b_1_1); } else { $('#button1').live('click', func_b_1_2); } などのように引数別に同じような関数を創って書いています。 DRY原則という同じコードを二度書くなという約束もあるようなので、 きっといい方法があると思うのですが、 お詳しい方、教えていただけるとうれしいです。 どうぞ、よろしくお願いいたします。

  • Flash as3.0版ソース  ボタンで内容遷移、うまくいかない…

    こんにちは。 Flash as3.0勉強始めてばかりです。 下記のソースのエラーはボタンを押したたびに、表示した内容はどんどん重ねています。たとえば、(1)ボタンを押した場合、(1)の内容を表示されまして。(2)ボタンを押したとき、画面には(1)+(2)の内容を表示されています。 いろいろ調べましたんですが、なかなかうまくいかないです。 ご解答をよろしくお願い致します。 詳細ソース ーーーーーーーーーーーーーーーーーーーーーー // イベントを設定 Button_tsr.addEventListener ( MouseEvent.CLICK , onClick1 ); Button_gaiyou.addEventListener ( MouseEvent.CLICK , onClick2 ); Button_message.addEventListener ( MouseEvent.CLICK , onClick3 ); Button_jigyou.addEventListener ( MouseEvent.CLICK , onClick4 ); Button_saiyou.addEventListener ( MouseEvent.CLICK , onClick5 ); Button_toiawase.addEventListener ( MouseEvent.CLICK , onClick6 ); // ローダーオブジェクトを作成し配置 var loader_obj : Loader = new Loader(); stage.addChild (loader_obj); loader_obj.x = 85; loader_obj.y =97; // 画面クリックをするとonClickが動作するイベント function onClick1 ( event:MouseEvent ) { // URLRequestを設定 var url0:URLRequest = new URLRequest( "Top.swf" ); // 実際にページに飛ぶ loader_obj.load ( url0 ); } function onClick2 ( event:MouseEvent ) { // URLRequestを設定 var url1:URLRequest = new URLRequest( "概要.swf" ); // 実際にページに飛ぶ loader_obj.load ( url1 ); } function onClick3 ( event:MouseEvent ) { // URLRequestを設定 var url2:URLRequest = new URLRequest( "Message.swf" ); // 実際にページに飛ぶ loader_obj.load ( url2); } function onClick4 ( event:MouseEvent ) { // URLRequestを設定 var url3:URLRequest = new URLRequest( "サービス.swf" ); // 実際にページに飛ぶ loader_obj.load ( url3); } function onClick5 ( event:MouseEvent ) { // URLRequestを設定 var url4:URLRequest = new URLRequest( "情報.swf" ); // 実際にページに飛ぶ loader_obj.load ( url4); } function onClick6 ( event:MouseEvent ) { // URLRequestを設定 var url5:URLRequest = new URLRequest( "問合せ.swf" ); // 実際にページに飛ぶ loader_obj.load ( url5); }

  • クローンすべてをクリックしたときにリスナーが実行

    下記のようにクローンすべてをクリックしたときにリスナーが実行されるようにしたかったのですが、同じクラス名の要素にはなっているもののおそらく配列の順番が違うので結局別要素と判断されてクローンをクリックしても実行されません。 クローンをクリックしても実行できるようにするにはどうすればよいのでしょうか。 イベントリスナーの対象要素を複数してする方法があるのでしょうか? let createElement = document.createElement('div'); document.body.appendChild(createElement); let className = createElement.className = 'game'; createElement.style.position = 'fixed'; let clone1 = createElement.cloneNode(true); document.body.appendChild(clone1); clone1.style.position = 'fixed'; let clone2 = createElement.cloneNode(true); document.body.appendChild(clone2); clone2.style.position = 'fixed'; createElement.addEventListener('click', ()=> { ~

  • JavaScriptについて

    JavaScriptでボタンゲームを作っているのですが、ボタンを押して正解だった場合、色が変わり押せなくなるようにしたいのですが、うまくいきません。どうしたら良いか困っています。 原因として「順番が正しいかどうか判定する」ところじゃないかと思います。 <script type="text/javascript"> //初期処理 var suji = "(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)(12)(13)(14)(15)"; var pushed = ""; // 押されたボタン管理 var startTime; // ゲーム開始時間を管理 var labelArray = suji.split(""); // 数字を一文字ずつ分割 $("startButton").onclick = start; nextGame(); // スタートボタンを表示する // 開始準備 function nextGame() { $("buttons").innerHTML = ""; $("startButton").style.visibility = "visible"; } // ゲーム開始 function start() { $("startButton").style.visibility = "hidden"; // 配列に数字を代入して順番をシャッフル arrayShuffle(labelArray); // ボタンを作る for (var i = 0; i < labelArray.length; i++) { var b = document.createElement("button"); b.innerHTML = labelArray[i]; b.onclick = button_clickHandler; $("buttons").appendChild(b); } pushed = 0; startTime = (new Date()).getTime(); } // ボタンが押された時の処理 function button_clickHandler(e) { var ch = e.target.innerHTML; // 押されたボタンの文字 // 順番が正しいかどうか判定する if (suji.substr(pushed, 1) != ch) { alert("違います。次は、" + suji.substr(pushed,1)); } else { $("buttons").innerHTML=""; arrayShuffle(labelArray) for(var i = 0; i < labelArray.length; i++) { var b = document.createElement("button"); b.innerHTML = labelArray[i]; b.onclick = button_clickHandler; $("buttons").appendChild(b); } e.target.disabled = true; e.target.style.backgroundColor = "#909090"; pushed++; } if (pushed == labelArray.length) { var now = new Date().getTime(); var tm = Math.floor((now - startTime) / 1000); var min = Math.floor(tm % 3600 / 60); var sec = tm % 60; alert("おめでとうございます。\n"+ min + "分" + sec +"秒でクリアです!"); nextGame(); } } // 配列をシャッフルする function arrayShuffle(bs) { for (var i = 0; i < bs.length; i++) { var r = Math.floor(Math.random()*bs.length); var tmp = bs[i]; bs[i] = bs[r]; bs[r] = tmp; } } function $(id) { return document.getElementById(id); } </script>

専門家に質問してみよう