我在jhin主题经常遇到帖子内容自动折叠后无法展开的问题,在手机UC上遇到过,在电脑火狐上也遇到过。不过大多数时候只要刷新一下就好了,我也没太在意,直到我遇到了这个贴:
https://hu60.cn/q.php/bbs.topic.89312.html
嗯,就是这个贴,在我修复之前,用电脑版火狐以140%比例放大,无论怎么点击“展开隐藏内容”,内容都无法展开。
用于折叠的代码是这样的:
$(document).ready(function(){
// 自动折叠过长内容
var maxHeight = 768;
$(".topic-content,.floor-content").each(function(){
var that =$(this);
var id=this.getAttribute("data-floorID");
if(that.height() > maxHeight){
that.height(maxHeight);
$('#floor_fold_bar_'+id).html("<button data-floorID='"+id+"'>展开隐藏内容</button>");
$('#floor_fold_bar_'+id+">button").on('click',function(){
var id=this.getAttribute("data-floorID");
var that=$("#floor_content_"+id)
if(that.height()>maxHeight){
that.height(maxHeight);
this.innerHTML='展开超出内容';
}else{
that.height(that[0].scrollHeight);
this.innerHTML='折叠超出内容';
}
});
}
});
我盯着它大眼瞪小眼的看了很久,怎么看都觉得没问题啊。但是同样的帖子,在经典主题里面就没问题,展开折叠无比顺滑(虽然没有动画效果)。经典主题的代码是这样的:
function foldFold(floor) {
var content = document.getElementById('floor_content_' + floor);
var foldBar = document.getElementById('floor_fold_bar_' + floor);
content.style.maxHeight = '768px';
foldBar.innerHTML = '<a id="floor_expand_' + floor +
'" href="#" onclick="foldExpand(' + floor + ');return false">查看全部</a>';
}
function foldExpand(floor) {
var content = document.getElementById('floor_content_' + floor);
var foldBar = document.getElementById('floor_fold_bar_' + floor);
content.style.maxHeight = '';
foldBar.innerHTML = '<a id="floor_fold_' + floor +
'" href="#" onclick="foldFold(' + floor + ');return false">折叠内容</a>';
}
function foldFloorInit(floor) {
var content = document.getElementById('floor_content_' + floor);
var height = content.offsetHeight;
if (height > 768) {
var foldBar = document.getElementById('floor_fold_bar_' + floor);
foldBar.style.borderTop = '1px solid #BED8EA';
foldBar.style.borderBottom = '1px solid #BED8EA';
foldBar.style.height = '24px';
foldBar.style.textAlign = 'center';
foldFold(floor);
}
}
function foldFloorOnload(floorSize) {
var i;
for (i=0; i<floorSize; i++) {
foldFloorInit(i);
}
}
我想了很多种可能,比如JQuery未正常加载、that[0].scrollHeight
与火狐兼容性不好等等,但随后都被一一否决了。最核心的问题是:只要我稍微改变一下网页的放大倍数,问题就不会出现。这个问题看起来只在140%放大比例下出现,所以JQuery加载和兼容性都不太可能。
然后,我尝试把that.height(maxHeight);
改成that.css('max-height', maxHeight+'px');
,但还是只在140%放大比例下出问题。万般无奈之下,我只好打开脚本调试器。然后我就看到了惊人的运行轨迹:
that.height()>maxHeight
???
明明that.height(maxHeight);
已经被反复执行了好几次,但接下来的每一次that.height()>maxHeight
判断都为真???!!!
于是我把console.log(that.height(), maxHeight, that.height()>maxHeight);
添加到了代码中,结果如下:
答案显而易见了,因为that.height()
是浮点数,即使将其设置为768,结果也可能不是768,而是比768大或者小那么一点点。然后比较的时候就……
而这个问题之所以只在特定的放大比例下出现,是因为其他比例下浏览器的内部浮点实现恰好可以精确存储768px,或者存储后的结果比768小(767.9999999...),而140%放大比例下对768px(实际为768
x1.4
=1075.2
px)的存储结果恰好比768大。。。。。。
于是果断改成了
if(this.innerHTML == '折叠超出内容'){
that.height(maxHeight);
this.innerHTML='展开超出内容';
}else{
that.height(that[0].scrollHeight);
this.innerHTML='折叠超出内容';
}
问题解决,展开功能恢复。
这件事情再次提醒了我,浮点数不能精确比较大小,不仅是不能精确比较相等,也不能精确比较大于或者小于。在任一操作数为浮点型或者可能为浮点型的情况下,做差取绝对值是唯一安全的办法。
// 不会出问题的比较方法
// 相当于 if (that.height() == maxHeight)
if (Math.abs(that.height() - maxHeight) < 0.1)
@o,老虎故意的
老虎排查问题的能力思路知识量着实让人羡慕
@o,专门花了两小时给你打码
试了各种软件,最后还是用PS(实际是GIMP,和PS差不多)搞定了
就是用这方法:https://jingyan.baidu.com/article/19192ad815e90ee53e57070d.html
@o,好,我给原帖打码了
@o,可以,你随意