jQuery - Dialogs vanish when one is closed/destroyed
I'm building an application that makes extensive use of jQuery UI Dialogs. I ran into an issue that happens when opening multiple dialogs at once, and can't really figure out how to fix it, if possible at all.
Basically, it goes like this:
- User opens dialog
A
(top: 100px, height: 300px) - User opens dialog
B
(top: 100px, height: 300px) - User closes dialog
A
- All dialogs opened after dialog
A
shifts up. e.g.: dialogB
top
property substracts dialogA
height
(100px - 300px = -200px): dialogs vanish.
I've come to that conclusion by using Firebug Inspect and Web Developer.
If dialog B
(opened after dialog A
) is closed first, the problem does not occur. I've tried with a vanilla UI as well (i.e.: no stylesheets other than jQuery's loaded), and it still happens. There seems to be an trigger when a dialog closes that I can't override.
Using position: fixed;
( as suggested by @TheVillageIdiot ) fixes it, but is still happens when the dialog is destroyed.
Here's an example:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title></title>
<link type="text/css" rel="stylesheet" media="all" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/ui-lightness/jquery-ui.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
</head>
<body>
<div id="dialog-1">
</div>
<div id="dialog-2">
</div>
<script type="text/javascript">
$('#dialog-1').dialog({
close: function() {
$(this).dialog('destroy');
},
height: 300,
position: [100, 100],
show: 'scale',
hide: 'drop',
resizable: false,
title: 'A',
});
$('#dialog-2').dialog({
close: function() {
$(this).dialog('destroy');
},
height: 300,
position: [100, 100],
show: 'scale',
hide: 'drop',
开发者_如何学Go resizable: false,
title: 'B',
});
</script>
</body>
</html>
Any suggestions are much appreciated.
It's probably because your dialogs aren't in position: absolute
, so the position (i.e. top:X) of dialog B
is calculated relatively to the position (top:Y) of dialog A
.
So let's say that absolute position of dialog B is top: 20px
, and dialog A is top: 10px
, the assigned CSS position of dialog B
will be top: 10px
because it's relative to dialog A
. So when dialog A
is destroyed, the position of dialog B
(top: 10px
) becomes relative to the element that was before dialog A
, most likely higher, hence going upwards in your window.
The solution is quite simple: set your dialog CSS position
attribute to absolute
. jQuery UI should catch up and calculate the positions properly.
P.S.: Just make sure you define your CSS absolute position after loading the jQuery UI CSS stylesheet, to make sure that yours override jQuery's.
From a UI standpoint, I'm a little concerned by the fact that you're firing multiple dialogs simultaneously. In UI patterns, several studies have concluded that a modal dialog is very disruptive, so ideally it's to be used in a situation where you absolutely have to interupt the rest of the process to make something happen or warn the user. Doing dialog after dialog in succession could probably be better accomplished in a pattern such as a wizard in a non-modal environment.
Alternatively, there are multiple notification widgets that do this sort of thing quite nicely. For example:
http://www.erichynds.com/examples/jquery-notify/
http://www.thinkbohemian.com/2010/04/22/stack-overflow-style-notifications-using-jquery/
Ok, that being said, I HAVE done this a few times, notably when I'm alerting a user that a process is happening and then telling them that the process has succeeded/failed. Rather than throwing up both and destroying one, the solution was to throw one up, destroy it, then sequentially instantiate the others. This could be done via button click in the jQuery dialog code itself for examples where you need user interaction, or it could be done automatically by a server-side script that "tells" the UI to destroy one and build another when notifying about a process. Either way, instantiating a script intended to create a single element multiple times and then expecting it to "stack" is inviting bugs with all the browser issues (cough, cough IE) out there.
精彩评论