如何检测变量中jQuery对象的DOM引用是否已失效
如何检测jQuery变量是否已失去对当前DOM元素的引用
问题背景
你遇到的场景是:
- 先将jQuery对象存入变量:
const $hoge = $('#hoge');
- 通过重写父元素HTML的方式,替换了id为
hoge的元素:
$hoge.parent().html('<div id="hoge"></div>');
- 此时原变量
$hoge指向的是已被移除的旧DOM元素,调用$hoge.addClass('test')无法作用于新元素;而你尝试用$hoge === $('#hoge')检测时,因每次$('#hoge')都会生成新的jQuery对象,所以始终返回false。
可行的检测方法
方法1:利用原生DOM的isConnected属性
jQuery对象包含原生DOM元素的引用,取出第一个元素(id选择器仅匹配单个元素)后,可通过isConnected属性判断该元素是否仍存在于文档树中:
const $hoge = $('#hoge'); // 检测旧元素是否已被移除 if (!$hoge[0].isConnected) { console.log('$hoge指向的元素已不在DOM中'); // 重新获取新元素更新变量 $hoge = $('#hoge'); }
isConnected是原生DOM节点的内置属性,直接判断节点是否属于当前文档的DOM树,高效且直观。
方法2:对比原生DOM元素的引用
将原生DOM元素单独存储,后续对比当前页面中id为hoge的元素引用,判断是否已被替换:
const hogeEl = $('#hoge')[0]; const $hoge = $('#hoge'); // 后续需要检测时 const currentHogeEl = $('#hoge')[0]; if (hogeEl !== currentHogeEl) { console.log('$hoge指向的元素已被替换'); // 更新变量为新元素的jQuery对象 $hoge = $('#hoge'); }
新生成的元素是完全独立的DOM节点,与旧节点的引用必然不同,通过直接对比即可确认状态。
方法3:使用jQuery的.filter验证匹配关系
通过filter方法筛选当前$('#hoge')结果中与原变量指向相同的元素,若筛选结果为空,说明原元素已被替换:
const $hoge = $('#hoge'); // 检测 if ($('#hoge').filter($hoge).length === 0) { console.log('$hoge指向的元素已被替换'); $hoge = $('#hoge'); }
.filter($hoge)会从当前匹配的元素中筛选出和$hoge指向一致的节点,长度为0则表示原元素已不在当前DOM的匹配结果中。
为什么$hoge === $('#hoge')始终返回false?
每次调用$('#hoge')都会创建一个全新的jQuery包装对象,即使两个对象指向同一个DOM元素,它们本身是不同的JavaScript对象,因此全等比较(===)会返回false。若要对比指向的DOM元素,必须取出原生节点进行引用对比。
内容的提问来源于stack exchange,提问作者Hiroshi H
相关产品推荐
相关产品推荐

