首页 > 解决方案 > 如何处理具有优先级的事件委托?

问题描述

我的应用程序中有类似的代码:

let item;

$('.parent').on('click', function () {
  item = $(this).attr('item') || 0; 
});

$('.parent').on('click', '.children', this, function () {
  doSomething();
});
<div class="parent" item="50">
  <div class="children">
  </div>
</div>

<div class="parent" item="51">
  <div class="children">
  </div>
</div>

<div class="parent" item="52">
  <div class="children">
  </div>
</div>

我有一个父元素,里面有几个孩子。单击父元素上的任何位置都会给我一个item信息,因此我将能够在单击子元素时根据此item变量加载函数。

我的问题是:我必须将子元素上的 onClick 事件委托给父元素,否则事件将按此顺序触发:

  1. 点击任何孩子
  2. 单击父级,为时已晚,因为我item首先需要变量

如果激活,我有一个替换父元素的功能,因为它是动态插入到 DOM 中的,所以我也必须委托 onClick 事件,如下所示:

$('.grandParent').on('click', '.parent', function () {
  item = $(this).attr('item') || 0;
});

现在我的问题是事件再次以错误的顺序触发:

  1. 点击任何孩子
  2. 点击父级

如何将父级的点击事件设置为最高优先级?

编辑 :

我会更具体。我的页面上有一个消息列表,每个.message元素都包含消息内容,还有一些功能,如编辑、删除、设置为收藏夹等。

像这样 :

<div class="message" data-item="1">
  <a class="edit">E</a>
  <a class="delete">X</a>
  <a class="favorite">Fav</a>
  <a class="like">Like</a>
  <div class="content">
    Hello world !
  </div>
</div>
<div class="message" data-item="2">
  <a class="edit">E</a>
  <a class="delete">X</a>
  <a class="favorite">Fav</a>
  <a class="like">Like</a>
  <div class="content">
    Hello world !
  </div>
</div>

单击时,这些功能中的每一个都会触发不同的功能:edit()、delete()、like() 等。

他们都将发出 AJAX 请求,然后将item变量发送到我的服务器,以了解此点击必须影响哪些项目。

为了避免在我的事件处理程序中重复,我试图data-item通过一个绑定到单击.message元素的事件来获取属性的值,这依赖于子元素的冒泡。

标签: javascriptjqueryevents

解决方案


获取item您真正想要的位置并摆脱处理程序parent

$('.parent').on('click', '.children', function () {
  item = $(this).closest('.parent').attr('item');
  doSomething();
});

编辑:

然后在单击祖父母时获取该项目:

$('.grandParent').on('click', '.children', function () {
  item = $(this).closest('.parent').attr('item');
});

编辑#2:

根据 OPs 更新的要求,这样做:

<div class="message" data-item="1">
  <a class="action edit" data-type="edit">E</a>
  <a class="action delete" data-type="delete">X</a>
  <a class="action favorite" data-type="favorite">Fav</a>
  <a class="like">Like</a>
  <div class="content">
    Hello world !
  </div>
</div>
<div class="message" data-item="2">
  <a class="action edit" data-type="edit">E</a>
  <a class="action delete" data-type="delete">X</a>
  <a class="action favorite" data-type="favorite">Fav</a>
  <a class="like">Like</a>
  <div class="content">
    Hello world !
  </div>
</div>

$(document).on('click','.message .action',function(e) {
   const item = $(this).closest('message').attr('item');
   switch($(this).data('type')) {
     case 'edit': doEdit(item); break;
     case 'delete': doDelete(item); break;
     case 'favorite': doFavorite(item); break;
   }
});

看,一个事件处理程序?

这是一种非常常见的模式来做你正在做的事情。在没有更健壮的框架(例如 React)的情况下,使用纯 jQuery 应该是这样做的。


推荐阅读