Accordian Element Height Issue
I have implemented 2 types of Accordians for my application- 1 Column and 2 Column
Im having a problem with the Static Height for the 1 Column Accordian. And I've been trying to modify the JavaScript all day but cant seem to get it to work.
The Heights should be dynamic in Height depending upon the amount data, however as you can see the Height is fixed, and some of the data is getting cut off: http://www.davincispainting.com/whydavincis.aspx
The other 2 Column Accordian has almost the same JavaScript as the 1 Column Accordian, however the Height is dynanmic depending on how much data there is: http://www.davincispainting.com/glossary.aspx
I would provide a Fiddle however the Data is now dynamic:
Here is the JavaScript for the problem Accordian: <script type="text/javascript">
$.fn.accordion = function () {
return this.each(function () {
$container = $('#mid-featureleft-client');
$container.find("dt").each(function () {
var $header = $(this);
var $selected = $header.next();
$header.click(function () {
$('.active').removeClass('active');
$(this).addClass('active');
if ($selected.is(":visible")) {
$selected.animate({
height: 0
}, {
duration: 300,
complete: function () {
$(this).hide();
}
});
} else {
$unselected = $container.find("dd:visible");
$selected.show();
var newHeight = heights[$selected.attr("id")];
var oldHeight = heights[$unselected.attr("id")];
$('<div>').animate({
height: 1
}, {
duration: 300,
step: function (now) {
var stepSelectedHeight = Math.round(newHeight * now);
$selected.height(stepSelectedHeight);
$unselected.height(oldHeight + Math.round((newHeight - oldHeight) * now) - Math.round(newHeight * now));
},
complete: function () {
$unselected.hide().css({
height: 0
});
}
});
}
return false;
});
});
// Iterate over panels, save heights, hide all.
var heights = new Object();
$container.find("dd").each(function () {
$this = $(this);
$this.css("overflow", "hidden");
heights[$this.attr("id")] = $this.height();
$this.hide().css({
height: 0
});
});
});
};
$(document).ready(function () {
$.getJSON('FaqsJson.ashx?factType=2', function (datas) {
var str_one = "";
str_one = "<dl>"
$.each(datas, function () {
str_one += "<dt class=\"glossquestion\"><a href=\"javascript://\" class=\"questionLink\">" + this['Question'] + "</a></dt>";
str_one += "<dd class=\"glossanswer\" style=\"-webkit-margin-start:0px\"><div class=\"answerbox\">" + this['Answer'] + "</div></dd>";
});
str_one += "</dl>";
$("#glossary_first").html(str_one);
$("#mid-featureleft-client").accordion();
});
});
</script>
Here is the relevent HTML:
<div id="mid-feature-client">
<div id="mid-featureleft-client">
<div id="glossary_first" class="controlbox">
<br /><br />
</div>
<div style="clear: both;">
</div>
</div>
</div>
Here is the relevent css:
#mid-featureleft-client .controlbox {
width:546px;
padding:3px 0 0 6px;
position:relative;
/*background-color:green;*/
}
#mid-featureleft-client .glossarycontrolbox {
width:260px;
padding:3px 0 0 6px;
position:relative;
float:left;
/*background-color:blue;*/
}
.question-clicked {
background-color: #CCCCCC;
color: #0C2A55;
/*margin-top: 10px;*/
/*padding: 2px 5px 0;*/
}
.questionLink-clicked {
color: #0C2A55;
font-size: 1.2em;
font-weight: bold;
}
.answerbox {
padding: 3px 5px 3px 5px;
}
.questionLink {
color: #0C2A55;
font-size: 1.2em;
font-weight: bold;
}
.glossquestion {
padding: 0 5px 4px 0;
}
.glossanswer {
background-color: #F9FBFC;
display: none;
}
#accordion .handle {
width: 260px;
height: 30px;
background-color: orange;
}
#accordion .section {
width: 260px;
height: 445px;
background-color: #a9a9a9;
overflow: hidden;
position: relative;
}
dt {
/*backgrou开发者_Python百科nd-color: #ccc;*/
}
dd {
/*height: 30px;*/
}
.active {
background: #a9a9a9;
}
The problem is with the way you're storing the heights, a bit after this comment:
// Iterate over panels, save heights, hide all.
Specifically, this line:
heights[$this.attr("id")] = $this.height();
Your dd
elements don't have an id
, so on each iteration of the loop, heights['']
is being set to the height of the current dd
.
You should be able to fix it by changing this:
$.each(datas, function () {
str_one += "<dt class=\"glossquestion\"><a href=\"javascript://\" class=\"questionLink\">" + this['Question'] + "</a></dt>";
str_one += "<dd class=\"glossanswer\" style=\"-webkit-margin-start:0px\"><div class=\"answerbox\">" + this['Answer'] + "</div></dd>";
});
to this:
var i = 0;
$.each(datas, function () {
str_one += "<dt class=\"glossquestion\"><a href=\"javascript://\" class=\"questionLink\">" + this['Question'] + "</a></dt>";
str_one += "<dd id=\"rand_" + i + "\" class=\"glossanswer\" style=\"-webkit-margin-start:0px\"><div class=\"answerbox\">" + this['Answer'] + "</div></dd>";
i++;
});
I'm just going to point out that my fix doesn't seem very jQuery-esque, and your entire code seems complicated for what it's doing.
If you changed your JSON to something like this:
[{"Question1":"..","Answer1":".."},{"Question2":"..","Answer2":".."}, .. ]
You could do this:
$.each(datas, function (i, v) {
str_one += "<dt class=\"glossquestion\"><a href=\"javascript://\" class=\"questionLink\">" + this['Question'] + "</a></dt>";
str_one += "<dd id=\"Dd" + i + "\" class=\"glossanswer\" style=\"-webkit-margin-start:0px\"><div class=\"answerbox\">" + this['Answer'] + "</div></dd>";
});
which is cleaner code than incrementing our own variable i
inside $.each
.
精彩评论