DOM

特效"三大家族":

offset  偏移

scroll   滚动

client   可视区

offset家族:

offsetWidth和style.width的区别:

style.width只能获取行内式,offsetWidth不管行内还是内嵌都能获取

style.width是字符串,带px,offsetWidth是数字

style.width能设置行内样式,offsetWidth是只读属性,不能设置样式

offsetWidth,offsetHeight是由width,padding,border组成的

offsetLeft:自己左边框距离定位的父盒子的padding之间的距离 ,如果没有定位的父盒,默认以body或是文档为准

如果父盒子有定位,就是到父盒子左内边框的距离

offsetTop:自己上边框距离定位的父盒子的padding之间的距离 ,如果没有定位的父盒,默认以body或是文档为准

没有offsetRight和offsetBottom

offsetParent如果父元素有定位,那么offsetParent就是定位的父元素,如果父元素没有定位,offsetParent就是body

parent永远指的是上一级元素

scroll家族

scrollWidth是指width+padding,获取的是盒子撑开后的大小

scrollTop是指滚动出盒子的距离

获取页面滚动出去的距离:

谷歌,火狐,IE9及以上版本支持document.body.scrollTop

IE8及以下版本支持document.documentElement.scrollTop

为了兼容所有版本,需要进行封装函数:

函数的作用:获取scrollTop和scrollLeft
function scroll() {
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;;
var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;

var o = {
scrollTop : scrollTop,
scrollLeft : scrollLeft
};
return o;
}
再进行简写
function scroll() {

return {
scrollLeft:document.body.scrollLeft || document.documentElement.scrollLeft,
scrollTop:document.body.scrollTop || document.documentElement.scrollTop
};
}


谷歌,火狐,IE9及以上版本支持getComputedStyle 返回的类型是样式对象CSSStyleDeclaration

(window.getComputedStyle(box, null)["width"])||0; 为了避免动画运行错误,此处运用短路运算原理,输出前面的数字,或者0

IE8及以下版本支持currentStyle
box.currentStyle["width"]

封装兼容性函数:
function getStyle(element, attr) {
if(window.getComputedStyle) {
return window.getComputedStyle(element,null)[attr];
}else{
return element.currentStyle[attr];
}
}


动画的函数(除了zindex和透明度不适用)
function animate(element, attrs, fn) {
//清除定时器
if(element.timerId) {
clearInterval(element.timerId);
}

element.timerId = setInterval(function () {

//问题:当多个属性的最小值到达之后,动画就会停止
//解决:当所有属性都到达目标值,动画停止

//假设所有的属性都到达目标值,停止定时器
var isStop = true;

//遍历多个属性
for(var attr in attrs) {

if(attr === "zIndex") {
element.style[attr] = attrs[attr];
}else if(attr === "opacity") {
//获取当前元素样式属性的值
var current = parseFloat(getStyle(element, attr)) || 0;
current *= 100;
//每一次step的值会越来越小
var step = (attrs[attr]*100 - current)/8;

//正数 向上取整 负数 向下取整
step = step > 0 ? Math.ceil(step): Math.floor(step);

current += step;


element.style[attr] = current/100;
//更改ie下的透明度
element.style.filter = "alpha(opacity="+ current +")";

//如果有一个属性没有到达目标值,不能停止动画
if(step != 0) {
isStop = false;
}
}else{
//获取当前元素样式属性的值
var current = parseInt(getStyle(element, attr)) || 0;
//每一次step的值会越来越小
var step = (attrs[attr] - current)/8;

//正数 向上取整 负数 向下取整
step = step > 0 ? Math.ceil(step): Math.floor(step);

current += step;


element.style[attr] = current + "px";


//如果有一个属性没有到达目标值,不能停止动画
if(step != 0) {
isStop = false;
}
}

}

//停止定时器
if(isStop) {
clearInterval(element.timerId);

//执行回调函数
if(fn){
fn();
}
}
},30);
}



当先执行一个属性变化,再执行下一个时,可以使用函数的回调
btn.onclick = function () {

animate(box, {50}, function () {
//回调函数
animate(box, {left:200}, function () {
//回调函数
animate(box, {height: 400});
});
});
}


封装透明度和zindex动画特效的函数:
盒子的css
#box {
200px;
height: 200px;
background-color: #ff0000;
position: absolute;
opacity: 0;
filter: alpha(opacity=0);
}

<script>
var btn = my$("btn");
btn.onclick = function () {
var box = my$("box");
animate(box, {opacity: 1});
}


//获取任意样式
function getStyle(element, attr) {
if(window.getComputedStyle) {
return window.getComputedStyle(element,null)[attr];
}else{
return element.currentStyle[attr];
}
}


//width : 400
//left : 300

//在修改单个属性的基础上修改
//1 修改参数,传入对象
//2 遍历对象,获取到所有的属性
//3 把target修改 成 attrs[attr]
function animate(element, attrs, fn) {
//清除定时器
if(element.timerId) {
clearInterval(element.timerId);
}

element.timerId = setInterval(function () {

//问题:当多个属性的最小值到达之后,动画就会停止
//解决:当所有属性都到达目标值,动画停止

//假设所有的属性都到达目标值,停止定时器
var isStop = true;

//遍历多个属性
for(var attr in attrs) {

if(attr === "zIndex") {
element.style[attr] = attrs[attr];
}else if(attr === "opacity") {
//获取当前元素样式属性的值
var current = parseFloat(getStyle(element, attr)) || 0;
current *= 100;
//每一次step的值会越来越小
var step = (attrs[attr]*100 - current)/8;

//正数 向上取整 负数 向下取整
step = step > 0 ? Math.ceil(step): Math.floor(step);

current += step;


element.style[attr] = current/100;
//更改ie下的透明度
element.style.filter = "alpha(opacity="+ current +")";

//如果有一个属性没有到达目标值,不能停止动画
if(step != 0) {
isStop = false;
}
}else{
//获取当前元素样式属性的值
var current = parseInt(getStyle(element, attr)) || 0;
//每一次step的值会越来越小
var step = (attrs[attr] - current)/8;

//正数 向上取整 负数 向下取整
step = step > 0 ? Math.ceil(step): Math.floor(step);

current += step;


element.style[attr] = current + "px";


//如果有一个属性没有到达目标值,不能停止动画
if(step != 0) {
isStop = false;
}
}

}

//停止定时器
if(isStop) {
clearInterval(element.timerId);

//执行回调函数
if(fn){
fn();
}
}
},30);
}


</script>
原文地址:https://www.cnblogs.com/sw1990/p/5771369.html