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

如何实现点击Yes按钮后禁用Modal关闭直至Ajax完成?修改data属性无效

Modal示例图

需求说明
  • 首次弹出Modal时,可通过点击取消按钮、关闭标记按钮或点击Modal外部区域进行关闭;
  • 点击Yes按钮后,在Ajax请求处理完成前,无法通过点击取消按钮、关闭标记按钮或点击Modal外部区域关闭Modal。

问题

我曾尝试在点击Yes按钮时通过JavaScript将data-backdrop改为static、data-keyboard改为false,但并未生效。请问该如何实现此功能?


实现方案

直接修改DOM的data-*属性不会生效,因为Modal初始化后,配置参数已存储在实例对象中,需要通过操作Modal实例来修改规则,同时禁用关闭按钮的交互。以下以Bootstrap 5为例给出实现代码:

1. 基础Modal结构

<div class="modal fade" id="confirmModal" tabindex="-1" aria-labelledby="confirmModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="confirmModalLabel">确认操作</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        确定要执行此操作吗?
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
        <button type="button" class="btn btn-primary" id="yesBtn">Yes</button>
      </div>
    </div>
  </div>
</div>

2. JavaScript逻辑

// 获取Modal实例及相关按钮
const confirmModal = new bootstrap.Modal(document.getElementById('confirmModal'));
const yesBtn = document.getElementById('yesBtn');
const closeBtn = document.querySelector('.btn-close');
const cancelBtn = document.querySelector('.btn-secondary[data-bs-dismiss="modal"]');

yesBtn.addEventListener('click', function() {
  // 1. 禁用关闭按钮并移除关闭触发属性
  closeBtn.disabled = true;
  cancelBtn.disabled = true;
  closeBtn.removeAttribute('data-bs-dismiss');
  cancelBtn.removeAttribute('data-bs-dismiss');

  // 2. 修改Modal配置,禁止外部点击和键盘关闭
  confirmModal._config.backdrop = 'static';
  confirmModal._config.keyboard = false;
  // 重新生成背景层使配置生效
  if (confirmModal._backdrop) {
    confirmModal._backdrop.dispose();
    confirmModal._backdrop = new bootstrap.Backdrop(confirmModal._element, {
      isVisible: true,
      isAnimated: confirmModal._config.animation
    });
  }

  // 3. 执行Ajax请求
  fetch('/your-api-endpoint', {
    method: 'POST',
    // 根据需求添加请求头、请求体等配置
  })
  .then(response => response.json())
  .then(data => {
    // 请求成功后的业务处理,比如提示操作完成
    console.log('操作执行成功');
  })
  .catch(error => {
    // 请求失败后的业务处理
    console.error('操作执行失败:', error);
  })
  .finally(() => {
    // 4. 请求完成后恢复所有设置
    closeBtn.disabled = false;
    cancelBtn.disabled = false;
    closeBtn.setAttribute('data-bs-dismiss', 'modal');
    cancelBtn.setAttribute('data-bs-dismiss', 'modal');
    
    confirmModal._config.backdrop = true;
    confirmModal._config.keyboard = true;
    if (confirmModal._backdrop) {
      confirmModal._backdrop.dispose();
      confirmModal._backdrop = new bootstrap.Backdrop(confirmModal._element, {
        isVisible: true,
        isAnimated: confirmModal._config.animation
      });
    }

    // 可选:请求完成后关闭Modal
    confirmModal.hide();
  });
});

关键说明

  • Modal初始化后,data-backdrop和data-keyboard仅作为初始配置,后续修改DOM属性不会触发实例更新,必须修改实例的_config并重新生成背景层。
  • 移除关闭按钮的data-bs-dismiss属性,避免用户通过键盘触发按钮的关闭逻辑。
  • 在finally块中恢复配置,确保无论请求成功或失败,Modal都能回到可正常关闭的状态。

如果使用jQuery版本的Bootstrap,逻辑类似,仅API调用方式不同:

$('#yesBtn').click(function() {
  const $modal = $('#confirmModal');
  // 禁用关闭按钮
  $('.btn-close, .btn-secondary[data-dismiss="modal"]').prop('disabled', true).removeAttr('data-dismiss');
  // 更新Modal配置
  $modal.modal({ backdrop: 'static', keyboard: false });

  // 执行Ajax请求
  $.ajax({
    url: '/your-api-endpoint',
    method: 'POST'
  })
  .done(function(data) {
    console.log('操作成功');
  })
  .fail(function(error) {
    console.error('操作失败');
  })
  .always(function() {
    // 恢复配置和按钮状态
    $('.btn-close, .btn-secondary[data-dismiss="modal"]').prop('disabled', false).attr('data-dismiss', 'modal');
    $modal.modal({ backdrop: true, keyboard: true });
    $modal.modal('hide');
  });
});

内容的提问来源于stack exchange,提问作者Donny Akhmad Septa Utama

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 12:04:52