JavaScript在使用Jquery插入LI元素时,有时不会调整UL元素的高度

我有一个Html/JavaScript应用程序,它包含N个列,这些列需要足够大才能包含所有列中所有可能的LI元素

简单的解决方案似乎是计算每列中所有项目的高度,补偿填充,然后将每列的高度设置为总高度

当LI元素包含纯文本时,这非常有效。不幸的是,当LI元素包含图像时,各种浏览器都会出现问题。例如,当我第一次在FireFox中加载页面时,它看起来像下面的屏幕截图,但在再次刷新时,它工作正常。在Chrome中,它也不能像预期的那样工作

我的应用程序在页面加载时不预填充LI元素-它使用JavaScript,如下所示:

函数populateUnsenstanswers(未设置类别和应答器){
对于(我在未确定类别中回答){
if(unsetCategoryAnswers.hasOwnProperty(i.toString())){
$(“#类别问题区#可能答案”)。追加(
categoryAnswerLiTag(未设置的categoryanswers[i])
);
}
}
}
函数categoryAnswerLiTag(未设置categoryanswer){
var html='<li id=“”+unsetCategoryAnswer.id+”>
if(未设置类别和应答图像){
html+='<img class=“categoryAnswerImage”title=“”;
html+=unsetCategoryAnswer.text;
html+='“src=”https://stackoverflow.com/trainingdividend/rest/streaming/';
html+=unsettegoryanswer.image.fileName;
html+=“style=”高度:”;
html+=unsettegoryanswer.image.height;
html+=';';
html+=“/>”;
}否则{
html+=未设置的类别yanswer.text
}
html+='</li>';
返回html;
}

加载完页面后,ajax请求获取要放入LI元素的所有对象,然后调用上面的第一个函数

创建完所有LI元素后,我立即调用该函数:

函数调整大小(){
var currentHeight,totalHeight;
总高度=0;
$(“#categoryQuestionArea ul”).children().each(function()){
currentHeight=$(this).height();
总高度+=当前高度+13;
});
$(“#类别问题区域ul”).高度(总高度);
$(“#类别问题区域分区#分隔符”).css(“填充顶部”,(总高度/2)+“px”);
}

有没有办法告诉jQuery,“在所有LI完全加载并渲染图像之前,不要调用resize()”

我认为在初始页面加载时,这些LI元素的高度是0或一个小值,因为它不包含图像,所以我的resize函数计算的结果是错误的(我用一些警告语句对此进行了测试)。只要填充了LIs并加载了图像,总高度就可以很好地计算出来

有什么帮助吗?谢谢

要真正回答您提出的问题,如果您只想在所有图像加载完毕后调用resize(),则需要为这些图像安装onload处理程序,并且在记录最后一个图像现在已加载时,可以调用resize()函数。您可以这样做(下面的代码解释):

var remainingAnswerImages=0;
函数categoryAnswerImageLoadHandler(){
--保留应答图像;
如果(保留回答图像===0){
调整大小();
}
}
函数populateUnsetAnswers(未设置类别和应答器){
//增加一个额外的图像计数,这样我们就没有任何机会了
//在加载所有图像之前达到零
++保留应答图像;
var possibleAnswers$=$(“#类别问题区#possibleAnswers”);
对于(我在未确定类别中回答){
if(unsetCategoryAnswers.hasOwnProperty(i.toString())){
可能的回答$.append(categoryAnswerLiTag(unsetegoryanswers[i]);
}
}
//取下一个额外的
--保留应答图像;
//如果我们的计数为零,那么要么没有图像
//或者立即从缓存中加载所有这些文件
//如果这里的计数不是零,那么
//categoryAnswerImageLoadHandler()函数将检测何时达到零
如果(保留回答图像===0){
调整大小();
}
}
函数categoryAnswerLiTag(未设置categoryanswer){
var obj=document.createElement(“li”);
obj.id=未设置的类别和swer.id;
if(未设置类别和应答图像){
//数一数这张照片
++保留应答图像;
var img=新图像();
img.onload=img.onerror=img.onabort=categoryAnswerImageLoadHandler;
img.title=unsettegoryanswer.text;
img.style.height=未设置类别swer.image.height;
img.src=”https://stackoverflow.com/trainingdividend/rest/streaming/“+unsettegoryanswer.image.fileName;
目标儿童(img);
}否则{
obj.innerHTML=unsetCategoryAnswer.text;
}
返回obj;
}

作为说明,此代码进行了以下更改:

  • 添加一个变量remainingAnswerImages,以跟踪仍需要加载多少图像
  • 为每个添加一个onload处理程序<img&gt创建的标记,以便我们可以跟踪加载的时间
  • 每次使用onload处理程序为标记生成HTML时,递增remainingAnswerImages
  • 添加完所有HTML后,请检查remainingAnswerImages计数是否为零(只有在没有图像或所有图像立即从浏览器缓存加载时才会出现这种情况)。如果是,请立即调用resize()
  • 在将为每个图像调用的onload处理程序中,减量remainingAnswerImages,如果计数已达到零,则调用resize()
  • 添加图像时,在remainingAnswerImages中添加一个额外的门,以防止在添加完图像之前计数为零。添加完图像后,再多加一张
  • 我还重写了categoryAnswerLiTag()函数,直接创建DOM对象,而不是将一堆字符串合并成HTML。在这种情况下,代码更易于阅读和维护
  • 我还将$(“#categoryQuestionArea#possibleAnswers”)for循环中移出,因为它每次都解析为相同的内容。最好在循环之前做一次。此外,在大多数情况下,这可以简化为$(“#possibleAnswers”),因为ID在页面中应该是唯一的

发表评论