\r\n```\r\n\r\n### コールバック関数 rev2\r\n\r\n先のコードを「clickEnd関数もlistenerオブジェクトに格納」に変更すれば、変数スコープを汚さない実装になります。\r\n\r\n- [clickイベント発火後+コールバック関数 rev2 - JSFiddle - Code Playground](https://jsfiddle.net/Lmwo4f6n/)\r\n\r\n```HTML\r\n\r\n\r\n```\r\n\r\n### 参考情報\r\n\r\n**コールバック関数**や**Promise**で検索すると、参考情報が見つかります。\r\n\r\n- [関数と宣言 · JavaScript Primer #jsprimer](https://jsprimer.net/basic/function-declaration/#callback)\r\n- [JavaScript Promiseの本](https://azu.github.io/promises-book/)\r\n\r\nRe: kentaka さん","dateModified":"2020-04-27T04:32:26.052Z","datePublished":"2020-04-27T04:14:30.064Z","upvoteCount":3,"url":"https://teratail.com/questions/256761#reply-369766","comment":[{"@type":"Comment","text":"余談ですが、\r\n\r\n> const number = 1;\r\n\r\nconst 宣言された変数値は書き換え不可の為、変数 number の値は「常に1」です。\r\n従って、「if( number >= 1 )」は常に true となり、条件式の意味がなくなります。\r\n本回答では、number をオブジェクトのプロパティに置くことで書き換えを可能としています。","datePublished":"2020-04-27T04:22:18.675Z","dateModified":"2020-04-27T04:22:18.675Z"}]},{"@type":"Answer","text":"うけとった変数をつかえるのは結局clickした後なので、ロジックがおかしいです\r\nあえてやるならこんな感じ","dateModified":"2020-04-27T00:19:53.089Z","datePublished":"2020-04-27T00:19:32.962Z","upvoteCount":0,"url":"https://teratail.com/questions/256761#reply-369705","comment":[{"@type":"Comment","text":"\r\n\r\n\r\n
","datePublished":"2020-04-27T00:20:27.867Z","dateModified":"2020-04-27T00:20:27.867Z"}]},{"@type":"Answer","text":"> 戻り値を変数に代入したい\r\n\r\n端的に言うと、イベントリスナの戻り値を受け取ることはできません。\r\n\r\nイベントリスナのようなコールバック関数は(__同期的タイミングで__)いつ実行されるかが定められていませんので、戻り値を直接受け取るのではなく、コールバック関数のスコープ外で予め宣言しておいた変数に代入して代用します。\r\n\r\n[EventListenerの管理](https://teratail.com/questions/248537#reply-359771) というご質問で、マウスイベントを例に回答させていただいことがあります。\r\n(こちらでは、``downPos`` を用いてイベント発火に関係なく参照できる変数を宣言しておき、リスナの返り値を受け取れないため、内部処理で代入しています)\r\n\r\nご参考になれば。","dateModified":"2020-04-26T20:42:08.398Z","datePublished":"2020-04-26T19:42:17.735Z","upvoteCount":4,"url":"https://teratail.com/questions/256761#reply-369680","comment":[]}],"breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"https://teratail.com","name":"トップ"}},{"@type":"ListItem","position":2,"item":{"@id":"https://teratail.com/tags/JavaScript","name":"JavaScriptに関する質問"}},{"@type":"ListItem","position":3,"item":{"@id":"https://teratail.com/questions/256761","name":"addEventListenerで実行させた関数の戻り値を変数に代入したい"}}]}}}
質問するログイン新規登録

Q&A

3回答

8162閲覧

addEventListenerで実行させた関数の戻り値を変数に代入したい

kentaka

総合スコア5

JavaScript

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

0グッド

2クリップ

投稿2020/04/26 19:23

編集2020/04/26 19:25

0

2

実行環境:GoogleChrome

JavaScript

1const btn = document.getElmentById( "button" ); 2let result; 3const number = 1; 4 5function a(){ 6 alert( number ); 7 if( number >= 1 ){ 8 return 1; 9 }else{ 10 return 0; 11 } 12} 13 14btn.addEventListener( "click", a, false );

htmlから取得したボタン要素をクリックすると、addEventListenerによって、a関数が呼び出されます。a関数は定数numberの値によって返す戻り値が異なりますが、この戻り値を変数resultに代入したいのですが、方法がわかりません。

JavaScript

1result = btn.oncilick = login();

のような書き方はそもそもできませんし、

JavaScript

1result = btn.addEventListener( "click" , a, false ); 2console.log( result );

とすることで、resultにaddEventListenerを代入しましたが、クリック前後のいずれもコンソールには「undefined」となっており、numberには何も定義されていないことがわかっています。

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

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

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

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

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

guest

回答3

0

戻り値を変数に代入したい

端的に言うと、イベントリスナの戻り値を受け取ることはできません。

イベントリスナのようなコールバック関数は(同期的タイミングで)いつ実行されるかが定められていませんので、戻り値を直接受け取るのではなく、コールバック関数のスコープ外で予め宣言しておいた変数に代入して代用します。

EventListenerの管理 というご質問で、マウスイベントを例に回答させていただいことがあります。
(こちらでは、downPos を用いてイベント発火に関係なく参照できる変数を宣言しておき、リスナの返り値を受け取れないため、内部処理で代入しています)

ご参考になれば。

投稿2020/04/26 19:42

編集2020/04/26 20:42
AkitoshiManabe

総合スコア5434

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

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

0

不具合の原因

resultにaddEventListenerを代入しましたが、クリック前後のいずれもコンソールには「undefined」となっており、numberには何も定義されていないことがわかっています。

既に回答されている通りですが、addEventListener 実行直後に返り値を参照しても、click イベント発火前なので、返り値は undefined になります

コールバック関数

期待通りの結果を得るには、click イベント発火直後に値を得る必要があります。

HTML

1<input id="test" type="button" value="test"> 2<script> 3'use strict'; 4const listener = { 5 number: 1, 6 handleEvent: function handleClick (event) { 7 clickEnd(this.number); 8 } 9}; 10 11function clickEnd(number) { 12 console.log(number); 13} 14 15document.getElementById('test').addEventListener('click', listener, false); 16</script>

コールバック関数 rev2

先のコードを「clickEnd関数もlistenerオブジェクトに格納」に変更すれば、変数スコープを汚さない実装になります。

HTML

1<input id="test" type="button" value="test"> 2<script> 3'use strict'; 4document.getElementById('test').addEventListener('click', { 5 number: 1, 6 handleEvent: function handleClick (event) { 7 this.clickEnd(); 8 }, 9 clickEnd: function clickEnd() { 10 console.log(this.number); 11 } 12}, false); 13</script>

参考情報

コールバック関数Promiseで検索すると、参考情報が見つかります。

Re: kentaka さん

投稿2020/04/27 04:14

編集2020/04/27 04:32
think49

総合スコア18196

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

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

think49

2020/04/27 04:22

余談ですが、 > const number = 1; const 宣言された変数値は書き換え不可の為、変数 number の値は「常に1」です。 従って、「if( number >= 1 )」は常に true となり、条件式の意味がなくなります。 本回答では、number をオブジェクトのプロパティに置くことで書き換えを可能としています。
guest

0

うけとった変数をつかえるのは結局clickした後なので、ロジックがおかしいです
あえてやるならこんな感じ

投稿2020/04/27 00:19

編集2020/04/27 00:19
yambejp

総合スコア118165

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

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

yambejp

2020/04/27 00:20

<script> window.addEventListener('DOMContentLoaded', ()=>{ let result=0; setInterval(()=>document.querySelector('#view').textContent=result,100); //resultを監視つづける const btn = document.getElementById( "button" ); const number = 1; function a(){ alert( number ); if( number >= 1 ){ result=1; }else{ result=0; } } btn.addEventListener( "click", a, false ); }); </script> <input type="button" value="button" id="button"> <div id="view"></div>
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.29%

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

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

質問する

関連した質問