友情提示:如有任何写的不对的地方还望谅解,若能指点一二更是感激不尽~
最近在做一个新闻类的网站,有些文章内容太长需要做分页处理,下面是我这两天思考之后做出来的,写出来和大家分享分享
需求
- 根据后台返回的文章按一定的高度做分页处理
文章的情况
- 长度不定,且不是纯文字,是一段html
- 用户可以选择文章的fontSize,目前只有三个值选择,小中大分别对应14px,16px,18px
- 其中可能会插入图片,图片大小不定,大概样式如下:
<p>这是一段新闻<p>
<p><img src='XXX' alt='这是一张图片'><p>
<p>这又是一段新闻<p>
<p><img src='XXX' alt='这又是一张图片'><p>
·
·
·
实现思路(以文章的行高为基准,使用margin-top实现翻页效果)
- 最外层套一个div.box,并设置
overflow:hidden
- 在
div.box
中再嵌套一个div.page
设置固定的行高line-height: 36px !important;
(此处很重要,设置了行高之后不管用户怎么改变font-size每行文字的高度都是固定的!important可以防止返回的html自带的样式造成层叠),将获取到的文章放在page里面 - 给外层
div.box
设置固定的高度,此高度必须为行高的倍数,例子中设置的是720px
- 翻页效果采取给div.page设置margin-top负值来实现
- 分页分两种情况考虑:1. 纯文字;2.带图片
- 如果当前显示出的界面中是纯文字,则按照之前设置的高度不变
- 如果当前显示出的界面中有图片则获取图片的高度加上之前设置的高度,但是考虑图片过长时,翻页时文章长度突然改变影响用户体验,此处需要稍作处理,大概HTML如下
<div class='box'>
<div class='page'></div>
</div>
以下为部分js:
//此处使用window.onload是为了确保下载完所有的图片,否则可能获取不到图片的高度
window.onload = function () {
//设置分页
var pages = $('.box'),
page = $('.page'),
boxH = pages[0].clientHeight,//界面显示出来的高度
pageH = pages[0].scrollHeight,//文章实际高度
allIndex = Math.ceil(pageH/(boxH));//先按纯文字计算总页数
// 有图片的情况
var pageImg = page.find('img'),
singleHeight = [],//保存计算后的单页高度
singleOffset = [],//保存计算后每次翻页的margin-top值
averH;
if(pageImg){
var offsetY = 0;
for(var h=0;h<allIndex;h++){
averH = setHeight(boxH,pageImg,pages,offsetY);
singleHeight.push(averH);
singleOffset.push(offsetY);
offsetY += averH;
if (offsetY>pageH){
pages.css('height',singleHeight[0]);
}
}
}
//重新计算页码
var newIndex = 1,
allH =0;
for (var w=0;w<singleHeight.length;w++){
allH += singleHeight[w];
if (allH>pageH) {
newIndex = w+1;
break
}
}
//setHeight这个函数返回的是计算出来的界面高度
function setHeight(boxH,pageImg,pages,offsetY) {
var averH=boxH,minH = 36;
//遍历所有的图片
for(var i=0;i<pageImg.length;i++){
// 单张图片距离文章顶部的距离
var imgTop = pageImg[i].offsetTop - pages[0].offsetTop - offsetY;
/* 单张图片外包裹的父元素的高度(所有图片都是被p标签包裹住的,直接获取图片的高度会不准确)*/
var pHeight = pageImg[i].parentNode.clientHeight;
// 筛选出在本页的图片
// 图片在文章底部且被截掉了一部分的情况
if (imgTop>=0 && imgTop<boxH && imgTop+pHeight>boxH){
//图片下面可能会有一排说明,最后加上minH保证这段说明不会跑到第二页
averH = imgTop+pHeight+minH;
} else if (imgTop>=0 && imgTop<boxH && imgTop+pHeight<boxH){ // 一张或多张图片都在文章内的情况
//平均高度
averH += pHeight-Math.round(pHeight/minH)*minH+minH;
}
}
//如果以上设置的情况不满足则返回最初的高度
return averH
}
以上。
在github有完整代码,有需要可以 点这里