SOLVED: SEE "CORRECTED SOLUTION" Area (below)
--------------------------------- ORIGINAL TEXT ---------------------------
I've created a JavaScript toaster popup to show info about an individual row. It works great in FireFox...but it goes down in flames in IE.
...suggestions and help appreciated.
WHAT I THINK IS FAILING: I think I declared the "Toaster" class wrong and IE isn't doesn't recognize it as an array. As such, when I call "PopUp(clientId)" on the toaster it fails becuase it doesn't traverse the array.
Additionally, FireFox populates the array correctly in the documents "ready" function...but I'm not sure IE is doing so.
Lastly, since I am still new to JavaScript it (obviously) could be HOW I am creating the classes (as well).
WHERE IT FAILS: The code fails because the value of "target" is null. This variable is null because IE doesn't seem to traverse the Toaster (array).
this.PopUp = function(clientId) {
var target = null;
jQuery.each(this, function() {
// Hide previous
if (jQuery(this)[0].IsUp)
jQuery(this)[0].PopDown();
if (jQuery(this)[0].ClientId == clientId)
target = jQuery(this)[0];
});
// Show current
target.PopUp();
}
THE FULL CODE SET: Thanks for the help...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title></title>
<script src="../Includes/JavaScript/jQuery/Core/jquery-1.3.2.js" type="text/javascript"></script>
<style type="text/css">
.toast
{
width: 100%;
position: relative;
}
.toastBorder
{
width: 100%;
position: absolute;
border-radius-topright:.5em;
border-radius-topleft:.5em;
-moz-border-radius-topright:.5em;
-moz-border-radius-topleft:.5em;
-webkit-border-radius-topright:.5em;
-webkit-border-radius-topleft:.5em;
background-color: #FFFFCC;
border: 1px solid #969696;
border-bottom-color: White;
display:none;
height: 0;
bottom: 0;
}
.toastForm
{
display:none;
}
</style>
<script type="text/javascript">
// CLASS DEFINITION:
function Toast(clientId, height, speed) {
// PROPERTIES
this.IsUp = false;
this.IsDown = false;
this.ClientId = clientId;
this.Height = height;
this.Speed = speed;
// METHODS
this.PopUp = function() {
if (this.IsUp) { return; }
this.IsUp = true;
this.IsDown = false;
var speed = this.Speed;
var action = '+=' + this.Height + "px";
// Border
jQuery('#' + this.ClientId).children('div.toastBorder').fadeIn('fast', function() {
jQuery(this).animate({ height: action }, speed, function() {
// Form
jQuery(this).children('div.toastForm').fadeIn('fast');
});
});
}
this.PopDown = function() {
if (this.IsDown) { return; }
this.IsUp = false;
this.IsDown = true;
var speed = this.Speed;
var action = '-=' + this.Height + "px";
// Form
jQuery('#' + this.ClientId).children('div.toastBorder').children('div.toastForm').fadeOut('fast');
// Border
jQuery('#' + this.ClientId + ' div.toastBorder').animate({ height: action }, speed, function() {
jQuery(this).fadeOut('fast');
});
}
}
// CLASS DEFINITION:
function Toaster() {
// PROPERTIES
// METHODS
this.PopUp = function(clientId) {
var target = null;
jQuery.each(this, function() {
// Hide previous
if (jQuery(this)[0].IsUp)
jQuery(this)[0].PopDown();
if (jQuery(this)[0].ClientId == clientId)
target = jQuery(this)[0];
});
// Show current
target.PopUp();
}
this.PopDown = function(clientId) {
jQuery.each(this, function() {
if (jQuery(this)[0].ClientId == clientId)
jQuery(this)[0].PopDown(); // Hide current
});
}
this.Add = function(toast) {
var found = false;
// No duplicates are allowed
jQuery.each(this, function() {
if (jQuery(this)[0].ClientId == toast.ClientId)
found = true;
});
if (!found)
this.push(toast);
}
}
// CLASS DEFINITION: Toaster inheritance
Toaster.prototype = new Array();
var myToaster;
var myToast;
// DOM EVENT: Document.Ready()
jQuery(document).ready(function() {
if (myToaster == null)
myToaster = new Toaster();
myToaster.Add(new Toast("row1", 100, 200));
myToaster.Add(new Toast("row2", 100, 200));
myToaster.Add(new Toast("row3", 100, 200));
myToaster.Add(new Toast("row4", 100, 200));
myToaster.Add(new Toast("row5", 100, 200));
// These BOTH return true in IE...
//alert(myToaster.Items instanceof Array);
//alert(myToaster instanceof Array);
// This is for the button example
if (myToast == null)
myToast = new Toast("row3", 100, 200);
});
</script>
</head>
<body>
<br />
I need help on the following:
<ul>
<li>
This works GREAT in FireFox
</li>
<li>
IE doesn't seem to recognize the Toaster class as being an array.
</li>
</ul>
<div style="width: 300;">
<label style="display:block;color: #660000;">INDIVIDUAL pieces of toast work fine in IE:</label>
<input type="button" value="Down (row 3)" onc开发者_如何学Golick="myToast.PopDown();" />
<input type="button" value="Up (row 3)" onclick="myToast.PopUp();" />
</div>
<br /><br />
<label style="color: #660000">Clicking a row IS SUPPOSED TO toggle a "piece of toast" for that row.</label>
<br /><br />
<table cellpadding="0" cellspacing="0" width="500" style=" border: solid 1px black">
<tr>
<td align="center" style="border-bottom: solid 1px black;">
Header
</td>
<td align="center" style="border-bottom: solid 1px black;">
Header
</td>
<td align="center" style="border-bottom: solid 1px black;">
Header
</td>
<td align="center" style="border-bottom: solid 1px black;">
Header
</td>
<td align="center" style="border-bottom: solid 1px black;">
Header
</td>
</tr>
<tr>
<td>
</td>
<td colspan="3">
<div id="row1" class="toast">
<div class="toastBorder">
<div align="center" class="toastForm">
<br />
Hello
<br /><br /><br /><br /><br />
</div>
</div>
</div>
</td>
<td>
</td>
</tr>
<tr onclick="myToaster.PopUp('row1');">
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
</tr>
<tr>
<td>
</td>
<td colspan="3">
<div id="row2" class="toast">
<div class="toastBorder">
<div align="center" class="toastForm">
<br />
Hello
<br /><br /><br /><br /><br />
</div>
</div>
</div>
</td>
<td>
</td>
</tr>
<tr onclick="myToaster.PopUp('row2');">
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
</tr>
<tr>
<td>
</td>
<td colspan="3">
<div id="row3" class="toast">
<div class="toastBorder">
<div align="center" class="toastForm">
<br />
Hello
<br /><br /><br /><br /><br />
</div>
</div>
</div>
</td>
<td>
</td>
</tr>
<tr onclick="myToaster.PopUp('row3');">
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
</tr>
<tr>
<td>
</td>
<td colspan="3">
<div id="row4" class="toast">
<div class="toastBorder">
<div align="center" class="toastForm">
<br />
Hello
<br /><br /><br /><br /><br />
</div>
</div>
</div>
</td>
<td>
</td>
</tr>
<tr onclick="myToaster.PopUp('row4');">
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
</tr>
<tr>
<td>
</td>
<td colspan="3">
<div id="row5" class="toast">
<div class="toastBorder">
<div align="center" class="toastForm">
<br />
Hello
<br /><br /><br /><br /><br />
</div>
</div>
</div>
</td>
<td>
</td>
</tr>
<tr onclick="myToaster.PopUp('row5');">
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
</tr>
</table>
</body>
</html>
HERE IS THE CORRECTED SOLUTION:
// CLASS DEFINITION:
function Toast(clientId, maxHeight, speed) {
// PROPERTIES
this.ClientId = clientId;
this.MaxHeight = maxHeight;
this.Speed = speed;
// METHODS
this.IsUp = function() {
return (jQuery('#' + this.ClientId).children().height() > 0) ? true : false;
}
this.PopUp = function() {
if (this.IsUp()) { return; }
var speed = this.Speed;
var action = '+=' + this.MaxHeight + "px";
// Border
jQuery('#' + this.ClientId).children('div.toastBorder').fadeIn('fast', function() {
jQuery(this).animate({ height: action }, speed, function() {
// Form
jQuery(this).children('div.toastForm').fadeIn('fast');
});
});
this.IsUp(true);
}
this.PopDown = function() {
if (!this.IsUp()) { return; }
var speed = this.Speed;
var action = '-=' + this.MaxHeight + "px";
// Form
jQuery('#' + this.ClientId).children('div.toastBorder').children('div.toastForm').fadeOut('fast');
// Border
jQuery('#' + this.ClientId).children('div.toastBorder').animate({ height: action }, speed, function() {
jQuery(this).fadeOut('fast');
});
this.IsUp(false);
}
}
// CLASS DEFINITION:
function Toaster() {
// PROPERTIES
this.Items = new Array();
// METHODS
this.PopUp = function(clientId) {
var target = null;
jQuery.each(this.Items, function() {
if (jQuery(this)[0].ClientId != clientId) {
if (jQuery(this)[0].IsUp()) {
jQuery(this)[0].PopDown(); // Hide previous
}
}
if (jQuery(this)[0].ClientId == clientId) {
target = jQuery(this)[0];
}
});
if (target != null) {
if (target.IsUp() == false)
target.PopUp();
}
}
this.PopDown = function(clientId) {
jQuery.each(this.Items, function() {
if (jQuery(this)[0].ClientId == clientId)
jQuery(this)[0].PopDown(); // Hide current
});
}
this.Add = function(toast) {
var found = false;
// No duplicates are allowed
jQuery.each(this.Items, function() {
if (jQuery(this.Items)[0].ClientId == toast.ClientId)
found = true;
});
if (!found)
this.Items.push(toast);
}
}
var myToaster;
var myToast;
// DOM EVENT: Document.Ready()
$j(document).ready(function() {
if (myToaster == null)
myToaster = new Toaster();
myToaster.Add(new Toast("row1", 125, 200));
myToaster.Add(new Toast("row2", 125, 200));
myToaster.Add(new Toast("row3", 125, 200));
myToaster.Add(new Toast("row4", 125, 200));
myToaster.Add(new Toast("row5", 125, 200));
});
</script>
The attempt to "subclass" Array by using it as the prototype object for your "Toaster" class is not going to work in IE, for whatever reason. If you debug the "Add" method, you'll notice that calls to "push" don't seem to fail, but they also don't change the length of the Toaster.
Trying to make Javascript act like a nice polite object-oriented language is fraught with peril, particularly when you try and treat the native types (like Array) as if they're implemented in Javascript too.
I'd just keep an array around as part of "Toaster" someplace.
精彩评论