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

Leaflet JS地图中Modal无法完全关闭问题求助

Leaflet地图Modal关闭后残留半透明遮罩的解决方法

我在Leaflet地图上配置了EasyButton,点击按钮弹出Modal(用于展示国家信息)。Modal参考W3 Schools代码实现,能正常打开,但点击关闭按钮(×)或Modal外部区域时,无法完全关闭——关闭后屏幕仍残留半透明遮罩,导致页面所有元素无法点击。

HTML代码

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta content="width=device-width, initial-scale=1.0" name="viewport">

  <title>Gazetteer Project</title>


  <!-- Favicons -->
  <link href="assets/img/favicon.png" rel="icon">
  <link href="assets/img/apple-touch-icon.png" rel="apple-touch-icon">

  <!-- Google Fonts -->
  <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i|Raleway:300,300i,400,400i,500,500i,600,600i,700,700i|Poppins:300,300i,400,400i,500,500i,600,600i,700,700i" rel="stylesheet">

  <!-- Vendor CSS Files -->
  <link href="assets/vendor/aos/aos.css" rel="stylesheet">
  <link href="assets/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
  <link href="assets/vendor/bootstrap-icons/bootstrap-icons.css" rel="stylesheet">
  <link href="assets/vendor/boxicons/css/boxicons.min.css" rel="stylesheet">
  <link href="assets/vendor/glightbox/css/glightbox.min.css" rel="stylesheet">
  <link href="assets/vendor/swiper/swiper-bundle.min.css" rel="stylesheet">

  <!-- Template Main CSS File -->
  <link href="assets/css/style.css" rel="stylesheet">
  
  <!-- W3 Schools -->
  <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
  
  <!-- Leaflet -->
   <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.2/dist/leaflet.css" integrity="sha256-sA+zWATbFveLLNqWO2gtiw3HL/lh1giY/Inf1BJ0z14=" crossorigin=""/>
   <script src="https://unpkg.com/leaflet@1.9.2/dist/leaflet.js" integrity="sha256-o9N1jGDZrf5tS+Ft4gbIK7mYMipq9lqpVJ91xHSyKhg=" crossorigin=""></script>
   <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet-easybutton@2/src/easy-button.css">
   <link href="https://unpkg.com/leaflet-easybutton@2.0.0/src/easy-button.css" rel="stylesheet">
   <script src="https://cdn.jsdelivr.net/npm/leaflet-easybutton@2/src/easy-button.js"></script>

   
   <!-- Bootstrap -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
    
  <!-- =======================================================
  * Template Name: Maxim - v4.9.1
  * Template URL: https://bootstrapmade.com/maxim-free-onepage-bootstrap-theme/
  * Author: BootstrapMade.com
  * License: https://bootstrapmade.com/license/
  ======================================================== -->
</head>

<body>

  <!-- ====== Modals ===== -->
    <!-- The Modal -->
    <div id="myModal" class="modal">

      <!-- Modal content -->
      <div class="modal-content">
        <span class="close">&times;</span>
        <p>Some text in the Modal..</p>
      </div>

    </div>

  
  <!-- ======= Header ======= -->
  <header id="header" class="fixed-top d-flex align-items-center">
    <div class="container d-flex justify-content-between">

      <div class="logo">
        <h1><a href="index.html">Geographical Gazetteer</a></h1>
      </div>
      

      <nav id="navbar" class="navbar">
      

        <ul>
          <li class="dropdown"><a href="#"><span>Drop Down</span> <i class="bi bi-chevron-down"></i></a>
          </li>
                
                <select id="innerSelect">
                  
                  
                </select>
              </div>
        <i class="bi bi-list mobile-nav-toggle"></i>

        </div>
      </nav>

  </header>
  
  
  <!-- ======= Map ======= -->
  <div id="container">
 <div id='map'></div>
    <!-- Modal -->

      
      

  <!-- ======= Footer ======= -->
