一前言
与js动画有关的主要有三大家族:offset/scroll/client。接下来认识一下三大家族。
offset
每个标签节点对象中都会有:offsetWidth、offsetHight、offsetLeft、offsetTop、offsetParent属性,他们代表什么意思呢?
offsetWidth 和 offsetHight用来获取标签的大小:
offsetWidth = width + padding + border;
offsetHeight = Height + padding + border;
offsetLeft 和 offsetTop距离带有定位的祖先盒子左边和上边位置 ;如果父级都没有定位,则以body为准。不论你是以何种手段产生的距离padding也好,绝对定位也好,返回的就是距离(只读属性)。
offsetParent返回距离自己最近带有定位的祖先标签对象。如果祖先都没有定位,返回body标签对象。
tips:style.left和offsetLeft 有本质的区别:style.left指定的是自身定位用到的属性,可读,可写,但是读取只能读取行内样式。offsetLeft 指定的是偏移量,只读属性,不可赋值,我们就可以结合这两个属性的特点总结如下:用offsetLeft 和 offsetTop 获取值,用style.left 和 style.top 赋值来实现动画。
通过上边的几个属性表示的含义+定位的css样式,理论上我们可以实现任何动画:其原理是:
让父盒子相对布局,子盒子绝对定位:然后通过公式:
ele.style.left = ele.offsetLeft + speed + "px";动态去改变元素left,来达到一个动画效果,通过上边的公式我们可以看到,我们在js中数据模型的建立需要开发者自己去做,而不是像android模型已经建立好,只需要设置初始值,结束值,动画时间,就可以拿到值。
scroll
每个标签节点对象中都还会有:scrollWidth 、scrollHeight、scrollTop 、scrollLeft属性,他们代表什么意思呢?
scrollWidth = width + padding;
scrollHeight = height + padding;
tips:这里不包括border,并且这里的scrollWidth 如果内容超过盒子就是内容的高度,如果不错超过就是盒子的高度。然而offsetWidth不管内容有没有超过都是盒子的大小
scrollTop 和 scrollLeft 代表网页被卷去的头部和左边的部分,兼容不同浏览器写法:
function scroll() {
return { //此函数的返回值是json
"top": window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop,
"left": window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft,
}
}client
上边两大家族都是针对盒子自身调用的数据或者针对整个网页滚动的数据。而client却不一样,
clientWidth 和 clientHeight
盒子调用时:
clientWidth= width + padding;
clientHeight= height + padding;
tips:不管内容是否超过都是盒子的大小
body/html调用时:获取页面的可视区域。
event调用:鼠标距离可视区域的距离。
clientTop 和 clientLeft
clientTop:盒子的上border。
clientLeft:盒子的左border。
二jQuery入门
就目前来拥有的知识来看,如果用原生的js去获取和操作DOM节点,会面临很多问题:浏览器兼容、代码繁琐、动画难实现(需要自己去建模)。为了解决这些问题jQuery库应运而生。jquery就是封装了很多操作节点方法。首先我们来认识一下$(参数):传入不同的参数,返回不同的对象。如:
$(); // 调用自定义的函数$
$(document).ready(function(){}); // 调用入口函数
$(function(){}); // 调用入口函数
$("#btnShow") // 获取id属性为btnShow的元素
$("div") // 获取所有的div标签元素
$(".btnShow") // 获取所有class是btnShow的元素jqueryAPI有两个特性:链式调用和隐式迭代。
- 链式调用是因为return的是this(只有设置操作才能把链式编程延续下去)
- 隐士迭代是因为返回的对象都是数组,内部默认迭代了对象
总结:jQuery 把 DOM节点对象包装成 jQuery 节点对象,并且节点对象之间可以互相转换:
- jquery节点对象 = $(DOM节点对象)
- DOM节点对象 = jquery节点对象[下标]
我们在前边已经学过,要获取DOM节点对象,可以通过doctoment配合选择器来获取DOM节点对象。同样的jQuery也封装了直接通过选择器可以获取jQuery节点的方法,css选择器都可以用到jQuery中,写到字符串中,如:$("选择器")。当然,由于jQuery返回的是一个数组,所以他还有过滤选择器,来帮助开发者更方便使用:
- "div:eq(a)": a表示选择第几个元素,返回当前位置元素数组;
- "div:gt(a)": a表示第几个位置,返回大于a位置的元素数组;
- "div:It(a)":a表示第几个位置,返回小于a位置的元素数组;
- "div:odd":选择序号为奇数位置,返回数组;
- div:even":选择序号为奇数位置,返回数组;
- "div:first":选择第一个位置,返回数组;
- "div:last":选择最后一个位置,返回数组;
同时还提供了:属选择器、筛选选择器 jquery节点筛选选择器方法:
- find("div"):获取当前节点所有后代div;
- children("div"):获取当前节点亲儿子div;
- siblings():获取当前节点的兄弟,不包括自己;
- parent():获取当前节点的父节点;
- eq(index):指定索引位置的节点;
三jQuery动画
上边我们已经知道动画的实现原理,因为js并没有对动画提前建模,做为开发者,实现动画就需要自己去建模,这是不能忍的,jQuery封装了很多动画,接下来我们就一起了解一下jQuery关于动画的方法。
显示隐藏动画
在js中我们通过display值为none或black去显示或者隐藏DOM节点,但是这种显示和隐藏比较生硬。jQuery帮我们封装了一个带有动画的显示和隐藏:
- $(selector).show()
- $(selector).show(time)
- $(selector).show("slow")
- $(selector).show(time,function(){})
隐藏同上只是把show方法变成hide方法。我们在开发时候常常显示和隐藏使用一个按钮,jQuery还提供了toggle方法,免除我们自己去定义标记。如:
$(".bb").toggle(3000,function(){alert("动画执行完毕")})仔细观察我们会发现show和hide方法动画是三组动画同时执行:从上到下显示+从左到右显示+透明度从0-1变化。那么猜测应该有这三个动画独立执行的API:
从上到下显示隐藏有三个方法:slideDown()、slideUp()、slideToggle(),API使用如上显示和隐藏。
透明度显示隐藏有三个方法:fadeOut()、fadeIn()、fadeToggle(),API使用如上显示和隐藏。
仅仅有上边这些简单的动画,在实际开发中还是难以满足需求,因为不够任意多样化。当然jQuery给我们提供了自定义动画,类似android的插值器的功能一样,只要给开始值(开始值就是当前div的css值),结束值,动画执行时间,就可以给你一系列的变化值,甚至比android更简单的是,它会自动刷新渲染。语法如下:
$(selector).animate({params}, speed, callback);第一个参数表示:要执行动画的CSS属性(必选)
第二个参数表示:执行动画时长(可选)
第三个参数表示:动画执行完后,立即执行的回调函数(可选)
例:
var json = {"width": 500, "height": 500, "left": 300, "top": 300, "border-radius": 100 };
$("div").animate(json, 1000, function () { });停止动画:
$(selector).stop(false, false);第一个参数:
true:后续动画不执行。(废除动画队列)
false:后续动画会执行。(废除队列里边的当前动画)
第二个参数:
true:立即完成当前动画。
false:立即停止当前动画。