如何使用JavaScript点击外部隐藏弹出窗口

4

有很多问题和我的一样,即使我查看了这个链接。但是我还没有得到一个合适的解决方案,所以我在这里发布我的问题。

当我点击图标时,必须弹出一条消息,当我点击包含图标的相同div时,它应该消失。 这个功能正常工作。 但是当我在div之外单击时,弹出窗口也应该消失。 我该如何修改这个javascript函数才能实现呢?

<div>
<h5 class="haead">Search for a product title
<div class="popup" onclick="myFunction5()"> <img class="qnicon" src="question.png">
<span class="popuptext" id="myPopup5">Search product.</span>
</div>
</h5>
</div>

<script>
function myFunction5() {
    var popup = document.getElementById("myPopup5");
    popup.classList.toggle("show");

}
</script>

https://dev59.com/XnVC5IYBdhLWcg3w4Vf6 - Z. Bagley
你链接的另一个问题有一个被接受的答案,可以适用于你。它基本上说明,在对话框上点击时,你需要停止事件传播,这将防止点击冒泡到文档上,然后在文档上添加一个点击处理程序来隐藏弹出窗口。 - Jonathan Kuhn
2个回答

4
我发现避免其他可能出现的问题的最简单方法是将弹出窗口放在一个100%宽/高的div上面。这个“禁用”div具有与通常关闭弹出窗口的按钮相同的点击处理程序。因此,如果用户点击“X”关闭,单击“确定”按钮(或您设置的任何其他按钮)或弹出窗口外部区域,都会产生相同效果,即关闭弹出窗口。
这个“禁用”div(它有效地禁用了整个应用程序,除了弹出窗口)可以完全透明,通过设置不透明度来实现。
你把“禁用”div放在z = 9998,把弹出窗口放在z = 9999(只需更多CSS),它们总是在顶部。请注意,如果所有内容加载到已经位于禁用div下方的div中(例如Angular中的router-outlet div),则可能不需要这样做,但我通常仍然这样做。
完整的基本示例。我通常将其制作为组件,并将其连接到事件总线,以便我可以在其中传递数据(因此我可以更改位置,样式,消息,甚至单击关闭按钮时发生的事情)。如果您得到此代码,则应该能够在任何框架等中使用类似的近似代码。
<html>
<head>
<style>

.button {
    text-align: center;
    width: 100px;
    height: 30px;
    background-color: green;
    border: 2px solid grey;
    color: white;
    margin: auto;
    position: relative;
}

.disabler {
    position: fixed;
    top: 0px;
    left: 0px;
    width: 100%;
    height: 100%;
    z-index: 99998;
    background-color: #000000;
    opacity: 0.5;
}

.popup {
    position: relative;
    /* Center with whatever voodoo you like */
    top: calc(50% - 150px);
    left: calc(50% - 150px);
    width: 300px;
    height: 300px;
    background-color: blue;
    border: 2px solid grey;
    z-index: 99999;
}
</style>
</head>
<body>

<div class="button" onclick="togglePopup ( )">
    Show Popup
</div>

<div class="button" onclick="showAlert ( )">
    Show Alert
</div>

<!-- This div is on top of everything except the popup div -->
<!-- It effectively disables the entire app except for the popup -->
<div id="disabler" class="disabler" onclick="togglePopup ( )"></div>

<!-- This div holds the popup -->
<!-- You can only close the popup by clicking the close button, or the disabler background -->
<!-- Clicking in the blue popup area doesn't do anything (intentionally) -->
<!-- Even though you can see other widgets through the disabler, they're all inaccessible -->
<!-- Try the show alert button to confirm -->
<div id="popup" class="popup">
    <div class="button" onclick="togglePopup ( )">
            Close Popup
    </div>
</div>

<script type="text/javascript">
    togglePopup ( ); // Hide them to start.
    function togglePopup ( ) {
        let disabler = document.getElementById ( 'disabler' );
        disabler.style.display = disabler.style.display ? '' : 'none';

        let popup = document.getElementById ( 'popup' );
        popup.style.display = popup.style.display ? '' : 'none';
    }

    function showAlert ( ) {
        alert ( 'Hey there!' );
    }
</script>

</body>

</html>

谢谢你的回答。但我没有明白你的回答。"disabler" div是什么? - temp
我会发布一个例子。 - Tim Consolazio

3
这是完成此操作的方法:
Javascript
popup.addEventListener('click',function(e) {
// This is important to prevent the popup from inheriting the event since it 
// is inside the body

    e.stopPropagation();
});

var body = document.body;
body.addEventListener('click', function(e){
    if(popup.classList.contains('show')) {
        popup.classList.remove("show");
    }
);

我希望这能解决你的问题

编辑
那个方法不起作用是因为你必须像这样正确地构建你的代码:

HTML

<div id='popup-container'>
    <!-- This all inside the popup -->
    <h5 class="haead">Search for a product title</h5>
    <div class="popup-data">
        <img class="qnicon" src="question.png">
        <span class="popuptext" id="myPopup5">Search product.</span>
    </div>
    <a href="#" id="show-popup">Show Popup</a>
</div>


Javascript

var popupContainer = document.getElementById('popup-container');
var body = document.body;
var showPopup = document.getElementById('show-popup');

showPopup.addEventListener('click', function(e) {
    e.preventDefault();
    popupContainer.classList.add('show');
});

popupContainer.addEventListener('click', function(e) {
    e.stopPropagation();
});

body.addEventListener('click', function(e) {
    if(popupContainer.classList.contains('show'))
        popupContainer.classList.remove('show');
);

代码运行良好,你的代码结构中有其他问题。如果你想测试我的代码,可以在 body 的事件监听函数内写入类似以下内容:console.log('it works'),你会发现该函数能够正常工作。 - Hamed Adil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接