<!---REMEMBER TO ADD IN BOOTSTRAP CREDITS---&gt;

  <a href="#" class="back-to-top d-flex align-items-center justify-content-center"><i class="bi bi-arrow-up-short"></i></a>

  <!-- Vendor JS Files -->
  <script src="assets/vendor/aos/aos.js"></script>
  <script src="assets/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
  <script src="assets/vendor/glightbox/js/glightbox.min.js"></script>
  <script src="assets/vendor/isotope-layout/isotope.pkgd.min.js"></script>
  <script src="assets/vendor/swiper/swiper-bundle.min.js"></script>
  <script src="assets/vendor/php-email-form/validate.js"></script>

  <!-- Template Main JS File -->
  <script src="assets/js/main.js"></script>


  <script src="assets/js/jquery-3.5.1.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>
  <script src="assets/js/functionality.js"></script>


</body>
</html>

JavaScript代码

L.easyButton('fa-comment-o', function(btn, map) {
    $('#myModal').modal('show');
}, 'Informacije').addTo(map);


// Get the modal
var modal = document.getElementById("myModal");


// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];


// When the user clicks on <span> (x), close the modal
span.onclick = function() {
  modal.style.display = "none";
}

// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
  if (event.target == modal) {
    modal.style.display = "none";
  }
}

CSS代码

/* The Modal (background) */
.modal {
  display: none; /* Hidden by default */
  position: fixed; /* Stay in place */
  z-index: 1; /* Sit on top */
  left: 0;
  top: 0;
  width: 100%; /* Full width */
  height: 100%; /* Full height */
  overflow: auto; /* Enable scroll if needed */
  background-color: rgb(0,0,0); /* Fallback color */
  background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}

/* Modal Content/Box */
.modal-content {
  background-color: #fefefe;
  margin: 15% auto; /* 15% from the top and centered */
  padding: 20px;
  border: 1px solid #888;
  width: 80%; /* Could be more or less, depending on screen size */
}

/* The Close Button */
.close {
  color: #aaa;
  float: right;
  font-size: 28px;
  font-weight: bold;
}

.close:hover,
.close:focus {
  color: black;
  text-decoration: none;
  cursor: pointer;
}

问题原因

核心问题是打开和关闭方式不匹配:你用Bootstrap的$('#myModal').modal('show')方法打开Modal,但关闭时用原生JS直接修改modal.style.display = "none"。这种操作只会隐藏Modal本身,不会触发Bootstrap Modal组件的完整关闭逻辑——Bootstrap打开Modal时会自动生成一个半透明遮罩层(.modal-backdrop),并给body添加modal-open类锁定页面滚动,而原生修改display不会清理这些元素和类,导致遮罩残留。

解决方案

方案一:统一使用Bootstrap Modal API关闭

直接调用Bootstrap的modal('hide')方法,它会自动处理遮罩层移除、body类清理等所有关闭逻辑:

// 关闭按钮点击事件
span.onclick = function() {
  $('#myModal').modal('hide');
}

// 点击Modal外部关闭
window.onclick = function(event) {
  if (event.target == modal) {
    $('#myModal').modal('hide');
  }
}

方案二:原生JS关闭+手动清理遮罩

如果坚持用原生JS修改display,需要手动移除Bootstrap生成的遮罩层和body类:

// 关闭按钮点击事件
span.onclick = function() {
  modal.style.display = "none";
  // 移除遮罩层
  const backdrop = document.querySelector('.modal-backdrop');
  if (backdrop) backdrop.remove();
  // 恢复页面滚动
  document.body.classList.remove('modal-open');
}

// 点击Modal外部关闭
window.onclick = function(event) {
  if (event.target == modal) {
    modal.style.display = "none";
    const backdrop = document.querySelector('.modal-backdrop');
    if (backdrop) backdrop.remove();
    document.body.classList.remove('modal-open');
  }
}

额外优化:避免Bootstrap版本冲突

你的HTML里重复加载了Bootstrap 3.4.1和4.5.2两个版本,这会导致样式和JS冲突,建议只保留一个版本(比如移除3.4.1的引用,保留4.5.2)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:35:21