web-dev-qa-db-ja.com

addEventListenerリスナー関数に引数を渡す方法

状況はやや似ています -

var someVar = some_other_function();
someObj.addEventListener("click", function(){
    some_function(someVar);
}, false);

問題は、someVarの値がaddEventListenerのリスナー関数内に表示されていないことです。この場合、新しい変数として扱われる可能性があります。

242
Abhishek Yadav

あなたが書いたコードには全く問題がありません。 some_functionsomeVarの両方がアクセス可能であるべきです。

function() { some_function(someVar); } 

作成されました。

アラートが探している値を提供しているか確認し、それが無名関数の範囲内でアクセス可能であることを確認してください(someVarの呼び出しの隣に同じaddEventListener変数を操作するコードが他にない場合)

var someVar; 
someVar = some_other_function();
alert(someVar);
someObj.addEventListener("click", function(){
    some_function(someVar);
}, false);
179
Sergey Ilinsky

イベントのtarget属性から引数を取得しないのはなぜですか?

例:

var someInput = document.querySelector('input');
someInput.addEventListener('click', myFunc, false);
someInput.myParam = 'This is my parameter';
function myFunc(evt)
{
  window.alert( evt.target.myParam );
}

JavaScriptはプロトタイプ指向の言語です、覚えておいてください!

282
Zaloz

この質問は古くなっていますが、後世のためにES5の.bind()を使用した代替手段を提供したいと思いました。 :)

function some_func(otherFunc, ev) {
    // magic happens
}
someObj.addEventListener("click", some_func.bind(null, some_other_func), false);

最初のパラメータをbindに渡す引数としてあなたのリスナ関数を設定する必要があることに注意してください(もう一方の関数)。2番目のパラメータは(最初のパラメータではなく)イベントになります。

51
Brian Moore

関数を変数として宣言することで、引数付きのeventlistenerを追加および削除できます。

myaudio.addEventListener('ended',funcName=function(){newSrc(myaudio)},false);

newSrcは、myaudioをパラメータとするメソッドです。funcNameは、関数名変数です。

myaudio.removeEventListener('ended',func,false);でリスナーを削除できます

19
Ganesh Krishnan

かなり古い質問ですが、私は今日同じ問題を抱えていました。私が見つけた最も明確な解決策は、 カレーの概念を使うことです。

そのためのコード:

someObj.addEventListener('click', some_function(someVar));

var some_function = function(someVar) {
    return function curried_func(e) {
        // do something here
    }
}

カリー化された関数に名前を付けることによって、後で実行するときにObject.removeEventListenerを呼び出してeventListenerを登録解除することができます。

17
tomcek112

必要なすべての引数を 'bind'でバインドすることができます。

root.addEventListener('click', myPrettyHandler.bind(null, event, arg1, ... ));

このようにして、eventarg1、およびその他のものをmyPrettyHandlerに渡すことができます。

http://passy.svbtle.com/partial-application-in-javascript-using-bind

14

あなたは クロージャ として知られているjavascript機能を介して(参照ではなく)値でsomevarを渡すことができます

var someVar='Origin';
func = function(v){
    console.log(v);
}
document.addEventListener('click',function(someVar){
   return function(){func(someVar)}
}(someVar));
someVar='changed'

あるいはwrapEventCallbackのような一般的な折り返し関数を書くこともできます。

function wrapEventCallback(callback){
    var args = Array.prototype.slice.call(arguments, 1);
    return function(e){
        callback.apply(this, args)
    }
}
var someVar='Origin';
func = function(v){
    console.log(v);
}
document.addEventListener('click',wrapEventCallback(func,someVar))
someVar='changed'

これはwrapEventCallback(func,var1,var2)のようなものです。

func.bind(null, var1,var2)
10
ahuigo

someVarの値は、リスナーからではなく、some_function()コンテキスト内でのみアクセス可能であるべきです。リスナーの中にそれを入れたいのなら、次のようにしなければなりません。

someObj.addEventListener("click",
                         function(){
                             var newVar = someVar;
                             some_function(someVar);
                         },
                         false);

代わりにnewVarを使用してください。

もう1つの方法は、リスナーでさらに使用するためにsome_function()からsomeVar値を返すことです(新しいローカル変数として)。

var someVar = some_function(someVar);
9
Thevs

これはさらに別の方法です(これはforループの中で動作します)。

var someVar = some_other_function();
someObj.addEventListener("click", 

function(theVar){
    return function(){some_function(theVar)};
}(someVar),

false);
9
Hello World

