在DOM更改后如何检查元素是否为空?

3

I have this code:

$(function() {
  $('.delete').click(function() {
    $(this).closest('li').remove();
  });

  $('#items').change(function() {
    if ($(this).is(':empty')) {
      alert('No more conditions');
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="items">
  <li><a href="#" class="delete">Delete me</a></li>
</ul>

一旦我点击链接,就会得到一个空的UL列表,但在.change()事件上使用.is('empty')不会触发警报。那么这是检查元素在DOM更改后是否为空的正确方法吗?如果不是,正确的方法是什么?

注意:解决方案必须与旧浏览器(如IE8)兼容。


请查看https://dev59.com/KnNA5IYBdhLWcg3wGJ0V。 - Alvaro
7个回答

3
这个解决方案怎么样?希望能有所帮助!

$(function() {
  $('.delete').click(function() {
  $(this).closest('li').remove();
  if ($('#items li').length === 0) {
  alert('No more conditions');
  }
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<ul id="items">
  <li><a href="#" class="delete">Delete me</a></li>
</ul>


2

这个事件仅适用于<input>元素、包括类型为checkbox和radio的<input>,以及<select>元素...

来自 https://api.jquery.com/change/


像这样的东西应该可以工作:

$(function() {
  $('.delete').click(function() {
    $(this).closest('li').remove();
    handleChange();
  });

  function handleChange() {
    if ($('#items').children().length == 0) {
      alert('No more conditions');
    }
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="items">
  <li><a href="#" class="delete">Delete me</a></li>
</ul>


2

change事件不能用于普通的DOM元素,只能用于input类型的元素。因此回答您的问题,不,那不是正确的方法来解决问题,也无法起作用。

您应该只需在执行删除操作的事件处理程序中包含存在性检查即可。

$('.delete').click(function() {
    $(this).closest('li').remove();
    if ($('#items').is(':empty')) {
        alert('No more conditions');
    }
});

另一种方法是为您特定的items元素设置Mutation Observer,但如果仅在每次删除后检查就足够了,那么这可能会过度。


1
我把你的代码放到片段中,在发表评论之前进行了测试。<li>被删除了,但是alert()没有触发。 - Makyen
2
我建议你自己尝试一下:JSFiddle - Makyen
1
当然,我看到了你提供的示例。你有没有尝试我提供的 JSFiddle 示例呢?我提供的示例是将你回答中的代码与问题中的 HTML 进行剪切和粘贴得到的。当点击 .delete <li> 时,它会被删除,但 alert() 不会显示(在 Chrome、Edge、IE11 或 Firefox 中)。你的代码在 OP 描述的情况下无法正常工作。我建议你不要进行人身攻击,只需坚持事实即可。 - Makyen
@Keith - 一般来说,我更喜欢使用类名进行过滤,如果这是我设计的东西,我会采用这种方法。话虽如此,这取决于组合方式。除了空格之外,如果OP使用空值与其解决方案配合使用,那么就没有什么问题了,主要问题在于事件处理程序。 - Travis J
1
您继续使用人身攻击论据,我建议您停止。这样做会削弱您其他论点的力量,因为它意味着您认为在不攻击对方的情况下,其他论点是不足够的。我没有发表贬低您的言论。我发表了一些对您的代码持批评态度的言论。具体而言,我说它不起作用,在OP明确问到的情况下确实如此。我还赞扬了您回答中的其他评论。 - Makyen
显示剩余10条评论

1
你可以使用 MutationObserver(),并将 childListsubtree 选项设置为 true

$(function() {
  $(".delete").click(function() {
    $(this).closest("li").remove();
  });

  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      if (!mutation.target.children.length) {
        console.log(mutation.target.id + " is empty. " + "No more conditions");
      }
    })
  });

  observer.observe($("#items")[0], {
    childList: true,
    subtree: true
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<ul id="items">
  <li><a href="#" class="delete">Delete me</a>
  </li>
</ul>


1
    元素在移除子节点时不会触发change事件。您需要使用MutationObserver来实现此功能。请注意,此功能在MSIE 10或更早版本中不可用。
$().ready(function documentReady() {
    console.log("%c Document Ready", 'color: #093');

    $(function() {
      $('.delete').click(function() {
        $(this).closest('li').remove();
      });

    var observer = new MutationObserver(function(mutations) {
        if ( $("#items").find("li").length === 0) {
            console.log('No more conditions');
        }    
    });

    var targetNode = document.getElementById("items");
    observer.observe(targetNode, { childList: true });

    });
});

如果你需要在旧版本的MSIE中实现类似的功能,可以使用类似但不如Mutation Events功能优秀的功能。检测是否支持MutationObserver,如果支持则使用它,否则回退到MutationEvent。

好的例子,但对我来说不起作用,因为我现在需要向后兼容性。 - ReynierPM

0

尝试使用.children()代替

它返回一个包含元素集合的jQuery对象(检查console.log())。

$('.delete').click(function() {
  $(this).closest('li').remove();
  console.log( $('#items').children().length, $('#items').children() );
  if (!$('#items').children().length) {
   alert('No more conditions');
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="items">
  <li><a href="#" class="delete">Delete me</a></li>
  <li><a href="#" class="delete">Delete me</a></li>
</ul>


虽然这段代码可以工作,但如果您解释一下为什么选择器:empty对于#items元素无效,那么这个答案会更好。 - Makyen

0

使用jQuery自定义事件完成,可能不是最完美的方式,但只是另一种选择。

$(function() {
  $('.delete').click(function() {
    $(this).closest('li').remove();
    $.event.trigger("limodeified");
  });

  $(document).on("limodeified", function() {
    if ($("#items").html().trim() === "") {
      alert('No more conditions');
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="items">
  <li><a href="#" class="delete">Delete me</a>
  </li>
</ul>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接