Description
原理
- 当前窗口的可视区域的高度
- 文档被卷曲的高度scrollTop
- 内容区域的的偏移量
判断添加当前两者的高度大于后面一项的时候,内容区域就进入了可视区域。
//当前窗口的可视区域的高度的获取。
window.innerHeight //第一种获取方式
document.documentElement.clientHeight || document.body.clientHeight
//在IE7兼容模式下,用document.body.clientHeight获取,在其他用
// document.documentElement.clientHeight 获取。
//文档被卷曲的高度scrollTop
document.body.scrollTop
//内容区域偏移量offsetTop,这个存在兼容问题。不同的浏览器的理解是不相同的。
注意,我就犯了一个错误,就是在滑动的是即onscroll事件里面scrollTop的数值一直在变化,但是我写出的一直都没有发生变化,原来是因为我没有吧这个值放在这个事件里面,放在window.onload事件里面了。所以出错了。
看看一个demo
<p id="content">Lorem ipsum dolor sit amet, consectetur adipisicing elit.
Dolore ipsa, illo nesciunt porro sed repellat quibusdam aliquam nobis harum
officiis aperiam eum possimus adipisci officia expedita beatae omnis enim,
obcaecati!
</p>
p {
margin: 1000px auto 0;
width: 400px;
height: 400px;
background-color: #ccc;
}
window.onload = function() {
var viewH = document.documentElement.clientHeight || document.body.clientHeight;
var content = document.getElementById('content');
//content.offsetTop是固定的值是该元素的偏移量
window.onscroll = function() {
// 当窗口开始滚动时。
var sTop = document.body.scrollTop ||document.documentElement.scrollTop;
console.log(viewH+sTop);
console.log(content.offsetTop);
if ((viewH+sTop) > content.offsetTop ){
alert('进入到可视区域内了');
}
}
}
getBoundingClientRect()这个也可以用来获取在可视区域加载数据
getBoundingClientRect();该方法获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置,他返回的是一个对象,即Object,该对象有是个属性:top,left,right,bottom。以像素为单位。
兼容性:上面四个属性,在ie5以上都能支持。而width和height这两个属性:ie9以上支持width/height属性。如果要兼容这两属性的话,可以采用下面的兼容形式
var rectWidth = rectObject.right - rectObject.left;
rectHeight = rectObject.bottom - rectObject.top;
在ie7及ie7以下left和top会多出两个像素的原因?
这是因为,在ie7及ie7以下的html元素坐标会从(2, 2)开始算起,在ie8已经修复了这个bug。这就是多出两个像素的原因。
var rectLeft = rectObject.left - document.documentElement.clientLeft || 2,
rectRight = rectObject.right - document.documentElement.clientLeft || 2,
rectBottom = rectObject.bottom - document.documentElement.clientTop || 2,
rectTop = rectObject.top - document.documentElement.clientTop || 2,
上面还可以用这种方式做。即这个元素的 getBoundingClientRect().top的高度小于可视区域的高度,那么就说明该元素出现在可视区域里面了。
window.onload = function() {
var viewH = document.documentElement.clientHeight || document.body.clientHeight;
var content = document.getElementById('content');
window.onscroll = function() {
var contentTop =content.getBoundingClientRect().top
//在滑动的过程中,这个元素的相对于浏览器窗口的位置一直在变化。
if (contentTop <= viewH){
alert('进入到可视区域内了');
}
}
}
在jquery中有一个方法is(":visible")
来判断元素是否可见,此时根据上面所学的,我们可以根据上面的写出相同功能的函数,而且性能还高。
function isVisible(ele) {
//兼容低版本浏览器
var h= ele.getBoundingClientRect().bottom-ele.getBoundingClientRect().top;
//不兼容ie9及以下浏览器
var h= ele.getBoundingClientRect().height;
if( h=== 0 ){
alert('该元素不可见');
}else {
alert('该元素可见');
}
}
在这里先要区分两个概念display:none
和visibility:hidden
以及opacity: 0
-
display:none
不为被隐藏的对象保留其物理空间,即该对象在页面上彻底消失,通俗来说就是看不见也摸不到。 -
visibility:hidden
和opacity: 0
使对象在网页上不可见,但该对象在网页上所占的空间没有改变,通俗来说就是看不见但摸得到。
当我们判断一个元素是否可见:是说明一个元素在文档中占位的空间有大于0的高度和宽度的。当你给一个元素设置高和宽以及visibility:hidden
,此时该元素还是占位的,说明该元素是可见的。这里的可见的判断标准,是该元素在文档中占位,不可见是该元素在文档中是不占位的。
有了这个方法,获取元素在页面的位置就更方便了
var X= this.getBoundingClientRect().left+document.documentElement.scrollLeft;
var Y =this.getBoundingClientRect().top+document.documentElement.scrollTop;
getClientRects方法(http://www.css88.com/archives/4187)
getClientRects方法返回的TextRectangle对象。W3C提供了一个文本的TextRectangle 对象,这个对象是对文本区域的一个解释。这里的文本区域只针对inline 元素,比如:a, span, em这类标签元素。
getClientRects 返回一个TextRectangle集合,就是TextRectangleList对象。getBoundingClientRect 返回 一个TextRectangle对象。
getClientRects返回的其实是个数组,数组中有很多个类似getBoundingClientRect返回的对象。getBoundingClientRect返回的永远是最外框框的那个矩形区域相关的坐标偏移对象;而getClientRects是多行文字区域的坐标偏移集合,在非IE浏览器下,只对inline的标签有反应。
{
top : (number)
bottom : (number)
left : (number)
right : (number)
width : (number)
height : (number)
}
类似新浪微博的用户信息卡的功能
- TextRectangle数组的长度可知道文字是否换行,甚至是换了几行。
- TextRectangle的几个属性和鼠标位置比较可以知道鼠标在哪一行上。
<p id="content">
hello world <span id="span" class="span">Lorem ipsum dolor sit amet,
consectetur adipisicing elit. Sed dolor ipsa totam accusantium nulla ad dolorum?
Voluptate natus saepe itaque maxime consequatur libero excepturi voluptas
quisquam, odit, voluptatum tenetur incidunt!</span>
hello world
</p>
在对于span的内联元素,在小屏幕下,内容会被分成好几行。getClientRects 该方法就生成几个元素的集合。即有几个矩形。
* {
padding: 0;
margin: 0;
}
span {
background-color: #999;
cursor: pointer;
}
var content = document.getElementById('content');
var span = document.getElementById('span');
span.onclick = function(event) {
var mouseY = event.clientY;
var objRectList = this.getClientRects();
var len = objRectList.length;
for (var i = 0; i < len; i++) {
//根据高度来判断点击了哪一行,这样我们就可以通过鼠标移入或者点击的坐标来决定卡片显示的位置
if ((objRectList[i].top <= mouseY) && (mouseY<= objRectList[i].bottom)){
alert('你点击了第' + (i+1) + '行');
}
}
}
event对象的clientX,offsetX,screenX,pageX,layerX区别
event.clientX、event.clientY
鼠标相对于浏览器窗口可视区域的X,Y坐标(窗口坐标),可视区域不包括工具栏和滚动条。IE事件和标准事件都定义了这2个属性.IE下(7及以下的浏览器)此属性不规范,它们的最小值不是0而是2,因为它是以(2,2)为坐标原点。
event.pageX、event.pageY
鼠标相对于整个页面的X/Y坐标。注意,整个页面的意思就是你整个网页的全部,比如说网页很宽很长,宽2000px,高3000px,那pageX,pageY的最大值就是它们了。类似于event.clientX、event.clientY,但它们使用的是文档坐标而非窗口坐标
兼容性:除IE6/7/8不支持外,其余浏览器均支持
event.offsetX、event.offsetY
offsetX/Y获取到是触发点相对被触发dom的左上角距离,不过左上角基准点在不同浏览器中有区别,其中在IE中以内容区左上角为基准点不包括边框,如果触发点在上边框会返回负值,而chrome中以边框左上角为基准点
兼容性:IE6/7/8不支持外。IE9及以上触发点在上边框会返回负值。Firefox的结果也是跟IE一样的。
chrome以边框左上角为基准点。
event.screenX、event.screenY
鼠标相对于用户显示器屏幕左上角的X,Y坐标。
event.layerX、event.layerY:
layerX/Y获取到的是触发点相对被触发dom左上角的距离,数值与offsetX/Y相同,这个变量就是firefox用来替代offsetX/Y的,基准点为边框左上角,但是有个条件就是,被触发的dom需要设置为position:relative或者position:absolute,否则会返回相对html文档区域左上角的距离
兼容性:IE6/7/8不支持。IE9即以上浏览器解析跟Firefox是一样的。
Activity