You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现等待ngx-spinner-overlay遮罩层隐藏以避免点击拦截异常

问题描述

我有一段点击下拉按钮的代码,包含等待元素隐藏的逻辑:

new WebDriverWait(driver, Duration.ofSeconds(timeout)).until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[contains(@class, 'ngx-spinner-overlay')]")));
new WebDriverWait(driver, Duration.ofSeconds(timeout)).until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("div.ngx-spinner-overlay")));

点击按钮的代码:

Thread.sleep(4000);
WebDriverWait button2Wait = new WebDriverWait(driver, Duration.ofSeconds(timeout));
WebElement button2 = button2Wait.until(ExpectedConditions.elementToBeClickable(By.xpath(dropDownId)));
new Actions(driver).moveToElement(button2).build().perform();
button2.click();

但偶尔会抛出如下异常:

org.openqa.selenium.ElementClickInterceptedException: element click intercepted: Element <mobileweb-value-selector _ngcontent-jkb-c228="" id="equipment" selectorskin="component" property.id="equipmentId" property.name="equipmentLookupCode" _nghost-jkb-c212="" class="ng-star-inserted">...</mobileweb-value-selector> is not clickable at point (694, 368). Other element would receive the click: <div _ngcontent-jkb-c171="" class="ngx-spinner-overlay ng-tns-c171-0 ng-trigger ng-trigger-fadeIn ng-star-inserted ng-animating" style="background-color: rgba(255, 255, 255, 0.75); z-index: 99999; position: fixed;">...</div>
  (Session info: chrome=110.0.5481.177)

请问如何编写代码以等待该div遮罩层完全隐藏?

解决方案

异常显示遮罩层带有ng-animating类,说明它还在执行淡出动画——此时元素可能已开始不可见,但仍存在于DOM中并拦截点击。原有的invisibilityOfElementLocated仅检查可见性,无法覆盖动画未结束的场景,可通过以下方式优化:

1. 等待遮罩层从DOM中移除

使用stalenessOf条件,确认元素完全脱离DOM:

try {
    WebElement spinnerOverlay = driver.findElement(By.cssSelector("div.ngx-spinner-overlay"));
    new WebDriverWait(driver, Duration.ofSeconds(timeout)).until(ExpectedConditions.stalenessOf(spinnerOverlay));
} catch (NoSuchElementException e) {
    // 遮罩层已不存在,直接跳过
}

2. 自定义条件:等待遮罩层不可见且无动画类

针对Angular动画场景,检查元素是否不可见,或动画类已移除:

new WebDriverWait(driver, Duration.ofSeconds(timeout)).until(driver -> {
    List<WebElement> overlays = driver.findElements(By.cssSelector("div.ngx-spinner-overlay"));
    if (overlays.isEmpty()) {
        return true;
    }
    WebElement overlay = overlays.get(0);
    return !overlay.isDisplayed() || !overlay.getAttribute("class").contains("ng-animating");
});

3. 优化完整点击流程

移除硬编码的Thread.sleep,用显式等待替代,确保点击前遮罩层完全消失:

// 等待遮罩层完全消失(含动画结束)
new WebDriverWait(driver, Duration.ofSeconds(timeout)).until(driver -> {
    List<WebElement> overlays = driver.findElements(By.cssSelector("div.ngx-spinner-overlay"));
    if (overlays.isEmpty()) {
        return true;
    }
    WebElement overlay = overlays.get(0);
    return !overlay.isDisplayed() && !overlay.getAttribute("class").contains("ng-animating");
});

// 定位并点击下拉按钮
WebElement button2 = new WebDriverWait(driver, Duration.ofSeconds(timeout))
        .until(ExpectedConditions.elementToBeClickable(By.xpath(dropDownId)));
button2.click();

关键说明

  • invisibilityOfElementLocated仅判断元素是否不可见,但元素可能仍在DOM中执行动画,继续拦截点击;
  • 用显式等待替代Thread.sleep,既保证稳定性又避免不必要的等待;
  • 自定义条件能精准适配Angular框架的动画状态,解决偶发的拦截问题。

内容的提问来源于stack exchange,提问作者Peter Penzov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 03:07:52