Javascript 如何使用jQuery的on(..)动态绑定多个事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10767991/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 02:51:04  来源:igfitidea点击:

How to use jQuery's on(..) to dynamically bind to multiple events

javascriptjqueryjavascript-events

提问by empire29

I am trying to create leverage jQuery's .on() (ex-live()) to bind multiple events. It is working for elements which exist on document.ready, but if i dynamically add a second link after page load, my event handler isn't triggered.

我正在尝试利用 jQuery 的 .on() (ex-live()) 来绑定多个事件。它适用于 document.ready 上存在的元素,但如果我在页面加载后动态添加第二个链接,则不会触发我的事件处理程序。

This makes sense since the outer-most method iterates over the elements, and doenst listen for newly added DOM nodes, etc. The .on(..) is what listens for new DOM nodes, but requires an event name params, which I dont have until I have the DOM node.

这是有道理的,因为最外层的方法迭代元素,并且不监听新添加的 DOM 节点等。 .on(..) 是监听新 DOM 节点的,但需要一个事件名称参数,我不需要直到我拥有 DOM 节点。

Seems like a chick and the egg sort of situation.

看起来像小鸡和鸡蛋的情况。

Thoughts?

想法?

<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!")
            });
        }
    });
}); 

Update, The following does seem work either; $(this) doesnt appear to be in the right scope.

更新,以下似乎也有效;$(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'
    });
});     


Update 1:

更新 1:

I think my best bet will be to create special .on methods for all the methods I want to support like so:

我认为我最好的选择是为我想要支持的所有方法创建特殊的 .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 ...

回答by thecodeparadox

$('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!');
});

Sample example

示例

If you want something like live event then:

如果你想要像现场活动这样的东西,那么:

$('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!');
});

According to your last edit try this:

根据你上次的编辑试试这个:

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

Sample example for edit

编辑示例

and for live event delegation

和现场活动委托

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

回答by meze

Afraid you can't do this because you need to provide jQuery with either DOM elements or event names. You can bind events to new DOM elements manually or bind all possible events that can be in data-test-events (if you have 3-5 of them, with all DOM events it will become a silly and slow solution) and check if your element has one of them:

恐怕您不能这样做,因为您需要为 jQuery 提供 DOM 元素或事件名称。您可以手动将事件绑定到新的 DOM 元素或绑定所有可能在数据测试事件中的事件(如果您有 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!");
});?

回答by Paul Fenney

If you want to trigger an event whenever a matching element is added to the DOM, you might want to have a look at livequery - http://docs.jquery.com/Plugins/livequery.

如果您想在将匹配元素添加到 DOM 时触发事件,您可能需要查看 livequery - http://docs.jquery.com/Plugins/livequery

回答by jmort253

This code will allow you to register multiple event handlers as a function array. It's tested and working. See this jsfiddle demo and test cases.

此代码将允许您将多个事件处理程序注册为函数数组。它已经过测试并且可以正常工作。请参阅此jsfiddle 演示和测试用例

JavaScript:

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:

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>

Testing adding more elements:

测试添加更多元素:

Here are 3 test cases:

下面是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>");

Word of caution:

注意事项:

I noticed that one of your links has both the click and mouseover attached. While this code will handle multiple events per link, as demonstrated by the last test case, the click event will not fire if a mouseover event is present.

我注意到您的一个链接同时附加了点击和鼠标悬停。虽然此代码将处理每个链接的多个事件,如上一个测试用例所示,但如果存在鼠标悬停事件,则不会触发 click 事件。

This is not a fault in the above code but in the way events are processed, as demonstrated here:

这不是上述代码中的错误,而是事件处理方式的错误,如下所示:

// mouseover and mouseout fire, but not the click event
$('#container').on('mouseover mouseout click', '.js-test',function() { alert("afdas " + event.type); });