Function.prototype.bind() は、ターゲット関数を特定のスコープにバインドし、オプションでターゲット関数内にthisオブジェクトを定義する方法です。

someObj.addEventListener("click", some_function.bind(this), false);

あるいは、例えばループの中で、字句の範囲の一部を捉えるには:

someObj.addEventListener("click", some_function.bind(this, arg1, arg2), false);

最後に、ターゲット関数内でthisパラメーターが必要ない場合

someObj.addEventListener("click", some_function.bind(null, arg1, arg2), false);
7
eclos

つかいます

   el.addEventListener('click',
    function(){
        // this will give you the id value 
        alert(this.id);    
    },
false);

そして、この無名関数にカスタム値を渡したい場合は、それを行う最も簡単な方法があります。

 // this will dynamically create property a property
 // you can create anything like el.<your  variable>
 el.myvalue = "hello world";
 el.addEventListener('click',
    function(){
        //this will show you the myvalue 
        alert(el.myvalue);
        // this will give you the id value 
        alert(this.id);    
    },
false);

私のプロジェクトでは完璧に動作します。これが役立つことを願っています

7
kta

また試してみてください(IE8 + Chrome。私はFFを知らない)。

function addEvent(obj, type, fn) {
    eval('obj.on'+type+'=fn');
}

function removeEvent(obj, type) {
    eval('obj.on'+type+'=null');
}

// Use :

function someFunction (someArg) {alert(someArg);}

var object=document.getElementById('somObject_id') ;
var someArg="Hi there !";
var func=function(){someFunction (someArg)};

// mouseover is inactive
addEvent (object, 'mouseover', func);
// mouseover is now active
addEvent (object, 'mouseover');
// mouseover is inactive

誤字がないことを願います:-)

3
DMike92

1つの方法は、外部関数を使ってこれを行うことです。

elem.addEventListener('click', (function(numCopy) {
  return function() {
    alert(numCopy)
  };
})(num));

このように無名関数を括弧で囲んですぐに呼び出す方法は、IIFEと呼ばれます(即時呼び出し関数式)。

あなたは http://codepen.io/froucher/pen/BoWwgz で2つのパラメータで例をチェックすることができます。

catimg.addEventListener('click', (function(c, i){
  return function() {
    c.meows++;
    i.textContent = c.name + '\'s meows are: ' + c.meows;
  }
})(cat, catmeows));
3
Felipe

EventListenerのコールバック関数に引数を送るには、独立関数を作成し、その独立関数に引数を渡す必要があります。

これはあなたが使うことができる素晴らしい小さなヘルパー関数です。上記の "hello world"の例に基づいています。)

また、リスナーをきれいに削除できるように、関数への参照を維持することも必要です。

// Lambda closure chaos.
//
// Send an anonymous function to the listener, but execute it immediately.
// This will cause the arguments are captured, which is useful when running 
// within loops.
//
// The anonymous function returns a closure, that will be executed when 
// the event triggers. And since the arguments were captured, any vars 
// that were sent in will be unique to the function.

function addListenerWithArgs(elem, evt, func, vars){
    var f = function(ff, vv){
            return (function (){
                ff(vv);
            });
    }(func, vars);

    elem.addEventListener(evt, f);

    return f;
}

// Usage:

function doSomething(withThis){
    console.log("withThis", withThis);
}

// Capture the function so we can remove it later.
var storeFunc = addListenerWithArgs(someElem, "click", doSomething, "foo");

// To remove the listener, use the normal routine:
someElem.removeEventListener("click", storeFunc);
3
bob

要素を見つけてそれにlistnerを追加するためにループ内で使用していたので、これにはまりませんでした。あなたがループでそれを使用しているなら、これは完全に動作します

for (var i = 0; i < states_array.length; i++) {
     var link = document.getElementById('apply_'+states_array[i].state_id);
     link.my_id = i;
     link.addEventListener('click', function(e) {   
        alert(e.target.my_id);        
        some_function(states_array[e.target.my_id].css_url);
     });
}
2
Suneel Kumar

bindを使用して関数を呼び出すのを間違えない限り、実際にはbindメソッドによって返される新しい関数が作成されます。これは後で問題を引き起こしたり、イベントリスナを削除したい場合には基本的に無名関数のようなものです。

// Possible:
function myCallback() { /* code here */ }
someObject.addEventListener('event', myCallback);
someObject.removeEventListener('event', myCallback);

// Not Possible:
function myCallback() { /* code here */ }
someObject.addEventListener('event', function() { myCallback });
someObject.removeEventListener('event', /* can't remove anonymous function */);

