如何修复Cypress循环删除元素时的‘cy.find()元素脱离DOM’错误?
问题:批量删除DOM元素时触发“元素已脱离DOM”错误
我编写了代码用于循环查找页面元素,若元素包含“Objectives”文本则点击其内部的删除按钮,但当页面对象数量超过3个时,代码抛出错误。
原代码如下:
cy.get('.row.js-all-talking-points-container').find('.card.obm-card-secondary.obm-card-agenda.h-100.mx-3.mx-sm-0').each(($el, index, $list) => { const getTextobjective = $el.find('span.agenda-item-title.text-muted').text() if (getTextobjective.includes('Objectives')) { cy.wrap($el).find('.btn.btn-outline-primary.js-remove-talking-point.js-remove-handler-added').should('be.visible').click({force: true}); } })
遇到的错误提示:
cy.find() failed because this element is detached from the DOM
修复建议
问题根源
删除第一个元素后,页面DOM会重新渲染(比如列表重排、元素数量变化),导致初始获取的元素列表中,后续元素脱离了当前DOM树,循环到这些元素时就会触发错误。
方案1:递归删除+每次重新查询元素
每次删除后重新定位目标元素,直到没有符合条件的元素为止,利用递归实现批量删除:
const deleteObjectivesItems = () => { cy.get('.row.js-all-talking-points-container') .find('.card.obm-card-secondary.obm-card-agenda.h-100.mx-3.mx-sm-0') .contains('span.agenda-item-title.text-muted', 'Objectives') .then(($el) => { // 找到元素对应的删除按钮并点击 cy.wrap($el) .closest('.card.obm-card-secondary.obm-card-agenda.h-100.mx-3.mx-sm-0') .find('.btn.btn-outline-primary.js-remove-talking-point.js-remove-handler-added') .should('be.visible') .click(); // 递归调用,继续删除剩余元素 deleteObjectivesItems(); }) .catch(() => { // 没有找到元素时终止递归 cy.log('所有包含"Objectives"的元素已删除完毕'); }); }; // 启动删除流程 deleteObjectivesItems();
方案2:按初始数量循环+每次重新查询
先统计符合条件的元素总数,再循环对应次数,每次迭代都重新查询元素,避免依赖失效的DOM引用:
cy.get('.row.js-all-talking-points-container').then(($container) => { // 统计需要删除的元素数量 const targetCount = $container.find('.card.obm-card-secondary.obm-card-agenda.h-100.mx-3.mx-sm-0').filter((i, el) => { return Cypress.$(el).find('span.agenda-item-title.text-muted').text().includes('Objectives'); }).length; // 循环删除,每次都重新定位元素 Cypress._.times(targetCount, () => { cy.get('.row.js-all-talking-points-container') .find('.card.obm-card-secondary.obm-card-agenda.h-100.mx-3.mx-sm-0') .filter((i, el) => { return Cypress.$(el).find('span.agenda-item-title.text-muted').text().includes('Objectives'); }) .first() .find('.btn.btn-outline-primary.js-remove-talking-point.js-remove-handler-added') .should('be.visible') .click(); }); });
额外提示
- 尽量不要用
force: true,如果按钮不可见,优先通过等待页面加载、滚动到元素位置等方式确保元素可见,强制点击可能会导致不可预期的行为 - 可根据页面加载速度,在删除操作后添加
cy.wait(500)(时间按需调整),确保DOM更新完成后再进行下一次操作
内容的提问来源于stack exchange,提问作者Nimesh Chhetri
相关产品推荐
相关产品推荐

