简单的解决方案似乎计算每列中所有项目的高度,补偿填充,然后将高度设置为每个列的总计.
当LI元素包含纯文本时,这很有用.不幸的是,当LI元素包含图像时,各种浏览器都有问题.例如,当我首先在FireFox中加载页面时,它看起来像下面的截图,但是在另一次刷新时,它的工作正常.它在Chrome中无法正常工作.
我的应用程序在页面加载时不预填充LI元素 – 它使用JavaScript,如下所示:
function populateUnsetAnswers(unsetCategoryAnswers) { for (i in unsetCategoryAnswers) { if (unsetCategoryAnswers.hasOwnProperty(i.toString())) { $('#categoryQuestionArea #possibleAnswers').append( categoryAnswerLiTag(unsetCategoryAnswers[i]) ); } } } function categoryAnswerLiTag(unsetCategoryAnswer) { var html = '<li id="' + unsetCategoryAnswer.id + '">'; if (unsetCategoryAnswer.image) { html += '<img class="categoryAnswerImage" title="'; html += unsetCategoryAnswer.text; html += '" src="/trainingdividend/rest/streaming/'; html += unsetCategoryAnswer.image.fileName; html += '" style="height: '; html += unsetCategoryAnswer.image.height; html += ';'; html += '" />'; } else { html += unsetCategoryAnswer.text } html += '</li>'; return html; }
当页面完成加载时,ajax请求将所有要放入LI元素的对象取出,然后调用上面的第一个函数.
function resize() { var currentHeight,totalHeight; totalHeight = 0; $("#categoryQuestionArea ul").children().each(function() { currentHeight = $(this).height(); totalHeight += currentHeight + 13; }); $("#categoryQuestionArea ul").height(totalHeight); $("#categoryQuestionArea div#separator").css("padding-top",(totalHeight / 2) + "px"); }
有没有办法告诉jQuery,“不要调用resize(),直到所有的LI都被完全加载并且图像已经呈现”?
我认为发生的情况是,在初始页面加载时,这些LI元素的高度是0或一个小的值,因为它不包含图像,所以我的resize函数是计算错误的结果(我用一些警报语句进行了测试).只要LI填充并且图像已经加载,总高度就算好了.
任何帮助?谢谢
解决方法
var remainingAnswerImages = 0; function categoryAnswerImageLoadHandler() { --remainingAnswerImages; if (remainingAnswerImages === 0) { resize(); } } function populateUnsetAnswers(unsetCategoryAnswers) { // add one extra to the image count so we won't have any chance // at getting to zero before loading all the images ++remainingAnswerImages; var possibleAnswers$= $('#categoryQuestionArea #possibleAnswers'); for (i in unsetCategoryAnswers) { if (unsetCategoryAnswers.hasOwnProperty(i.toString())) { possibleAnswers$.append(categoryAnswerLiTag(unsetCategoryAnswers[i])); } } // remove the one extra --remainingAnswerImages; // if we hit zero on the count,then there either were no images // or all of them loaded immediately from the cache // if the count isn't zero here,then the // categoryAnswerImageLoadHandler() function will detect when it does hit zero if (remainingAnswerImages === 0) { resize(); } } function categoryAnswerLiTag(unsetCategoryAnswer) { var obj = document.createElement("li"); obj.id = unsetCategoryAnswer.id; if (unsetCategoryAnswer.image) { // count this image ++remainingAnswerImages; var img = new Image(); img.onload = img.onerror = img.onabort = categoryAnswerImageLoadHandler; img.title = unsetCategoryAnswer.text; img.style.height = unsetCategoryAnswer.image.height; img.src = "/trainingdividend/rest/streaming/" + unsetCategoryAnswer.image.fileName; obj.appendChild(img); } else { obj.innerHTML = unsetCategoryAnswer.text; } return obj; }
通过说明,此代码进行了以下更改:
>添加一个变量remainingAnswerImages来跟踪还需要加载多少图像.>为每个< img>添加一个onload处理程序标签被创建,所以我们可以跟踪加载的时间.>每次我们使用onload处理程序生成一个标签的HTML,增加remainingAnswerImages.>完成添加所有HTML后,请检查其余的AustwerImages计数以查看是否为零(只有当没有图像或者所有图像立即从浏览器缓存中加载时,才会这样).如果是这样,请立即调用resize().>在将为每个图像调用的onload处理程序中,减少remainingAnswerImages,如果计数达到零,调用resize().>在添加图像时,添加一个额外的剩余的作为一个门,以防止得到零计数,直到我们完成添加图像.完成添加图片后,再加一点.>我还重写了类别AnswerLiTag()函数,直接创建DOM对象,而不是将一串字符串并入HTML.在这种情况下,代码是更清洁的阅读和维护.>我还将$(‘#categoryQuestionArea #possibleAnswers’)从你的for循环中移出,因为它每次都解析为同样的事情.更好地在循环之前做一次.此外,在大多数情况下,这可以简化为$(‘#possibleAnswers’),因为ids应该在页面中是唯一的.