それを念頭に置いてください。

ES6を使用している場合は、推奨されているのと同じ方法を実行できますが、少しきれいになります。

someObject.addEventListener('event', () => myCallback(params));
2
developer82

次のアプローチは私にはうまくいきました。 ここ から変更されました。

function callback(theVar) {
  return function() {
    theVar();
  }
}

function some_other_function() {
  document.body.innerHTML += "made it.";
}

var someVar = some_other_function;
document.getElementById('button').addEventListener('click', callback(someVar));
<!DOCTYPE html>
<html>
  <body>
    <button type="button" id="button">Click Me!</button>
  </body>
</html>
1
Nate
    var EV = {
        ev: '',
        fn: '',
        elem: '',
        add: function () {
            this.elem.addEventListener(this.ev, this.fn, false);
        }
    };

    function cons() {
        console.log('some what');
    }

    EV.ev = 'click';
    EV.fn = cons;
    EV.elem = document.getElementById('body');
    EV.add();

//If you want to add one more listener for load event then simply add this two lines of code:

    EV.ev = 'load';
    EV.add();
1

あなたが必要です:

newElem.addEventListener('click', {
    handleEvent: function (event) {
        clickImg(parameter);
    }
});
0
Victor Behar

ニース一行代替

element.addEventListener('dragstart',(evt) => onDragStart(param1, param2, param3, evt));
function onDragStart(param1, param2, param3, evt) {

 //some action...

}
0
Gon82

次のコードは私にとってはうまくいきました(firefox):

for (var i=0; i<3; i++) {
   element = new ...   // create your element
   element.counter = i;
   element.addEventListener('click', function(e){
        console.log(this.counter);
        ...            // another code with this element
   }, false);
}

出力:

0
1
2
0
Šerg
    $form.addEventListener('submit', save.bind(null, data, keyword, $name.value, myStemComment));
    function save(data, keyword, name, comment, event) {

これで、イベントが正しく渡されました。

0
chovy

次の答えは正しいですが、yuicompressorを使ってjsファイルを圧縮したとすると、IE8では以下のコードは機能しません。 (実際には、依然としてほとんどの米国人がIE8を使用しています)

var someVar; 
someVar = some_other_function();
alert(someVar);
someObj.addEventListener("click",
                         function(){
                          some_function(someVar);
                         },
                         false);

だから、我々は次のように上記の問題を修正することができ、それはすべてのブラウザで正常に動作します

var someVar, eventListnerFunc;
someVar = some_other_function();
eventListnerFunc = some_function(someVar);
someObj.addEventListener("click", eventListnerFunc, false);

本番環境でjsファイルを圧縮している人にとっては便利なことです。

がんばろう!!

0
Asik

おそらく最適ではありませんが、非常に精通していない人にとっては十分に単純です。 addEventListenerを呼び出す関数をそれ自身の関数に入れます。このようにして、渡された関数値はそれぞれ独自のスコープを維持し、必要に応じてその関数を反復処理できます。

例画像とファイル名のプレビューをキャプチャしてレンダリングする必要があるので、ファイルの読み取りを行いました。複数ファイルのアップロードタイプを利用する場合、非同期の問題を避けるために少し時間がかかりました。異なるファイルをアップロードしたにもかかわらず、誤ってすべてのレンダリングに同じ「名前」が表示されることがあります。

もともと、すべてのreadFile()関数はreadFiles()関数内にありました。これは非同期スコープの問題を引き起こしました。

    function readFiles(input) {
      if (input.files) {
        for(i=0;i<input.files.length;i++) {

          var filename = input.files[i].name;

          if ( /\.(jpe?g|jpg|png|gif|svg|bmp)$/i.test(filename) ) {
            readFile(input.files[i],filename);
          }
       }
      }
    } //end readFiles



    function readFile(file,filename) {
            var reader = new FileReader();

            reader.addEventListener("load", function() { alert(filename);}, false);

            reader.readAsDataURL(file);

    } //end readFile
0
Spoo

この解決策は見た目に良いかもしれません

var some_other_function = someVar => function() {
}

someObj.addEventListener('click', some_other_function(someVar));

またはバインド変数も良いでしょう

0
fnclovers

すべての関数の中には特別な変数があります:arguments。あなたはあなたのパラメータを無名パラメータとして渡し、arguments変数を通して(順番に)アクセスすることができます。

例:

var someVar = some_other_function();
someObj.addEventListener("click", function(someVar){
    some_function(arguments[0]);
}, false);
0
StanE