遇到一个需求,写一个类QQ的文件列表,想把头部固定,下面内容滚动。暂时想到的办法是,头部元素<header></header>
和内容元素<main></main>
独立,然后每一列的元素<item></item>
放在<main></main>
里面,形成这样一个结构:
<div class="container">
<header></header>
<main>
<item></item>
<item></item>
</main>
</div>
其中header
、main
以及 item
的宽度都是100% ,为了让header
和item
里面的内容上下对齐,所以<header>和<item>
都选择了弹性布局。效果图如下:
但是问题出现了,在main
的内容超出高度后,出现了滚动条,由于滚动条有宽度,main
的内容(padding + content)变小,导致item
变小,而header
还是没变,直接导致了header
和item
的每个内容都不能对齐。
方案之一是通过JS和css同事来进行控制。
基本思路是,css方面,给mian预定一个滚动条的位置。js方面,获取浏览器的滚动条宽度,然后将header
的宽度减去滚动条宽度,补上(padding)。
//css,不管超不超出都先给容器一个滚动条的位置
main{
overflow-y:scroll;
}
//js
function listWidthChange(header,content){
var fileContentWidth = content[0].offsetWidth;
var fileContentScrollWidth = content[0].scrollWidth;
var scrollWidth = fileContentWidth - fileContentScrollWidth;
var fileHeaderNewWidth = fileContentWidth - scrollWidth;
header.css({
width: fileHeaderNewWidth,
paddingRight:fileHeaderNewWidth
});
}
$(function(){
listWidthChange($('header'),$('main'));
})
这样就解决问题了。如果以后还有别的好办法会回来更新。
<- - - - - - – - – - -分割线 – - - - - - - – - - - - - – >
上面的代码使用了offsetWidth
以及 scrollWidth
这个两个属性,获取了元素的宽两种宽度,从而计算出浏览器滚动条的宽度。
但JS还提供了很多宽高属性,下面总结一下:
//宽
var obj = document.getElementById(xxxxx);
obj.offsetWidth //返回元素宽度,不含外边距(margin)
jqObj.width() //返回元素宽度,不含外边距(margin),可设值
jqObj.outWidth(false) //默认参数为false,返回元素宽度,不含外边距(margin)
jqObj.outWidth(true) //默认参数为false,返回元素宽度,含外边距(margin)
obj.clientWidth //返回元素宽度,不含偏移值(overflow-x超出时)、外边距(margin)
obj.scrollWidth //返回元素宽度,含偏移值(overflow-x超出时)、不含外边距(margin)
obj.clientTop //返回元素的边框宽度(border-size)
//高和宽是一样的
这些属性个地方需要注意,那就是被操纵的元素必须是占位的,如果设置成display:none
,那以上js原生属性的值都为0。设置成visibility:hidden
还是能取到正确的值。
取滚动条偏移值:
document.documentElement.scrollTop