11

複数のイベントをバインドするために、レバレッジjQueryの.on()(ex-live())を作成しようとしています。document.readyに存在する要素に対して機能していますが、ページの読み込み後に2番目のリンクを動的に追加すると、イベントハンドラーがトリガーされません。

最も外側のメソッドが要素を反復処理し、新しく追加されたDOMノードなどをリッスンするのでこれは理にかなっています。.on(..)は新しいDOMノードをリッスンするものですが、イベント名paramsが必要です。 DOMノードができるまで持っています。

ひよこと卵のような状況のようです。

考え?

<a href="/foo.html" class="js-test" data-test-events="['click', 'mouseover']">Test 1</a>
<a href="/foo.html" class="js-test" data-test-events="['mouseout']">Test 2</a>

$(function() { 
    $('.js-test').each(function() { 
        var $this = $(this);
        var e, events = $this.data('test-events');

        for(e in events) {
            $this.on(events[e], function() {
                console.log("hello world!")
            });
        }
    });
}); 

更新、以下も機能するようです。$(this)は正しいスコープにないようです。

<a href="/foo.html" class="js-test" data-test-events="click mouseover">Test 1</a>
<a href="/foo.html" class="js-test" data-test-events="mouseout">Test 2</a>

$(function() { 
    $('.js-test').on($(this).data('test-events'), function() { 
        // call third party analytics with data pulled of 'this'
    });
});     

アップデート1:

私の最善の策は、次のようにサポートしたいすべてのメソッドに対して特別な.onメソッドを作成することだと思います。

$(document).on('click', '.js-test[data-test-events~="click"]' function(event) {
    record(this, event);
});

$(document).on('mouseover', '.js-test[data-test-events~="mouseover"]', function(event) {
    record(this, event);
});

 ... etc ...
4

4 に答える 4

15
$('a.js-test').on('click mouseover', function(event) {
  // you can get event name like following
  var eventName = event.type; // return mouseover/ click
  console.log(eventName);
  // you code
  console.log('Hello, World!');
});

サンプル例

ライブイベントのようなものが必要な場合は、次のようにします。

$('body').on('click mouseover', 'a.js-test', function(event) {
  // you can get event name like following
  var eventName = event.type; // return mouseover/ click
  console.log(eventName);
  // you code
  console.log('Hello, World!');
});

あなたの最後の編集によると、これを試してください:

$('.js-test').on($('.js-test').data('test-events'), function() {
    console.log("hello world!")
});

編集用のサンプル例

ライブイベントの委任用

$('body').on($('.js-test').data('test-events'), '.js-test', function() {
    console.log("hello world!")
});
于 2012-05-26T16:29:33.800 に答える
1

jQueryにDOM要素またはイベント名のいずれかを提供する必要があるため、これを行うことはできません。イベントを新しいDOM要素に手動でバインドするか、data-test-eventsに含まれる可能性のあるすべてのイベントをバインドして(3〜5個ある場合、すべてのDOMイベントで、ばかげた遅い解決策になります)、要素には次のいずれかがあります。

$('body').on("mouseover click mouseout mouseenter mouseleave", '.js-test', function(e) {
    if (!$.inArray(e.type, $(this).data('test-events').split(' '))) {
        return;
    }
    console.log("hello world!");
});​
于 2012-05-26T22:20:00.830 に答える
0

一致する要素が DOM に追加されるたびにイベントをトリガーしたい場合は、 livequery - http://docs.jquery.com/Plugins/livequeryを参照してください。

于 2012-05-26T23:35:49.663 に答える
0

このコードにより、複数のイベント ハンドラーを関数配列として登録できます。テスト済みで動作しています。このjsfiddle デモとテスト ケースを参照してください。

JavaScript:

$(document).ready(function() {
    eventFnArray = [];
    eventFnArray["click"] = function(e) { 
        if(e.type != "click") return ;
        alert("click event fired - do xyz here");
        // do xyz
    };
    eventFnArray["mouseover"] = function(e) { 
        if(e.type != "mouseover") return ;
        alert("mouseover fired - do abc here"); 
        // do abc
    };
    eventFnArray["mouseout"] = function(e) { 
        if(e.type != "mouseout") return ;
        alert("mouseout fired - do JKL here"); 
        // do JKL
    };

    $('.js-test').each( (function(fn) { 

        return function(i) {   
            if(i != 0) return;
            var _that = this;
            var events = [];
            events = $(_that).attr("data-events").split(" ");

 //           alert($(_that).attr("data-events") + " : " + events.join(" "));

            $(this).parent().on(
                events.join(" "), 
                '.js-test', 
                function() {
                    console.info("hello - this is the " + event.type + " event");
      //             alert("data-events = " + $(this).attr("data-events") + " : event.type = " + event.type);
                    // delegate to the correct event handler based on the event type
                    if($(this).attr("data-events").indexOf(event.type) != -1)
                        fn[ event.type ](event);
                }
            );
        } 
    })(eventFnArray));    // pass function array into closure

});

HTML:

<div id="container">
    <a href="#" class="js-test" data-events="click mouseout mouseover">Test 1</a>
    <a href="#" class="js-test" data-events="mouseover">Test 2</a>
</div>

さらに要素を追加するテスト:

以下に 3 つのテスト ケースを示します。

// adds a link with the click event attached.
$('#container').append("<a href='#' class='js-test' data-events='click'>TEst333</a>");

// adds a link with the mouseover event 
$('#container').append("<a href='#' class='js-test' data-events='mouseover'>TEst444</a>");

// adds a link with mouseout
$('#container').append("<a href='#' class='js-test' data-events='mouseout'>TEs555</a>");

// adds a link with both mouseover and mouseout attached
$('#container').append("<a href='#' class='js-test' data-events='mouseout mouseover'>TEstLast</a>");

// mouseout and click
$('#container').append("<a href='#' class='js-test' data-events='mouseout click'>TEstLastForREAL</a>");

注意事項:

リンクの 1 つにクリックとマウスオーバーの両方が添付されていることに気付きました。最後のテスト ケースで示したように、このコードはリンクごとに複数のイベントを処理しますが、マウスオーバー イベントが存在する場合、クリック イベントは発生しません。

これは上記のコードの問題ではなく、次のようにイベントの処理方法に問題があります。

// mouseover and mouseout fire, but not the click event
$('#container').on('mouseover mouseout click', '.js-test',function() { alert("afdas " + event.type); });
于 2012-05-29T03:55:11.390 に答える