私が記述していることは、より標準的なアプローチではあまりアドバイスされていない可能性があります。そうであれば、有効な答えになります。カスタム.on()および.off()操作をjqueryのカスタムイベントに追加する標準的な方法は何ですか?
独自のカスタムイベントを作成しているとしますが、on()およびoff()の各ステップでは、その要素に対してアクションを実行する必要があります。
私の例のシナリオでは、要素が500 msタイムパス内で1回、2回、または3回クリックされたときに発生する「multiclick」というカスタムjqueryイベントを作成します。
私の最初のアイデアはオフ、上の機能を拡張し、トリガーなどのように私の独自のイベントを追加することです:
(function($)
{
var oldOn = $.fn.on;
var oldOff = $.fn.off;
var oldTrigger = $.fn.trigger;
// events [, selector ] [, data ], handler
// events [, selector ] [, data ]
// Note: this does not implement selector or data for multiclick
$.fn.on = function(events, handler)
{
if (events.split(/\s+/).some(function(event) { return event == 'multiclick'; }))
{
$(this).each(function()
{
if (!Array.isArray($(this).data('multiclick-state')))
{
$(this).data('multiclick-state', []);
}
var clicks = 0;
var clicksTimer = null;
var clickHandler = function(e)
{
clicks++;
if (clicks == 1)
{
clicksTimer = setTimeout(function()
{
handler(e, clicks);
clicks = 0;
}, 500);
}
else if (clicks == 3)
{
clearTimeout(clicksTimer);
handler(e, clicks);
clicks = 0;
}
};
$(this).data('multiclick-state').push(
{
handler: handler,
clickHandler: clickHandler
});
$(this).click(clickHandler);
});
arguments[0] = arguments[0].replace('multiclick', '');
}
return oldOn.apply(this, arguments);
};
// events [, selector ] [, handler ]
// events [, selector ]
// events
// Note: this does not implement selector
$.fn.off = function(events, handler)
{
if (events.split(/\s+/).some(function(event) { return event == 'multiclick'; }))
{
$(this).each(function()
{
if (!Array.isArray($(this).data('multiclick-state')))
{
$(this).data('multiclick-state', []);
}
$(this).data('multiclick-state', $(this).data('multiclick-state').filter(function(state)
{
if (handler == undefined || state.handler === handler)
{
$(this).off('click', state.clickHandler);
return false;
}
return true;
}.bind(this)));
});
arguments[0] = arguments[0].replace('multiclick', '');
}
return oldOff.apply(this, arguments);
};
// eventType [, extraParameters ]
// event, [, extraParameters ]
// Note: I wrote this in case trigger is changed to handle multiple events. Currently it does not. Also I don't support the second overloaded signature
$.fn.trigger = function(events)
{
if (typeof events == 'string' && events.split(/\s+/).some(function(event) { return event == 'multiclick'; }))
{
$(this).each(function()
{
if (!Array.isArray($(this).data('multiclick-state')))
{
$(this).data('multiclick-state', []);
}
// This doesn't support disabling bubbling or stopPropogation, would have to think about it. Very ad-hoc.
$(this).data('multiclick-state').forEach(function(data)
{
data.clickHandler();
});
});
arguments[0] = arguments[0].replace('multiclick', '');
}
return oldTrigger.apply(this, arguments);
};
$.fn.multiclick = function(callback)
{
if (arguments.length == 1)
{
return $(this).on('multiclick', callback);
}
else
{
return $(this).trigger('multiclick');
}
return this;
};
}(jQuery));
私は本当にこれが最も完全なソリューションである保証が、それはありませんよ基本的なアプローチを示しています。そして、それは通常のjqueryのイベントのように使用することになります。
function multiclick(e, clicks)
{
console.log(clicks);
}
// $(document).on('multiclick', multiclick);
$(document).multiclick(multiclick);
//$(document).off('multiclick');
//$(document).off('multiclick', multiclick);
jsfiddle例:https://jsfiddle.net/rhsswfho/1/
これは、すべてのちょうどヘルパー関数とかなり直接的あるいはjqueryのに組み込まれるべきもののために多くのコードのように思えますしかし、私は誰も見つけません。言い換えれば、やや壊れやすく、すべてのオン、オフ、トリガコールにパフォーマンス上のペナルティが加わります。
これを行うための標準的なアプローチ、またはそのような問題を処理するためのより標準的なアプローチは何ですか?
あなたが解決しようとしているより高いレベルの問題を本当に明らかにしません。これはちょうど[XY問題]のように聞こえます(https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – charlietfl
@charlietflローカライズされたソリューションを作成しようとしていました。本質的に、はるかに簡単であることが判明した文書にバインドする代わりに:http://jsfiddle.net/f35u0fw2 – Sirisian
まだ適切な問題の説明がありません。あなたは、どこかに散らばっている文章やコードがたくさんあり、期待どおりに動いているかどうかは具体的に言及していません。 [ask] – charlietfl