6

重複の可能性:
jQuery - すべてのイベントを DOM 要素にバインドするにはどうすればよいですか?

ある要素を完全にインタラクティブにできないようにしたい場合を想像してみてください。

もちろん、次のようにクリック イベントの防止のデフォルトをバインドすることもできます。

$('form *').bind('click', function(event) {
    event.preventDefault();
});

ただし、これは 1 つのイベントにすぎず、hover、focus、selectstart など、他にも多数のイベントがあります。

'click focus hover dblclick blur selectstart' のようにすべてを 1 行で指定することもできますが、これはあまり意味がなく、保守も容易ではありません。

では、イベントの種類を区別せずにイベント リスナーをバインドすることは可能ですか? たぶん、一部のネイティブ JavaScript リスナーで許可されているのでしょうか?

4

6 に答える 6

4

すべての要素が同じイベントをサポートしているわけではなく、すべてのイベントが同じように動作するわけではないため、そのような可能性はありません。イベント名を吐き出すスクリプトによって静的または動的に定義されているかどうかにかかわらず、常にイベントのリストを明示的に提供する必要があります。

イベント名の配列を作成するスクリプトにリンクしましたが、これらは 1 つの要素に対してのみ作成されます。もちろん、問題のすべての要素を列挙し、欠落しているイベントを追加する、より複雑で遅いスクリプトを使用してこれを生成する必要があります。特定のイベントが追加されているかどうかに関係なく、Javascript オブジェクトを連想配列として使用すると、高速に検索できます。

より良い提案

あなたがやろうとしていることは、高度に設計されたソリューションである可能性があります。一部の要素 (リンク、ボタン、またはその他のもの) を無効にする必要があるデモのクリック可能なインターフェイスを作成するときは、問題の要素を無効にする CSS クラスを定義し、後で無効にする簡単なスクリプトを作成します。

特定の要素で無効にするイベントを指定することで、これをさらに活用できます (デフォルトはclickイベントです)。

<!-- no events; use defaults -->
<a href="#" class="disable">No-follow link</a>
<button class="disable">Nothing happens</button>
<!-- provide events -->
<a href="#" class="disable" data-events="click blur">No-follow link</a>
<form class="disable" data-events="submit">...</form>

脚本

$(function() {

    var disable = function(evt) {
        evt.preventDefault();
        console.log("Prevented on " + evt.target.tagName);
    };

    $(".disable").each(function() {
        var ctx = $(this);
        ctx.bind(ctx.data("events") || "click", disable);
    });
});

スマート デフォルトの使用

上の例では、1 つのイベントのデフォルトを定義しています。clickイベント。これは問題なく、ほとんどの場合に機能しますが、すべてではありません。formたとえば、要素は無効にする必要がある送信イベントを常に定義する必要があります。そう。次に、スマートなデフォルト。また、抑制が必要なリスト イベントは通常短いという事実も考慮する必要があります。また、デフォルトを使用して大部分のケースをカバーすると、実際にデフォルトから逸脱する要素にわずかなオーバーヘッドしかありません。

$(function() {

    // click is still default event
    // this object defines per element events that aren't just click
    var extraDefaults = {
        form: "submit"
    };

    var disable = function(evt) {
        evt.preventDefault();
        console.log("Prevented on " + evt.target.tagName);
    };

    $(".disable").each(function() {
        var ctx = $(this);
        ctx.bind(
            // use inline-defined events
            ctx.data("events") ||
            // use extra defaults if present
            extraDefaults[this.tagName.toLower()] ||
            // just use default click event
            "click",
            disable);
    });
});
于 2012-08-31T11:03:51.170 に答える
1

次のようにほとんどのjQueryイベントをバインドできます。

$("#elementID").on(Object.keys(jQuery.event.fixHooks).join(" "), function(e) { 
    e.preventDefault(); 
});

これにより、次のイベントでDefaultが防止されます。

クリックdblclickmousedownmouseup mousemove mouseover mouseout mouseenter mouseenter mouseleave keydown keypress keyupcontextmenu

フィドル

于 2012-08-31T11:22:47.603 に答える
1

すべてのオプションを検討した後でも、このイベントの喧騒にはまだ便利ではないようです。また、各イベントのハンドラーを個別にバインドする必要があるため、スクリプトもパフォーマンスに影響します。

要素をカバーするために透明な背景を持つ div を上に置くだけで、はるかに単純なソリューションに固執するつもりです。

$('form').css('position','relative').prepend($('<div class="mask" style="position:absolute;z-index:9000;height:100%;width:100%;background-image:url(1px_transparent.png);"></div>'));

これは要素の全領域を自動的に塗りつぶします。代わりに、半透明の画像を使用して、これがロックされた要素であることをユーザーが理解できるようにし、混乱を招かないようにすることもできます。

ロックを解除するには、要素から .mask div を削除するだけです。

編集

新しいフィドル: http://jsfiddle.net/YAdXk/8/

実際には、tabindex属性をに設定することでタブ移動を無効にすることができます-1

.find('input,textarea,select').attr('tabindex','-1');

更新されたフィドルにより、タブ移動も防止されます。

EDIT2

lock()または、任意の要素でカスタムとunlock()関数を使用するように jQuery を拡張できます。

最後のフィドルを参照してください: http://jsfiddle.net/YAdXk/13/

(function($) {
$.fn.lock= function() {
    return this.each(function() {
        $(this).css('position','relative').prepend($('<div class="mask" style="position:absolute;z-index:9000;height:100%;width:100%;background-image:url('+transparent_picture+');"></div>')).find('input,textarea,select').attr('tabindex','-1');
    });
};   

$.fn.unlock= function() {
    return this.each(function() {
        $(this).find('*').removeAttr('tabindex').filter('.mask').remove();
   });
};

})( jQuery )
于 2012-08-31T12:12:35.130 に答える
0
var all_events = "click blur focus mouse"; //etc...

$('form *').bind(all_events, function(event) {
        event.preventDefault();
});

メンテナンスが簡単になりました;)

于 2012-08-31T11:16:56.483 に答える
0

jQuery はここですべてのショートカット イベント タイプを定義するため、その文字列を使用してすべてのイベントを保存し、再利用することができます。

var events = "blur focus focusin focusout load resize scroll unload click dblclick " +
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
"change select submit keydown keypress keyup error contextmenu";

$('button').bind(events, function() {
    // hey
});
于 2012-08-31T11:18:40.350 に答える
0

はい、一度に 1 つのタイプのすべてのイベントをキャッチすることは可能です! ただし、すべてのイベント タイプを明示的に指定する必要があります。

のコード例"form *"は非効率的であり、コードの実行後に追加された要素のイベントをキャッチしません。

$("form")JavaScript イベントのバブリング効果により、最上位の要素 (または)に catch all イベント ハンドラーを割り当て、$("body")それに追加preventDefault()することができます。

コード例:

$("a").on("click", function() {
    $("body").append("<p>Clicked...</p>");
});
$("body").on("click", function(e) {
  e.preventDefault();
});

と:

<div>
    <p><a href="#" target="_blank">Click on me</a></p>
</div>​

親要素のすべてのイベントをキャッチするという概念は、多くの場合、イベント デリゲーションと呼ばれます。

于 2012-08-31T11:42:24.263 に答える