jQuery 1.7 .on()事件委托不适用于禁用元素上的选择器

时间:2012-04-11 01:44:25

标签: javascript jquery javascript-events event-delegation

我的HTML(非动态)如下所示:

<select id="domain" class="marketplace">
  <option>United States</option>
  ...
</select>

这有效:

$("#domain").on("change", function() {
  $("#domain").attr("disabled", "disabled");
  /* do ajaxy stuff */
  $("#domain").removeAttr("disabled");
});
$("select.marketplace").on("change", function() { /* do some general stuff */});

这不是:

$("#domain").on("change", function() {
  $("#domain").attr("disabled", "disabled");
  /* do ajaxy stuff */
  $("#domain").removeAttr("disabled");
});
$(document).on("change", "select.marketplace", function() { /* do some general stuff */});

删除$("#domain").attr("disabled", "disabled");调用会恢复$(document).on()委派的功能,因此无论事件是如何触发的(即{{1也不是.trigger也不是用户互动)。但是,我不明白为什么,因为处理程序都没有返回任何内容或进行任何阻止事件传播的调用,并且jQuery文档没有提到对传播有任何影响的“禁用”属性。我在这里缺少什么?

2 个答案:

答案 0 :(得分:2)

为了重现您的问题,我创建了以下代码段(按钮Click Me用于触发更改事件,只是为了完整演示):

$(document).on("change", "select.marketplace", function (e) {
  $('#result').append('<p>$(document).on("change", "select.marketplace", function (e) {: This does not work!<p/>');
});
$(function () {
  $("#domain").on("change", function () {
    $("#domain").attr("disabled", "disabled");
    /* do ajaxy stuff */
    //$("#domain").removeAttr("disabled");
  });
  $("select.marketplace").on("change", function (e) {
    $('#result').append('<p>$("select.marketplace").on("change", function (e) {: This work!<p/>');
  });
  $('#btn').on('click', function (e) {
    $('#domain').trigger('change');
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>

<button id="btn">Click Me</button>
<select id="domain" class="marketplace">
    <option>United States</option>
    <option>United States</option>
    <option>United States</option>
    <option>United States</option>
</select>
<div id="result"></div>

我评论了对域更改事件禁用的removeAttr以重现错误。

使用jQuery 1.7,关于更改的文档不会像你想象的那样工作。

现在让我们使用通用文档更改有关更改的文档,让我们过滤事件目标:

$(document).on("change", function (e) {
   if ($(e.target).is('select.marketplace')) {
      $('#result').append('<p>$(document).on("change", function (e) {: This works!<p/>');
   }
});
$(function () {
  $("#domain").on("change", function () {
    $("#domain").attr("disabled", "disabled");
    /* do ajaxy stuff */
    //$("#domain").removeAttr("disabled");
  });
  $("select.marketplace").on("change", function (e) {
    $('#result').append('<p>$("select.marketplace").on("change", function (e) {: This work!<p/>');
  });
  $('#btn').on('click', function (e) {
    $('#domain').trigger('change');
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>



<button id="btn">Click Me</button>
<select id="domain" class="marketplace">
    <option>United States</option>
    <option>United States</option>
    <option>United States</option>
    <option>United States</option>
</select>
<div id="result"></div>

现在您会看到不同的行为,正是您正在寻找的行为。

当然,这不是最佳解决方案,只是解决问题的一种方法。

我等待其他想法,因为我的解决方案只是一种解决方法。

如果您有兴趣获取更多信息,可以查看jQuery

dispatch: function( event ) {

在源代码jQuery 1.7中注意“禁用”一词。

答案 1 :(得分:-1)

您是否尝试过像这样的事件命名空间:

$(document).ready(function() {
  $("#domain").on("change.eventOne", function() { /* do some specific stuff */ });
  $(document).on("change.eventTwo", "select.marketplace", function() { /* do some general stuff */ });
});

您可能还想尝试从身体附着。我有更好的运气:

$(document).ready(function() {
  $("#domain").on("change.eventOne", function() { /* do some specific stuff */ });
  $('body').on("change.eventTwo", "select.marketplace", function() { /* do some general stuff */ });
});

这是一个明显起作用的事件的小提琴。除非我不理解“工作”对OP的实际意义。

https://jsfiddle.net/szcjszkz/1/