JavaScript 中的自定义“确认”对话框?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6929416/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Custom "confirm" dialog in JavaScript?
提问by Vivian River
I've been working on an ASP.net project that uses custom 'modal dialogs'. I use scare quotes here because I understand that the 'modal dialog' is simply a div in my html document that is set to appear "on top" of the rest of the document and is not a modal dialog in the true sense of the word.
我一直在研究一个使用自定义“模态对话框”的 ASP.net 项目。我在这里使用恐吓引号是因为我知道“模态对话框”只是我的 html 文档中的一个 div,它被设置为显示在文档其余部分的“顶部”,而不是真正意义上的模态对话框.
In many parts of the web site, I have code that looks like this:
在网站的许多部分,我的代码如下所示:
var warning = 'Are you sure you want to do this?';
if (confirm(warning)) {
// Do something
}
else {
// Do something else
}
This is okay, but it would be nice to make the confirm dialog match the style of the rest of the page.
这没关系,但是让确认对话框与页面其余部分的样式相匹配会很好。
However, since it is not a true modal dialog, I think that I need to write something like this: (I use jQuery-UI in this example)
然而,由于它不是一个真正的模态对话框,我认为我需要写这样的东西:(我在这个例子中使用了 jQuery-UI)
<div id='modal_dialog'>
<div class='title'>
</div>
<input type='button' value='yes' id='btnYes' />
<input type='button' value='no' id='btnNo' />
</div>
<script>
function DoSomethingDangerous() {
var warning = 'Are you sure you want to do this?';
$('.title').html(warning);
var dialog = $('#modal_dialog').dialog();
function Yes() {
dialog.dialog('close');
// Do something
}
function No() {
dialog.dialog('close');
// Do something else
}
$('#btnYes').click(Yes);
$('#btnNo').click(No);
}
Is this a good way to accomplish what I want, or is there a better way?
这是完成我想要的东西的好方法,还是有更好的方法?
回答by alnorth29
You might want to consider abstracting it out into a function like this:
您可能需要考虑将其抽象为这样的函数:
function dialog(message, yesCallback, noCallback) {
$('.title').html(message);
var dialog = $('#modal_dialog').dialog();
$('#btnYes').click(function() {
dialog.dialog('close');
yesCallback();
});
$('#btnNo').click(function() {
dialog.dialog('close');
noCallback();
});
}
You can then use it like this:
然后你可以像这样使用它:
dialog('Are you sure you want to do this?',
function() {
// Do something
},
function() {
// Do something else
}
);
回答by Joshua Pinter
SweetAlert
甜蜜警报
You should take a look at SweetAlertas an option to save some work. It's beautiful from the default state and is highly customizable.
您应该查看SweetAlert作为保存一些工作的选项。它在默认状态下很漂亮,并且是高度可定制的。
Confirm Example
确认示例
sweetAlert(
{
title: "Are you sure?",
text: "You will not be able to recover this imaginary file!",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "Yes, delete it!"
},
deleteIt()
);
回答by Alper Aydingül
var confirmBox = '<div class="modal fade confirm-modal">' +
'<div class="modal-dialog modal-sm" role="document">' +
'<div class="modal-content">' +
'<button type="button" class="close m-4 c-pointer" data-dismiss="modal" aria-label="Close">' +
'<span aria-hidden="true">×</span>' +
'</button>' +
'<div class="modal-body pb-5"></div>' +
'<div class="modal-footer pt-3 pb-3">' +
'<a href="#" class="btn btn-primary yesBtn btn-sm">OK</a>' +
'<button type="button" class="btn btn-secondary abortBtn btn-sm" data-dismiss="modal">Abbrechen</button>' +
'</div>' +
'</div>' +
'</div>' +
'</div>';
var dialog = function(el, text, trueCallback, abortCallback) {
el.click(function(e) {
var thisConfirm = $(confirmBox).clone();
thisConfirm.find('.modal-body').text(text);
e.preventDefault();
$('body').append(thisConfirm);
$(thisConfirm).modal('show');
if (abortCallback) {
$(thisConfirm).find('.abortBtn').click(function(e) {
e.preventDefault();
abortCallback();
$(thisConfirm).modal('hide');
});
}
if (trueCallback) {
$(thisConfirm).find('.yesBtn').click(function(e) {
e.preventDefault();
trueCallback();
$(thisConfirm).modal('hide');
});
} else {
if (el.prop('nodeName') == 'A') {
$(thisConfirm).find('.yesBtn').attr('href', el.attr('href'));
}
if (el.attr('type') == 'submit') {
$(thisConfirm).find('.yesBtn').click(function(e) {
e.preventDefault();
el.off().click();
});
}
}
$(thisConfirm).on('hidden.bs.modal', function(e) {
$(this).remove();
});
});
}
// custom confirm
$(function() {
$('[data-confirm]').each(function() {
dialog($(this), $(this).attr('data-confirm'));
});
dialog($('#customCallback'), "dialog with custom callback", function() {
alert("hi there");
});
});
.test {
display:block;
padding: 5p 10px;
background:orange;
color:white;
border-radius:4px;
margin:0;
border:0;
width:150px;
text-align:center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
example 1
<a class="test" href="http://example" data-confirm="do you want really leave the website?">leave website</a><br><br>
example 2
<form action="">
<button class="test" type="submit" data-confirm="send form to delete some files?">delete some files</button>
</form><br><br>
example 3
<span class="test" id="customCallback">with callback</span>
回答by user3284707
To enable you to use the confirm box like the normal confirm dialog, I would use Promises which will enable you to await on the result of the outcome and then act on this, rather than having to use callbacks.
为了使您能够像正常的确认对话框一样使用确认框,我将使用 Promises,这将使您能够等待结果的结果,然后对此采取行动,而不必使用回调。
This will allow you to follow the same pattern you have in other parts of your code with code such as...
这将允许您使用与代码其他部分相同的模式,例如...
const confirm = await ui.confirm('Are you sure you want to do this?');
if(confirm){
alert('yes clicked');
} else{
alert('no clicked');
}
See codepen for example, or run the snippet below.
例如,请参阅 codepen,或运行下面的代码段。
https://codepen.io/larnott/pen/rNNQoNp
https://codepen.io/larnott/pen/rNNQoNp
const ui = {
confirm: async (message) => createConfirm(message)
}
const createConfirm = (message) => {
return new Promise((complete, failed)=>{
$('#confirmMessage').text(message)
$('#confirmYes').off('click');
$('#confirmNo').off('click');
$('#confirmYes').on('click', ()=> { $('.confirm').hide(); complete(true); });
$('#confirmNo').on('click', ()=> { $('.confirm').hide(); complete(false); });
$('.confirm').show();
});
}
const saveForm = async () => {
const confirm = await ui.confirm('Are you sure you want to do this?');
if(confirm){
alert('yes clicked');
} else{
alert('no clicked');
}
}
body {
margin: 0px;
font-family: "Arial";
}
.example {
padding: 20px;
}
input[type=button] {
padding: 5px 10px;
margin: 10px 5px;
border-radius: 5px;
cursor: pointer;
background: #ddd;
border: 1px solid #ccc;
}
input[type=button]:hover {
background: #ccc;
}
.confirm {
display: none;
}
.confirm > div:first-of-type {
position: fixed;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
top: 0px;
left: 0px;
}
.confirm > div:last-of-type {
padding: 10px 20px;
background: white;
position: absolute;
width: auto;
height: auto;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border-radius: 5px;
border: 1px solid #333;
}
.confirm > div:last-of-type div:first-of-type {
min-width: 150px;
padding: 10px;
}
.confirm > div:last-of-type div:last-of-type {
text-align: right;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="example">
<input type="button" onclick="saveForm()" value="Save" />
</div>
<!-- Hidden confirm markup somewhere at the bottom of page -->
<div class="confirm">
<div></div>
<div>
<div id="confirmMessage"></div>
<div>
<input id="confirmYes" type="button" value="Yes" />
<input id="confirmNo" type="button" value="No" />
</div>
</div>
</div>
回答by James Hill
I would use the example given on jQuery UI's site as a template:
我将使用 jQuery UI 站点上给出的示例作为模板:
$( "#modal_dialog" ).dialog({
resizable: false,
height:140,
modal: true,
buttons: {
"Yes": function() {
$( this ).dialog( "close" );
},
"No": function() {
$( this ).dialog( "close" );
}
}
});
回答by andro83
One other way would be using colorbox
另一种方法是使用 colorbox
function createConfirm(message, okHandler) {
var confirm = '<p id="confirmMessage">'+message+'</p><div class="clearfix dropbig">'+
'<input type="button" id="confirmYes" class="alignleft ui-button ui-widget ui-state-default" value="Yes" />' +
'<input type="button" id="confirmNo" class="ui-button ui-widget ui-state-default" value="No" /></div>';
$.fn.colorbox({html:confirm,
onComplete: function(){
$("#confirmYes").click(function(){
okHandler();
$.fn.colorbox.close();
});
$("#confirmNo").click(function(){
$.fn.colorbox.close();
});
}});
}
回答by Peter Cyrus
Faced with the same problem, I was able to solve it using only vanilla JS, but in an ugly way. To be more accurate, in a non-procedural way. I removed all my function parameters and return values and replaced them with global variables, and now the functions only serve as containers for lines of code - they're no longer logical units.
面对同样的问题,我只能使用 vanilla JS 来解决它,但方法很丑陋。更准确地说,以非程序方式。我删除了所有函数参数和返回值,并用全局变量替换它们,现在函数仅用作代码行的容器——它们不再是逻辑单元。
In my case, I also had the added complication of needing many confirmations (as a parser works through a text). My solution was to put everything up to the first confirmation in a JS function that ends by painting my custom popup on the screen, and then terminating.
就我而言,我还增加了需要多次确认的复杂性(因为解析器通过文本工作)。我的解决方案是在 JS 函数中进行第一次确认,最后在屏幕上绘制我的自定义弹出窗口,然后终止。
Then the buttons in my popup call another function that uses the answer and then continues working (parsing) as usual up to the next confirmation, when it again paints the screen and then terminates. This second function is called as often as needed.
然后我的弹出窗口中的按钮调用另一个使用答案的函数,然后像往常一样继续工作(解析)直到下一次确认,当它再次绘制屏幕然后终止时。根据需要经常调用第二个函数。
Both functions also recognize when the work is done - they do a little cleanup and then finish for good. The result is that I have complete control of the popups; the price I paid is in elegance.
这两个函数还可以识别工作何时完成 - 它们会进行一些清理,然后永久完成。结果是我完全控制了弹出窗口;我付出的代价是优雅。