2016-03-28 13 views
0

私はこの小さなハックを実行して、特定の関数に異なるタイミングで複数のイベントを追加する必要があります。DOMオブジェクトを持たない関数にイベントをバインドする方法

$("#handler").bind("click",function(){ alert(1); }); 
$("#handler").bind("click",function(){ alert(2); }); 
$("#handler").bind("click",function(){ alert(3); }); 

私は単に$("#handler").click()を呼び出すと、それらのすべてのイベントを発生させます。

質問:これは、バインドする任意のHTMLオブジェクトを作成せずに行うことができますか?

標準のJavaScript関数でこれを行うのと同じことは何ですか?

function handler(){ alert(1); } 
function handler(){ alert(2); } 
function handler(){ alert(3); } 
handler(); 

^これは、ちょうど最後の1を発射し、すべての3にはどうすれば関数に代わりのDOM要素に複数のイベントをバインドすることができませんか?

+0

イベントを1回だけバインドします。 – Tushar

+0

@ Tusharはい、当然のことですが、私は正しい質問をする必要はありませんか?問題は、バインディングが実行時のさまざまな部分で発生することです。しかし、入力のおかげで – RealWorldCoder

+0

あなたはループを使用することを考慮している?最後の読み込み関数が最初の関数と同じであったため、最後の関数を呼び出します。 –

答えて

1

個々の機能をグループ化してより大きな「機能セット」にグループ化する方法を探している場合は、後ですべてを同時にトリガーすることができます。これは、javascriptのSetオブジェクトで実現できます。例:私は言ってあなたに基づいて、あなたの質問のこの解釈を基づかてる

// define the Set object that you want to store the functions inside: 
var handlerFunctionCollection = new Set(); 


// add individual functions to the Set: 
handlerFunctionCollection.add(function(){ console.log(1); }); 
handlerFunctionCollection.add(function(){ console.log(2); }); 
handlerFunctionCollection.add(function(){ console.log(3); }); 

// trigger all functions in set using forEach on Set 
// and call() method on stored Function object: 
handlerFunctionCollection.forEach(function(handlerFunction) { 
    if(handlerFunction instanceof Function) { 
     handlerFunction.call(); 
    } 
}); 

注:私は単に$("#handler").click()を呼び出すと

が、それはすべてのこれらのイベントを発生させます。あなたが実際にイベントに直接機能をバインドする方法を探していませんが、そうでない場合は手動でclickイベントをトリガすることがないための方法は、一つの場所に複数の機能をトリガすることを提案

SetArray以上のオブジェクトまたは同様のコレクションを使用することの利点は、あなたがいた場合は、複数回(誤って、またはそれ以外)と同じ機能を追加しようとするようにSetのメンバーは、ユニークであるということです、追加FunctionオブジェクトうSetでは1回しか発生しないため、forEachをトリガするときにトリガされるのは、追加されるたびにではなくSetに1回だけ存在するためです。

1

JavaScriptでは、すべての関数は実際には関数オブジェクトです。

Javascriptでは、同じ名前の複数の関数を定義すると、最後の関数が実際に実行されます。 JavaScript functionsは、多くの言語ではと似ていません。他の言語では、渡されるパラメータの数に応じて2つの別個の関数としてfuncA(parm1)funcA(parm1, parm2)が実行されます。

あなたの場合、関数スコープ内のさまざまな状況に対応できる方法で1つの関数を宣言する必要があります。

0

ObserverまたはPublisher/Subscriber ("PubSub")のコンセプトを探しています。

これは非常に簡単に自分で作成することができます。
以下のデモコードを実行するための、アプリケーション専用のコード(DOM対応のものなど)を少しきれいにしたものです。あなたがPublisherライブラリを持っていたし、自分のアプリで上記のリスナー関数を持っていたと仮定すると、

const trigger = $("#Trigger"); 
const system = Publisher(); 

// add my listeners 
system 
.on("trigger", triggerContentUpdate) 
.on("update", updateView) 
.on("update", logUpdate); // note how I have two things bound to the same event 

