有没有办法像alert
,confirm
和prompt
(简称:“acp”)那样故意冻结浏览器窗口?
我想显示一个带有自定义css的模态对话框而不是“acp”的原生弹出窗口,但是也希望能够冻结浏览器,直到我得到用户反馈,就像“acp”一样。
但男人,为什么?这是不好的做法(呃,我必须downvote)! 所以当它是不好的做法 - 那么为什么“acp”实际上提供了这种同步行为呢?因为在某些特定情况下,它恰好是适合用户体验的正确工具。那些原生模态看起来很丑陋,同时也非常有限。
这里只是一个快速而肮脏的例子,在用户提供反馈之前冻结浏览器是完全可以的。让我们说我们有一个form
与input type="reset"
元素。因此,在我们真正让form
重置之前,我们会问用户:“您确定要重置(数据会丢失)吗?”。
如果我对原生模态外观(我不是)我可以做到:
var handleSubmit = function( e ) {
confirm('Are you sure you want to reset (data will be lost)?') || e.preventDefault()
}
$('form').on( 'reset', handleSubmit ) // just using jQuery here for the sake of shortness
// Edit to make Herohtar hopefully feel much better:
// using jQuery here for the sake of lazyness :)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<input placeholder="type something, reset and cancel to keep input value" style="width:100%">
<input type="reset">
</form>
所以“每个人”应该同意(编辑:或者至少有人可以)这不是坏习惯,对吗?
但是,如何使用自定义样式的模态/对话框/弹出窗口实现相同的目标呢?
我当然 - 不是要求HTML
/ CSS
部分,而是要求通过JavaScript冻结浏览器窗口的能力!
说实话,我实际上期待一些downvotes为此,但也许有一个杀手JavaScript忍者,谁有这一个特殊的黑客,使它成为可能...
注意:我确切知道如何在最后实现相同的结果,但我正在寻找一个实际的冻结/ synconous功能,以保持代码直接前进和更少hack-ish。
除弹出窗口外,您可以将所有内容放在div中。然后,您可以通过css打开/关闭指针事件。
div中的所有内容将不再具有可互动性。这将给出冻结浏览器窗口的外观。
.freeze { pointer-events: none; }
注意:将pointer-events
添加到元素时,这也会影响所有子元素,因此将其放在正文上也会锁定弹出窗口。
弹出窗口关闭后,我们可以从div中删除freeze
类,一切都将重新开始。
const content = document.getElementById('content')
const overlay = document.querySelector('.overlay')
const a = document.querySelector('.open-overlay')
const close = document.querySelector('.overlay .close')
// Open a popup and freeze the browser content
a.addEventListener('click', e => {
e.preventDefault()
content.classList.add('freeze')
overlay.classList.remove('hidden')
})
// Close the popup window and unfreeze the browser content
close.addEventListener('click', e => {
e.preventDefault()
content.classList.remove('freeze')
overlay.classList.add('hidden')
})
.freeze { pointer-events: none; }
.hidden { display: none; }
.overlay {
position: fixed;
z-index: 100;
padding: 20px;
background: white;
border: solid 1px #ccc;
width: 300px;
top: 20px;
left: 0;
right: 0;
margin: auto;
}
<div class="overlay hidden">
<h1>Overlay</h1>
<a href="" class="close">Close</a>
</div>
<div id="content">
<a href="" class="open-overlay">Open Overlay</a>
<p>Hello World</p>
<p>Hello World</p>
<p>Hello World</p>
<p>Hello World</p>
<p>Hello World</p>
<form>
<input type="text">
</form>
</div>
您不能像本机对话框那样冻结浏览器应用程序。这些不是使用JavaScript构建的,它们使用本机代码构建,并且可以以任何方式影响浏览器应用程序。禁止JavaScript以这种方式影响客户端应用程序。
但是,您可以在浏览器窗口中冻结与页面内容的交互....
只需在页面上方放置一个尺寸为div
的窗口,并固定定位。这将阻止用户能够与主页面上的任何内容进行交互(在其后面)。然后,在其上显示模态对话框。当用户清除模态时,隐藏它和窗口大小的div,从而使主页再次交互。
let modal = document.querySelector(".modal");
let pageCover = document.querySelector(".pageCover");
let main = document.querySelector("main");
document.getElementById("open").addEventListener("click", function(){
modal.classList.remove("hidden");
pageCover.classList.remove("hidden");
main.addEventListener("focus", preventFocus);
});
document.getElementById("close").addEventListener("click", function(){
modal.classList.add("hidden");
pageCover.classList.add("hidden");
main.removeEventListener("focus", preventFocus);
});
function preventFocus (evt){
evt.preventDefault();
}
.hidden { display:none; }
.pageCover {
position:fixed;
z-index:10;
background-color:rgba(0,0,0,.25);
width:100vw;
height:100vh;
top:0;
left:0;
}
.modal {
position:absolute;
z-index:100;
background-color:aliceblue;
border:2px double grey;
width:200px;
height:200px;
top:30%;
left:30%;
text-align:center;
}
.modalTitle {
margin:0;
background-color:#00a;
color:#ff0;
padding:5px;
font-weight:bold;
font-size:1.1em;
}
#close {
background-color:#800080;
color:#ff0;
border:1px solid #e0e0e0;
padding:5px 10px;
}
#close:hover { background-color:#c000c0; }
<main>
<h1>This is some page content</h1>
<p>And more content</p>
<button id="open">Click Me To Show Modal</button>
<div>More content</div>
</main>
<div class="hidden pageCover"></div>
<div class="hidden modal">
<div class="modalTitle">Modal Title Here</div>
<p>
Now, you can only interact with the contents of this "modal".
</p>
<button id="close" >Close</button>
</div>