jQuery如何选择不在.resend_contain容器内的[data-resendtext]属性元素
问题描述
原有功能的正常运行逻辑:点击span元素时,从最近的.message-bubble元素中获取data-resendtext属性值而非元素文本,原有实现代码如下:
$('.messages').on('click', '.message__action.message__edit[data-midedit]', function(e) { var t_edit = $(this), t_msg = t_edit.closest('.message-bubble'); old_text = t_msg.find('[data-resendtext]').eq(0).attr('data-resendtext'); alert(old_text); });
对应的基础HTML结构:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="messages"> <div class="message-bubble" data-mid="1"> <div class="message-bubble-inner"> <p data-resendtext="First text">Lorem ipsum</p> </div> <span class="message__action message__edit" data-midedit="1">Click</span> </div> <div class="message-bubble" data-mid="2"> <div class="message-bubble-inner"> <p data-resendtext="Another text">Lorem ipsum</p> </div> <span class="message__action message__edit" data-midedit="2">Click</span> </div> </div>
存在的问题
页面所有数据均通过AJAX加载,部分.message-bubble元素会携带引用内容,.resend_contain容器内的引用段落也带有data-resendtext属性,原有代码会优先获取到容器内引用内容的属性值,需要排除该容器内的元素,获取外层实际消息对应的data-resendtext属性值。
当前使用的临时解决代码:
if(t_msg.find('.resend_contain').length !== 0) { old_text = t_msg.find('[data-resendtext]').eq(1).attr('data-resendtext').trim(); } else { old_text = t_msg.find('[data-resendtext]').eq(0).attr('data-resendtext').trim(); }
优化解决方案
直接使用jQuery的:not选择器过滤掉.resend_contain下的目标元素即可,无需额外条件判断,一行代码就能实现需求,稳定性和效率都更高:
old_text = t_msg.find('[data-resendtext]:not(.resend_contain [data-resendtext])').eq(0).attr('data-resendtext').trim();
方案说明
- 选择器
[data-resendtext]:not(.resend_contain [data-resendtext])会直接匹配所有带有data-resendtext属性、且不属于.resend_contain后代的元素 - 无论消息气泡内是否存在引用容器,都直接取匹配到的第一个元素的属性值,不会因为DOM结构顺序调整出现取值错误的问题
- 仅需要一次DOM查询,比原有条件判断的写法性能更优
内容的提问来源于stack exchange,提问作者Andrew Zheludkov
相关产品推荐
相关产品推荐

