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">×</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---> <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
相关产品推荐
相关产品推荐

