【问题标题】:How do I manually trigger a delegated event with jQuery?如何使用 jQuery 手动触发委托事件?
【发布时间】:2019-06-13 03:55:56
【问题描述】:

jQuery 有没有办法手动触发委托事件处理程序?

以下示例代码:

<div class="container">
  <input type="button" value="Hello">
  <span class="output"></span>
</div>
​
<script>
  $('.container')
    .on('click', '[type=button]', function(e) {
      $(e.delegateTarget).find('.output').text($(this).val());
    })
    .find('[type=button]').triggerHandler('click');​
</script>

(在线:http://jsfiddle.net/TcHBE/

我原以为这会起作用,并且文本“Hello”会出现在跨度中,而无需实际单击按钮,但事实并非如此。

我在处理程序中使用e.delegateTarget,因为.ouput 元素与按钮的关系不为已知,除了.container 中的某个位置。这就是我首先使用委托事件处理程序的原因。

更新:

我也使用triggerHandler,因为该事件在我不想触发的真实代码中具有默认行为。 (在实际代码中,该事件是Bootstrap Modal plugin 的自定义事件hide,但我实际上并不想在页面加载时触发事件处理程序时隐藏模式)。

我可以将处理程序提取到一个命名函数中并直接调用它,但是由于使用了e.delegateTarget,这会使方法构造更加复杂。

【问题讨论】:

  • 更新您的代码以显示实际问题。不清楚您是否要阻止其他事件处理程序或默认操作发生。

标签: jquery


【解决方案1】:

您可以手动创建一个 Event 对象并相应地设置 target 属性以诱使 jQuery 认为该事件冒泡了。

var c = $('#container');

c.on('click', '[type=button]', function(e) {
    $(e.delegateTarget).find('span').text($(this).val());
});

var event = jQuery.Event('click');
event.target = c.find('[type=button]')[0];

c.trigger(event);

http://jsfiddle.net/PCLFx/

【讨论】:

  • 几个月后我回来了,我自己确实需要这个 ;-)
  • 比使用 skeezy 未记录的 API 来检索事件处理函数要好。
  • Event.target Read only 来源:developer.mozilla.org/en-US/docs/Web/API/Event
  • @AlekseyBykov 我们自己创建了一个 Event 实例,因此我们可以控制它。对于浏览器触发的事件,它是只读的。 (jQuery.Event('click')) instanceof Event = > false (jQuery.Event('click')) instanceof jQuery.Event => true
【解决方案2】:

我知道,这个问题是古老的,但是当我在寻找另一个问题的答案时磕磕绊绊,我想我不妨在这里分享我稍微简单的方法。

我们的想法是直接在所需的目标元素上创建事件:$(target_selector).trigger(event_type) 或者 - 对于“点击”等标准事件甚至更短 - 执行 $(target_selector).click(),请看下面我的小小提琴:

$(function(){
 $('.container').on('click','button',function(){
  console.log('delegated click on '+$(this).text());
  return false;
 });
 $('#other').click(e=>$('.container button').trigger('click'));
 $('#clickone').click(e=>$('.container .one').click());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form class="container">
<button type="submit" class="one">click 1</button> and another chance to click here on <button class="two">click 2</button>.
</form><br>
<div id="other">Trigger clicks on both buttons here!</div><br>
<div id="clickone">Trigger a click on button "one" only.</div>

【讨论】:

    【解决方案3】:

    我们可以将额外的event configuration 作为second argument 传递给jQuery's $.Event()。更多信息here.

    $('#click-me').on('click', function(evt){
      $(document).trigger($.Event('custom-click', {target: evt.currentTarget}));
    });
    
    $(document).on('custom-click', '#click-me', function(evt){
      alert(`${evt.type} was triggered on button with ${evt.target.id} id.`);
    })
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    
    <button id="click-me">Click Me</button>

    祝你好运……

    【讨论】:

      【解决方案4】:

      .on() 方法中的选择器是可选的。
      当你写:

        $('.container')
          .on('click', '[type=button]', function(e) {
            $(e.delegateTarget).find('.output').text($(this).val());
          })
          .find('[type=button]').triggerHandler('click');​
      

      您告诉事件处理程序只监听容器内的按钮单击。
      $(e.delegateTarget) 只是对外部容器的引用。

      我已经更新了your fiddle to echo this

      这是引用from the API:

      当提供选择器时,事件处理程序被称为 委托。事件直接发生时不调用处理程序 绑定元素,但仅适用于后代(内部元素) 匹配选择器。 jQuery 将事件从事件目标向上冒泡 到处理程序附加的元素(即,最里面 最外层元素)并运行该处理程序的任何元素 路径匹配选择器。

      【讨论】:

      • 此编辑可能会更改其代码的意图/目的。在此代码中包含选择器[type=button] 会将事件附加到添加到 页面加载后添加到 DOM 的按钮。如果他移除选择器,动态添加的按钮在点击时不会触发该功能。
      • @NoahWhitmore 谢谢。这是一个重要的提及。我曾经忘记所有关于第四维度的事情。 :)
      【解决方案5】:

      作为@Prinzhorn 答案的补充,拥有这个 JQuery 函数可能很有用:

      (function( $ ){
          $.fn.triggerParent = function (eventName, parent) {
              this.each(function() {
                  var event = jQuery.Event(eventName);
                  event.target = this;
                  $(parent).trigger(event);
              });
          };
      })( jQuery );
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多