// something that kicks off the "trigger" event 
// could be a timer, or an AJAX call, or anything else 
trigger.onclick =() => system.fire("trigger"); 

、これはほとんどすべてあなたが仕事下記のデモを作るために書く必要があるだろうJSのです。

私が実際に書いたライブラリとデモの実装は以下の通りです。もちろん

/*** LIBRARY CODE ***/ 
 

 
// Channel.js 
 
const Channel =() => { 
 
    const listeners = new Set(); 
 

 
    const channel = { 
 

 
    listen(listener) { 
 
     listeners.add(listener); 
 
     return channel; 
 
    }, 
 

 
    ignore(listener) { 
 
     listeners.delete(listener); 
 
     return channel; 
 
    }, 
 

 
    notify(data) { 
 
     listeners.forEach(react => react(data)); 
 
     return channel; 
 
    } 
 
    }; 
 

 
    return channel; 
 
}; 
 

 
// Publisher.js 
 
const Publisher =() => { 
 
    const channels = {}; 
 

 
    function getChannel(name) { 
 
    const channel = channels[name] || Channel(); 
 
    channels[name] = channel; 
 
    return channel; 
 
    } 
 

 
    const publisher = { 
 

 
    on(name, subscriber) { 
 
     getChannel(name).listen(subscriber); 
 
     return publisher; 
 
    }, 
 

 
    off(name, subscriber) { 
 
     getChannel(name).ignore(subscriber); 
 
     return publisher; 
 
    }, 
 

 
    fire(name, data) { 
 
     getChannel(name).notify(data); 
 
     return publisher; 
 
    } 
 

 
    }; 
 

 
    return publisher; 
 
} 
 

 
/*** END OF LIBRARY CODE ***/ 
 

 

 

 
/*** APPLICATION CODE ***/ 
 

 
// const Publisher = require("publisher"); or import Publisher from "publisher"; 
 

 
const $ = selector => document.querySelector(selector); 
 

 
const trigger = $("#Trigger"); 
 
const input = $("#Content"); 
 
const output = $("#Result"); 
 
const log = $("#Log"); 
 

 
const system = Publisher(); 
 

 
system 
 
    .on("trigger",() => { 
 
    const content = input.value; 
 
    system.fire("update", content); 
 
    }) 
 
    .on("update", content => output.value = content) 
 
    // normally, I never use innerHTML, and my logic and view are never attached, but this is dirt-simple now 
 
    .on("update", content => log.innerHTML += `<li>[${ (new Date()).toISOString() }]: ${content}</li>`); 
 

 
trigger.onclick =() => system.fire("trigger"); 
 

 
/*** END OF APPLICATION CODE ***/
<h3>Input</h3> 
 
<div> 
 
    <input id="Content" type="text"> 
 
    <button id="Trigger">Update</button> 
 
</div> 
 
<h3>Output</h3> 
 
<output id="Result"></output> 
 

 
<h3>Log</h3> 
 
<ul id="Log"></ul>

、私はすべての方法ダウンして行くために、比較的近代的な構文を使用していませんが、古い互換性のあるコードに書き換え、またはtranspiledとポリフィルを与えることはできません何もしていますIE7/8へのサポート

私が任意のオブジェクトを出版社にしたいのであれば、私はそれをやや早く行うことができます。

+0

これはjavascriptですか? – RealWorldCoder

+1

@RealWorldCoderそれは100%JavaScriptです。ネイティブ、通常、毎日のJavaScript。すべてのarrow関数を古くなった 'function'で置き換えることができます。' Set'を '[]'で置き換えることができ、重複したリスナーを挿入しないようにチェックすることができます。すべての 'const'を' var'で置き換えることができます。そしてあなたは昔のJSに戻ります。あなたがこれを実行している場合は、ChromeやFireFox、または自尊心のあるブラウザなどと言いますが、この例はうまくいくはずです。 – Norguard

+0

@RealWorldCoderは、 'Set'や' Map'のようなオブジェクトに対してpolyfillと併用すると、ES6(上記)をES3(IE8 +)互換のコードに変換するhttp://BabelJS.ioを見ています。 – Norguard

関連する問題